From: Jeesun Kim Date: Mon, 14 Nov 2016 02:24:32 +0000 (+0900) Subject: Add number blocking feature. X-Git-Tag: submit/tizen/20170711.002954~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2c1ec965a0afb312d20634d573c20c7ebbeb98e6;p=platform%2Fcore%2Ftelephony%2Fphonenumber-utils.git Add number blocking feature. Change-Id: Ib8f725c51a3c60fba06cd970b15e671eec290e29 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b3513c..33d60f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ SET(CLIENT ${PROJECT_NAME}) SET(DAEMON "${PROJECT_NAME}-daemon") SET(DBUS_INTERFACE "org.tizen.PhonenumberUtils.dbus") +EXECUTE_PROCESS(COMMAND build-util/generator.sh) + ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(daemon) ADD_SUBDIRECTORY(client) diff --git a/build-util/DB-schema-gen.c b/build-util/DB-schema-gen.c new file mode 100644 index 0000000..d609485 --- /dev/null +++ b/build-util/DB-schema-gen.c @@ -0,0 +1,56 @@ +/* + * Phonenumber Utils + * + * Copyright (c) 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 +#include + +int main(int argc, char **argv) +{ + FILE *fp; + int c; + + fp = fopen(argv[1], "r"); + if (NULL == fp) + exit(EXIT_FAILURE); + + do { + c = fgetc(fp); + switch (c) { + case '\n': + printf("\\\n"); + break; + case '-': + if ('-' == (c = fgetc(fp))) { + while ('\n' != c && EOF != c) + c = fgetc(fp); + printf("\\\n"); + } else { + printf("-%c", c); + } + break; + case EOF: + break; + default: + printf("%c", c); + break; + } + } while (EOF != c); + + exit(EXIT_SUCCESS); +} + diff --git a/build-util/Makefile b/build-util/Makefile new file mode 100644 index 0000000..125a31e --- /dev/null +++ b/build-util/Makefile @@ -0,0 +1,23 @@ +CC = gcc + +REQUIRED_PKG = +CFLAGS = -g -Wall #-fprofile-arcs -ftest-coverage +LDFLAGS = +ifdef REQUIRED_PKG + CFLAGS += $(shell pkg-config --cflags $(REQUIRED_PKG)) + LDFLAGS += -L$(pkg-config --libs $(REQUIRED_PKG)) + LDFLAGS += $(shell pkg-config --libs $(REQUIRED_PKG)) +endif + +SRCS = $(wildcard *.c) +OBJECTS = $(SRCS:.c=.o) +TARGETS = $(OBJECTS:.o=) + +all: $(TARGETS) + +$(TARGETS) : $(SRCS) + $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@ + +clean: + rm -rf $(OBJECTS) $(TARGETS) + diff --git a/build-util/generator.sh b/build-util/generator.sh new file mode 100755 index 0000000..517d47e --- /dev/null +++ b/build-util/generator.sh @@ -0,0 +1,34 @@ +# +# Phonenumber Utils +# +# Copyright (c) 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. +# + +#!/bin/sh + +echo "###### DB Generator #####" + +cd build-util +make + +# Make DB schema for generating DB file when running phonenumber-utils daemon +echo "static const char *schema_query = \"\\" > ../daemon/schema.h +./DB-schema-gen ./schema.sql >> ../daemon/schema.h +echo \"\; >> ../daemon/schema.h + +# Make DB file at builing time +sqlite3 .phonenumber-utils.db < schema.sql + +make clean diff --git a/build-util/schema.sql b/build-util/schema.sql new file mode 100644 index 0000000..dd73a09 --- /dev/null +++ b/build-util/schema.sql @@ -0,0 +1,29 @@ +-- +-- Phonenumber Utils +-- +-- Copyright (c) 2010 - 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. +-- +PRAGMA user_version = 100; +PRAGMA journal_mode = WAL; + +CREATE TABLE blocknumbers +( + id INTEGER PRIMARY KEY AUTOINCREMENT, + match_type INTEGER, + user_id INTEGER, + number TEXT, + normalized_number TEXT +); + diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index dea8482..60b87c9 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -2,13 +2,16 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) FILE(GLOB CLIENT_SRCS *.c) -SET(CLIENT_SRCS ${CLIENT_SRCS} ${CMAKE_SOURCE_DIR}/common/phn-dbus.c) +SET(CLIENT_SRCS ${CLIENT_SRCS} + ${CMAKE_SOURCE_DIR}/common/phn-dbus.c + ${CMAKE_SOURCE_DIR}/common/phn-dbus-utils.c + ${CMAKE_SOURCE_DIR}/common/phn-record.c) SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/common/phn-dbus.c PROPERTIES GENERATED TRUE) pkg_check_modules(client_pkgs REQUIRED dlog glib-2.0 capi-base-common gio-2.0 gio-unix-2.0 - capi-system-info) + capi-system-info libsystemd-login) INCLUDE_DIRECTORIES(${client_pkgs_INCLUDE_DIRS}) LINK_DIRECTORIES(${client_pkgs_LIBRARY_DIRS}) diff --git a/client/phnc-blocking_rule.c b/client/phnc-blocking_rule.c new file mode 100644 index 0000000..a43f8b9 --- /dev/null +++ b/client/phnc-blocking_rule.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 - 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 + +#include "phone_number.h" +#include "phn-log.h" +#include "phn-record.h" +#include "phnc.h" +#include "phn-property.h" + +API int phone_number_blocking_rule_create(phone_number_blocking_rule_h *rule) +{ + int ret; + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + ret = phn_record_create(rule); + + if (PHONE_NUMBER_ERROR_NONE == ret) { + phn_blocking_rule_s *p = (phn_blocking_rule_s *)*rule; + p->user_id = phnc_get_uid(); + } + return ret; +} + +API int phone_number_blocking_rule_destroy(phone_number_blocking_rule_h rule) +{ + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + return phn_record_destroy(rule); +} + +API int phone_number_blocking_rule_get_number(phone_number_blocking_rule_h rule, char** number) +{ + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + return phn_record_get_str(rule, PHN_PROPERTY_BLOCKING_RULE_NUMBER, number); +} + +API int phone_number_blocking_rule_get_match_type(phone_number_blocking_rule_h rule, phone_number_blocking_rule_match_type_e *match_type) +{ + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == match_type, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + return phn_record_get_int(rule, PHN_PROPERTY_BLOCKING_RULE_MATCH_TYPE, (int*)match_type); +} + +API int phone_number_blocking_rule_set_number(phone_number_blocking_rule_h rule, const char* number) +{ + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + return phn_record_set_str(rule, PHN_PROPERTY_BLOCKING_RULE_NUMBER, number); +} + +API int phone_number_blocking_rule_set_match_type(phone_number_blocking_rule_h rule, phone_number_blocking_rule_match_type_e match_type) +{ + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF((match_type < PHONE_NUMBER_MATCH_TYPE_EXACTLY || PHONE_NUMBER_MATCH_TYPE_ENDS_WITH < match_type), + PHONE_NUMBER_ERROR_INVALID_PARAMETER); + return phn_record_set_int(rule, PHN_PROPERTY_BLOCKING_RULE_MATCH_TYPE, (int)match_type); +} + diff --git a/client/phnc-dbus.c b/client/phnc-dbus.c new file mode 100644 index 0000000..7bc707d --- /dev/null +++ b/client/phnc-dbus.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2015 - 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 + +#include "phone_number.h" +#include "phn-log.h" +#include "phn-record.h" +#include "phn-common.h" +#include "phn-utils.h" +#include "phn-dbus.h" +#include "phn-dbus-utils.h" + +static phnDbus *phnc_dbus_object; + +int phnc_dbus_connect(void) +{ + GError *error = NULL; + + if (phnc_dbus_object) { + DBG("phnc_dbus_object is already created"); + return PHONE_NUMBER_ERROR_NONE; + } + +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + phnc_dbus_object = phn_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + PHN_DBUS_INTERFACE, + PHN_DBUS_OBJPATH, + NULL, + &error); + if (NULL == phnc_dbus_object) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_proxy_new_for_bus_sync() Fail(%s)", error->message); + g_error_free(error); + return PHONE_NUMBER_ERROR_SYSTEM; + /* LCOV_EXCL_STOP */ + } + return PHONE_NUMBER_ERROR_NONE; +} + +int phnc_dbus_disconnect(void) +{ + RETV_IF(NULL == phnc_dbus_object, PHONE_NUMBER_ERROR_SYSTEM); + + DBG("client closed"); + g_object_unref(phnc_dbus_object); + phnc_dbus_object = NULL; + + return PHONE_NUMBER_ERROR_NONE; +} + +int phnc_dbus_get_location_from_number(const char *number, phone_number_region_e region, + phone_number_lang_e lang, char **location) +{ + int ret = 0; + GError *error = NULL; + char *out_loc = NULL; + bool not_connected = phnc_dbus_object ? false : true; + + if (not_connected) + phnc_dbus_connect(); + + phn_dbus_call_get_location_sync(phnc_dbus_object, number, region, lang, + &out_loc, &ret, NULL, &error); + + if (not_connected) + phnc_dbus_disconnect(); + + if (NULL != error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_get_location_sync() Fail(%s)", error->message); + g_error_free(error); + free(out_loc); + return PHONE_NUMBER_ERROR_SYSTEM; + /* LCOV_EXCL_STOP */ + } + + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("Phonenumber utils error : %d", ret); + free(out_loc); + return ret; + /* LCOV_EXCL_STOP */ + } + *location = out_loc; + + return ret; +} + +int phnc_dbus_get_formatted_number(const char *number, phone_number_region_e region, + char **formatted_number) +{ + int ret = 0; + GError *error = NULL; + char *out_num = NULL; + bool not_connected = phnc_dbus_object ? false : true; + + if (not_connected) + phnc_dbus_connect(); + + phn_dbus_call_get_number_sync(phnc_dbus_object, number, region, &out_num, + &ret, NULL, &error); + + if (not_connected) + phnc_dbus_disconnect(); + + if (NULL != error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_get_number_sync() Fail(%s)", error->message); + g_error_free(error); + free(out_num); + return PHONE_NUMBER_ERROR_SYSTEM; + /* LCOV_EXCL_STOP */ + } + + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("Phonenumber utils error : %d", ret); + free(out_num); + return ret; + /* LCOV_EXCL_STOP */ + } + *formatted_number = out_num; + + return ret; +} + +int phnc_dbus_get_normalized_number(const char *number, char **normalized_number) +{ + int ret = 0; + GError *error = NULL; + char *out_num = NULL; + bool not_connected = phnc_dbus_object ? false : true; + + /* TODO: remove "not_connected" condition in this API. + * contacts-service is still using this API without phone_number_connect() + */ + if (not_connected) + phnc_dbus_connect(); + + phn_dbus_call_get_normalized_number_sync(phnc_dbus_object, number, &out_num, + &ret, NULL, &error); + + if (not_connected) + phnc_dbus_disconnect(); + + if (NULL != error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_get_normalized_number_sync() Fail(%s)", error->message); + if (G_DBUS_ERROR_ACCESS_DENIED == error->code) + ret = PHONE_NUMBER_ERROR_PERMISSION_DENIED; + else + ret = PHONE_NUMBER_ERROR_SYSTEM; + g_error_free(error); + free(out_num); + return ret; + /* LCOV_EXCL_STOP */ + } + + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("Phonenumber utils error : %d", ret); + free(out_num); + return ret; + /* LCOV_EXCL_STOP */ + } + *normalized_number = out_num; + + return ret; +} + +int phnc_dbus_add_blocking_rule(phone_number_blocking_rule_h rule) +{ + int ret = 0; + GError *error = NULL; + + GVariant *arg_rule = phn_dbus_utils_record_to_gvariant(rule); + phn_dbus_call_add_blocking_rule_sync(phnc_dbus_object, arg_rule, &ret, NULL, &error); + // TODO:g_variant_unref(arg_rule); + + if (error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_add_blocking_rule_sync() Fail([%s]", error->message); + ret = (G_DBUS_ERROR_ACCESS_DENIED == error->code) + ? PHONE_NUMBER_ERROR_PERMISSION_DENIED : PHONE_NUMBER_ERROR_IPC; + g_error_free(error); + /* LCOV_EXCL_STOP */ + } + + return ret; +} + +int phnc_dbus_remove_blocking_rule(int id) +{ + int ret = 0; + GError *error = NULL; + + phn_dbus_call_remove_blocking_rule_sync(phnc_dbus_object, id, &ret, NULL, &error); + + if (error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_remove_blocking_rule_sync() Fail(%s)", error->message); + ret = (G_DBUS_ERROR_ACCESS_DENIED == error->code) + ? PHONE_NUMBER_ERROR_PERMISSION_DENIED : PHONE_NUMBER_ERROR_IPC; + g_error_free(error); + return ret; + /* LCOV_EXCL_STOP */ + } + + return ret; +} + +int phnc_dbus_check_blocking(int user_id, const char *number, bool* out_is_blocked) +{ + int ret = 0; + GError *error = NULL; + + int is_blocked = 0; + phn_dbus_call_check_blocking_sync(phnc_dbus_object, user_id, number, &is_blocked, &ret, NULL, &error); + + if (error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_check_blocking_sync() Fail([%s]", error->message); + ret = (G_DBUS_ERROR_ACCESS_DENIED == error->code) + ? PHONE_NUMBER_ERROR_PERMISSION_DENIED : PHONE_NUMBER_ERROR_IPC; + g_error_free(error); + /* LCOV_EXCL_STOP */ + } + + *out_is_blocked = (0 == is_blocked ? false : true); + + return ret; +} + +int phnc_dbus_get_blocking_rules(int user_id, int offset, int limit, phone_number_blocking_rule_h **rules, int *length) +{ + FN_CALL; + + int ret = 0; + GError *error = NULL; + + GVariant *arg_list = NULL; + phn_dbus_call_get_blocking_rules_sync(phnc_dbus_object, user_id, offset, limit, &arg_list, &ret, + NULL, &error); + + if (error) { + /* LCOV_EXCL_START */ + ERR("phn_dbus_call_get_blocking_rules_sync() Fail([%s]", error->message); + ret = (G_DBUS_ERROR_ACCESS_DENIED == error->code) + ? PHONE_NUMBER_ERROR_PERMISSION_DENIED : PHONE_NUMBER_ERROR_IPC; + g_error_free(error); + /* LCOV_EXCL_STOP */ + } + + if (PHONE_NUMBER_ERROR_NO_DATA == ret) { + DBG("No blocking rule"); + *rules = NULL; + *length = 0; + return ret; + } + + phn_dbus_utils_gvariant_to_array(arg_list, rules, length); + // TODO: g_variant_unref(arg_list); + + return ret; +} + diff --git a/client/phnc-dbus.h b/client/phnc-dbus.h new file mode 100644 index 0000000..55362c0 --- /dev/null +++ b/client/phnc-dbus.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHONENUMBER_UTILS_CLIENTDBUS_H__ +#define __PHONENUMBER_UTILS_CLIENTDBUS_H__ + +#include "phone_number_types.h" + +int phnc_dbus_connect(void); +int phnc_dbus_disconnect(void); +int phnc_dbus_get_location_from_number(const char *number, phone_number_region_e region, phone_number_lang_e lang, char **location); +int phnc_dbus_get_formatted_number(const char *number, phone_number_region_e region, char **formatted_number); +int phnc_dbus_get_normalized_number(const char *number, char **normalized_number); +int phnc_dbus_add_blocking_rule +(phone_number_blocking_rule_h rule); +int phnc_dbus_remove_blocking_rule(int id); +int phnc_dbus_check_blocking(int user_id, const char *number, bool* out_is_blocked); +int phnc_dbus_get_blocking_rules(int user_id, int offset, int limit, phone_number_blocking_rule_h **rules, int *length); + +#endif /*__PHONENUMBER_UTILS_CLIENTDBUS_H__*/ + diff --git a/client/phnc.c b/client/phnc.c index 74a0c3f..42a18cc 100644 --- a/client/phnc.c +++ b/client/phnc.c @@ -18,17 +18,14 @@ */ #include -#include -#include -#include -#include #include +#include +#include #include "phone_number.h" -#include "phone_number_errors.h" -#include "phone_number_types.h" - -#include "phn-dbus.h" +#include "phn-record.h" +#include "phn-property.h" +#include "phnc-dbus.h" #include "phnc.h" #define PHN_FEATURE_TELEPHONY "http://tizen.org/feature/network.telephony" @@ -37,36 +34,6 @@ #define PHN_FEATURE_TELEPHONY_NOT_SUPPORTED 0 #define PHN_FEATURE_TELEPHONY_SUPPORTED 1 -static phnDbus *phn_client_dbus_object; - -static int _phn_client_dbus_start() -{ - FN_CALL; - GError *error = NULL; - - if (phn_client_dbus_object) { - DBG("phn_client_dbus_object is already created"); - return PHONE_NUMBER_ERROR_NONE; - } - - phn_client_dbus_object = phn_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - PHN_DBUS_INTERFACE, - PHN_DBUS_OBJPATH, - NULL, - &error); - if (NULL == phn_client_dbus_object) { - /* LCOV_EXCL_START */ - ERR("phn_dbus_proxy_new_for_bus_sync() Fail(%s)", error->message); - g_error_free(error); - return PHONE_NUMBER_ERROR_SYSTEM; - /* LCOV_EXCL_STOP */ - } - - return PHONE_NUMBER_ERROR_NONE; -} - - static int _phn_is_support_telephony_feature() { int err; @@ -84,55 +51,65 @@ static int _phn_is_support_telephony_feature() /* LCOV_EXCL_STOP */ } - if (is_support) - _phn_telephony_feature_support = PHN_FEATURE_TELEPHONY_SUPPORTED; - else - _phn_telephony_feature_support = PHN_FEATURE_TELEPHONY_NOT_SUPPORTED; + _phn_telephony_feature_support = + is_support ? PHN_FEATURE_TELEPHONY_SUPPORTED : PHN_FEATURE_TELEPHONY_NOT_SUPPORTED; return _phn_telephony_feature_support; } +#define PHNC_SYSTEM_SLICE "system.slice" -API int phone_number_connect(void) +int phnc_get_uid(void) { - int ret; - FN_CALL; - -#if !GLIB_CHECK_VERSION(2, 35, 0) - g_type_init(); -#endif - - ret = _phn_client_dbus_start(); - if (PHONE_NUMBER_ERROR_NONE != ret) { - /* LCOV_EXCL_START */ - ERR("_phn_client_dbus_start() Fail(%d)", ret); - /* LCOV_EXCL_STOP */ + int ret = 0; + bool is_in_system = false; + char *slice = NULL; + int uid = (int)getuid(); + + ret = sd_pid_get_slice(getpid(), &slice); + if (0 <= ret && slice) { + if (STRING_EQUAL == strncmp(slice, PHNC_SYSTEM_SLICE, strlen(PHNC_SYSTEM_SLICE))) { + is_in_system = true; + } + } else { + ERR("sd_pid_get_slice() Fail(%d)", ret); + } + free(slice); + + if (is_in_system) { + int active_user_count = 0; + uid_t *active_user_list = NULL; + + active_user_count = sd_get_active_uids(&active_user_list); + if (active_user_list) { + INFO("active uid = %d", active_user_list[0]); + uid = (int)active_user_list[0]; + if (1 != active_user_count) + ERR("active_user_count is not 1(%d)", active_user_count); + free(active_user_list); + } } - return ret; + DBG("uid = %d", uid); + return uid; } - -API int phone_number_disconnect(void) +API int phone_number_connect(void) { - RETV_IF(NULL == phn_client_dbus_object, PHONE_NUMBER_ERROR_SYSTEM); - - g_object_unref(phn_client_dbus_object); - phn_client_dbus_object = NULL; + FN_CALL; + return phnc_dbus_connect(); +} - DBG("client closed"); - return PHONE_NUMBER_ERROR_NONE; +API int phone_number_disconnect(void) +{ + return phnc_dbus_disconnect(); } - API int phone_number_get_location_from_number(const char *number, phone_number_region_e region, phone_number_lang_e lang, char **location) { FN_CALL; - int ret; - GError *error = NULL; - char *out_loc = NULL; RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); RETV_IF('\0' == *number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); @@ -142,45 +119,13 @@ API int phone_number_get_location_from_number(const char *number, RETVM_IF(lang < 0 || PHONE_NUMBER_LANG_MAX <= lang, PHONE_NUMBER_ERROR_INVALID_PARAMETER, "lang(%d) Invalid", lang); - if (NULL == phn_client_dbus_object) { - phone_number_connect(); - phn_dbus_call_get_location_sync(phn_client_dbus_object, number, region, lang, - &out_loc, &ret, NULL, &error); - phone_number_disconnect(); - } else { - phn_dbus_call_get_location_sync(phn_client_dbus_object, number, region, lang, - &out_loc, &ret, NULL, &error); - } - - if (NULL != error) { - /* LCOV_EXCL_START */ - ERR("phn_dbus_call_get_location_sync() Fail(%s)", error->message); - g_error_free(error); - free(out_loc); - return PHONE_NUMBER_ERROR_SYSTEM; - /* LCOV_EXCL_STOP */ - } - - if (PHONE_NUMBER_ERROR_NONE != ret) { - /* LCOV_EXCL_START */ - ERR("Phonenumber utils error : %d", ret); - free(out_loc); - return ret; - /* LCOV_EXCL_STOP */ - } - - *location = out_loc; - - return ret; + return phnc_dbus_get_location_from_number(number, region, lang, location); } API int phone_number_get_formatted_number(const char *number, phone_number_region_e region, char **formatted_number) { FN_CALL; - int ret; - GError *error = NULL; - char *out_num = NULL; RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); RETV_IF('\0' == *number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); @@ -188,45 +133,14 @@ API int phone_number_get_formatted_number(const char *number, RETVM_IF(region < 0 || PHONE_NUMBER_REGION_MAX <= region, PHONE_NUMBER_ERROR_INVALID_PARAMETER, "region(%d) Invalid", region); - - if (NULL == phn_client_dbus_object) { - phone_number_connect(); - phn_dbus_call_get_number_sync(phn_client_dbus_object, number, region, &out_num, - &ret, NULL, &error); - phone_number_disconnect(); - } else { - phn_dbus_call_get_number_sync(phn_client_dbus_object, number, region, &out_num, - &ret, NULL, &error); - } - - if (NULL != error) { - /* LCOV_EXCL_START */ - ERR("phn_dbus_call_get_number_sync() Fail(%s)", error->message); - g_error_free(error); - free(out_num); - return PHONE_NUMBER_ERROR_SYSTEM; - /* LCOV_EXCL_STOP */ - } - - if (PHONE_NUMBER_ERROR_NONE != ret) { - /* LCOV_EXCL_START */ - ERR("Phonenumber utils error : %d", ret); - free(out_num); - return ret; - /* LCOV_EXCL_STOP */ - } - - *formatted_number = out_num; - return ret; + return phnc_dbus_get_formatted_number(number, region, formatted_number); } - API int phone_number_get_normalized_number(const char *number, char **normalized_number) { FN_CALL; - int ret; - GError *error = NULL; - char *out_num = NULL; + + int ret = 0; ret = _phn_is_support_telephony_feature(); RETV_IF(PHONE_NUMBER_ERROR_SYSTEM == ret, PHONE_NUMBER_ERROR_SYSTEM); @@ -236,38 +150,50 @@ API int phone_number_get_normalized_number(const char *number, char **normalized RETV_IF('\0' == *number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); RETV_IF(NULL == normalized_number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); - if (NULL == phn_client_dbus_object) { - phone_number_connect(); - phn_dbus_call_get_normalized_number_sync(phn_client_dbus_object, number, &out_num, - &ret, NULL, &error); - phone_number_disconnect(); - } else { - phn_dbus_call_get_normalized_number_sync(phn_client_dbus_object, number, &out_num, - &ret, NULL, &error); - } + return phnc_dbus_get_normalized_number(number, normalized_number); +} - if (NULL != error) { - /* LCOV_EXCL_START */ - ERR("phn_dbus_call_get_normalized_number_sync() Fail(%s)", error->message); - if (G_DBUS_ERROR_ACCESS_DENIED == error->code) - ret = PHONE_NUMBER_ERROR_PERMISSION_DENIED; - else - ret = PHONE_NUMBER_ERROR_SYSTEM; - g_error_free(error); - free(out_num); - return ret; - /* LCOV_EXCL_STOP */ - } +API int phone_number_add_blocking_rule(phone_number_blocking_rule_h rule) +{ + FN_CALL; + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); - if (PHONE_NUMBER_ERROR_NONE != ret) { - /* LCOV_EXCL_START */ - ERR("Phonenumber utils error : %d", ret); - free(out_num); - return ret; - /* LCOV_EXCL_STOP */ - } + return phnc_dbus_add_blocking_rule +(rule); +} - *normalized_number = out_num; - return ret; +API int phone_number_remove_blocking_rule(phone_number_blocking_rule_h rule) +{ + FN_CALL; + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + int id = 0; + int ret = 0; + ret = phn_record_get_int(rule, PHN_PROPERTY_BLOCKING_RULE_ID, &id); + RETV_IF(PHONE_NUMBER_ERROR_NONE != ret, ret); + RETV_IF(id <= 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + return phnc_dbus_remove_blocking_rule(id); } +API int phone_number_get_blocking_rules(int offset, int limit, phone_number_blocking_rule_h **rules, int *length) +{ + FN_CALL; + RETV_IF(offset < 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(limit < 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == rules, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == length, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + return phnc_dbus_get_blocking_rules(phnc_get_uid(), offset, limit, rules, length); +} + +API int phone_number_check_blocking(const char *number, bool* is_blocked) +{ + FN_CALL; + RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF('\0' == *number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == is_blocked, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + return phnc_dbus_check_blocking(phnc_get_uid(), number, is_blocked); +} + + diff --git a/client/phnc.h b/client/phnc.h index 0aed10a..fab230e 100644 --- a/client/phnc.h +++ b/client/phnc.h @@ -24,5 +24,7 @@ #endif #define API __attribute__((visibility("default"))) +int phnc_get_uid(void); + #endif /*__PHONENUMBER_UTILS_CLIENT_H__*/ diff --git a/common/phn-common.h b/common/phn-common.h index 435aa60..be4c8ff 100644 --- a/common/phn-common.h +++ b/common/phn-common.h @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef __PHONENUMBER_UTILS_COMMON_H__ #define __PHONENUMBER_UTILS_COMMON_H__ -#include "phone_number_errors.h" - #ifndef PHN_DBUS_INTERFACE #define PHN_DBUS_INTERFACE "org.tizen.PhonenumberUtils.dbus" #endif diff --git a/common/phn-dbus-utils.c b/common/phn-dbus-utils.c new file mode 100644 index 0000000..b975b59 --- /dev/null +++ b/common/phn-dbus-utils.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015 - 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 +#include +#include + +#include "phone_number_errors.h" +#include "phone_number_types.h" +#include "phn-log.h" +#include "phn-record.h" + +#define PHN_DBUS_SET_STRING(x) (x) ? x : "" +#define PHN_DBUS_GET_STRING(x) do { \ + x = (NULL != x) ? strdup(x) : NULL; \ +} while (0) + + +GVariant* phn_dbus_utils_record_to_gvariant(phone_number_blocking_rule_h record) +{ + RETV_IF(NULL == record, (GVariant*)""); + + GVariant *value = NULL; + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + value = g_variant_new("(iiiss)", + p->id, + p->match_type, + p->user_id, + PHN_DBUS_SET_STRING(p->number), + PHN_DBUS_SET_STRING(p->normalized_number)); + + return value; +} + +GVariant* phn_dbus_utils_list_to_gvariant(GSList *list) +{ + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE("av")); + + GSList *cursor = list; + + if (NULL == list) { + phone_number_blocking_rule_h record = NULL; + phn_record_create(&record); + GVariant *arg_record = phn_dbus_utils_record_to_gvariant(record); + g_variant_builder_add(&builder, "v", arg_record); + phn_record_destroy(record); + } + + while (cursor) { + phone_number_blocking_rule_h record = cursor->data; + GVariant *arg_record = phn_dbus_utils_record_to_gvariant(record); + g_variant_builder_add(&builder, "v", arg_record); + cursor = g_slist_next(cursor); + } + + return g_variant_builder_end(&builder); +} + + +int phn_dbus_utils_gvariant_to_record(GVariant *arg_record, phone_number_blocking_rule_h *out_record) +{ + RETV_IF(NULL == arg_record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phone_number_blocking_rule_h record = NULL; + phn_record_create(&record); + + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + g_variant_get(arg_record, "(iii&s&s)", + &p->id, + &p->match_type, + &p->user_id, + &p->number, + &p->normalized_number); + PHN_DBUS_GET_STRING(p->number); + PHN_DBUS_GET_STRING(p->normalized_number); + + *out_record = record; + + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_dbus_utils_gvariant_to_array(GVariant *arg_list, phone_number_blocking_rule_h **out_array, int *length) +{ + RETV_IF(NULL == out_array, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + GVariantIter *iter_value = NULL; + g_variant_get(arg_list, "av", &iter_value); + + GVariant *arg_record = NULL; + GSList *list = NULL; + while (g_variant_iter_loop(iter_value, "v", &arg_record)) { + phone_number_blocking_rule_h record = NULL; + phn_dbus_utils_gvariant_to_record(arg_record, &record); + list = g_slist_append(list, record); + } + + if (NULL != list) { + int cnt = (int)g_slist_length(list); + GSList *cursor = list; + + phone_number_blocking_rule_h *array = calloc(cnt, sizeof(phone_number_blocking_rule_h)); + if (NULL == array) { + ERR("calloc() fail"); + return PHONE_NUMBER_ERROR_OUT_OF_MEMORY; + } + + int idx = 0; + while (cursor) { + if (idx == cnt) { + ERR("g_slist_length() returns wrong value[%d]", cnt); + *length = 0; + free(array); + g_slist_free_full(list, phn_record_free); + return PHONE_NUMBER_ERROR_SYSTEM; + } + + phone_number_blocking_rule_h record = cursor->data; + array[idx++] = record; + cursor = g_slist_next(cursor); + } + g_slist_free(list); + *out_array = array; + *length = idx; + } + + return PHONE_NUMBER_ERROR_NONE; +} + diff --git a/common/phn-dbus-utils.h b/common/phn-dbus-utils.h new file mode 100644 index 0000000..dc08615 --- /dev/null +++ b/common/phn-dbus-utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2015 - 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. + */ + + +#ifndef __PHN_DBUS_UTILS_H__ +#define __PHN_DBUS_UTILS_H__ + +#include "phone_number_types.h" + +GVariant* phn_dbus_utils_record_to_gvariant(phone_number_blocking_rule_h record); +GVariant* phn_dbus_utils_list_to_gvariant(GSList *list); +int phn_dbus_utils_gvariant_to_record(GVariant *arg_record, phone_number_blocking_rule_h *out_record); +int phn_dbus_utils_gvariant_to_array(GVariant *arg_list, phone_number_blocking_rule_h **array, int *length); +#endif /* __PHN_DBUS_UTILS_H__ */ + diff --git a/common/phn-dbus.xml b/common/phn-dbus.xml index 2b1e983..ad5075c 100644 --- a/common/phn-dbus.xml +++ b/common/phn-dbus.xml @@ -18,6 +18,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/common/phn-log.h b/common/phn-log.h index 72f16a5..7a30c61 100644 --- a/common/phn-log.h +++ b/common/phn-log.h @@ -16,8 +16,9 @@ * limitations under the License. * */ -#ifndef __PHONENUMBER_COMMON_LOG_H__ -#define __PHONENUMBER_COMMON_LOG_H__ + +#ifndef __PHONENUMBER_UTILS_LOG_H__ +#define __PHONENUMBER_UTILS_LOG_H__ #ifdef PHN_CONSOLE_COLOR_LOG #define PHN_LOG_RED "\033[0;31m" @@ -136,4 +137,4 @@ } \ } while (0) -#endif /* __PHONENUMBER_COMMON_LOG_H__ */ +#endif /* __PHONENUMBER_UTILS_LOG_H__ */ diff --git a/common/phn-property.h b/common/phn-property.h new file mode 100644 index 0000000..3e18591 --- /dev/null +++ b/common/phn-property.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHN_PROPERTY_H__ +#define __PHN_PROPERTY_H__ + +/* for property 0xFF000000 */ +#define PHN_PROPERTY_MASK 0x0FF00000 +#define PHN_PROPERTY_BLOCKING_RULE 0x01000000 + +/* f or type check: data_type mask 0x000F0000 */ +#define PHN_PROPERTY_DATA_TYPE_MASK 0x000F0000 +#define PHN_PROPERTY_DATA_TYPE_INT 0x00010000 +#define PHN_PROPERTY_DATA_TYPE_STR 0x00020000 +#define PHN_PROPERTY_DATA_CHECK(property_id, data_type) \ + ((property_id & PHN_PROPERTY_DATA_TYPE_MASK) == data_type ? true : false) + +#define PHN_PROPERTY_RW_MASK 0x0000F000 +#define PHN_PROPERTY_READ_ONLY 0x00001000 +#define PHN_PROPERTY_RW_CHECK(property_id, data_type) \ + ((property_id & PHN_PROPERTY_RW_MASK) == data_type ? true : false) + +typedef enum { + PHN_PROPERTY_BLOCKING_RULE_ID = (PHN_PROPERTY_BLOCKING_RULE | PHN_PROPERTY_DATA_TYPE_INT) + 0, + PHN_PROPERTY_BLOCKING_RULE_MATCH_TYPE = (PHN_PROPERTY_BLOCKING_RULE | PHN_PROPERTY_DATA_TYPE_INT) + 1, + PHN_PROPERTY_BLOCKING_RULE_USER_ID = (PHN_PROPERTY_BLOCKING_RULE | PHN_PROPERTY_DATA_TYPE_INT) + 2, + PHN_PROPERTY_BLOCKING_RULE_NUMBER = (PHN_PROPERTY_BLOCKING_RULE | PHN_PROPERTY_DATA_TYPE_STR) + 3, + PHN_PROPERTY_BLOCKING_RULE_NORMALIZED_NUMBER = (PHN_PROPERTY_BLOCKING_RULE | PHN_PROPERTY_DATA_TYPE_STR) + 4, +} phn_property_e; + +#endif /* __PHN_PROPERTY_H__ */ + diff --git a/common/phn-record.c b/common/phn-record.c new file mode 100644 index 0000000..bdccf38 --- /dev/null +++ b/common/phn-record.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015 - 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 "phone_number_errors.h" +#include "phn-log.h" +#include "phn-utils.h" +#include "phn-record.h" +#include "phn-property.h" + +int phn_record_create(phone_number_blocking_rule_h *out_record) +{ + RETV_IF(NULL == out_record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phn_blocking_rule_s *p = NULL; + p = calloc(1, sizeof(phn_blocking_rule_s)); + if (NULL == p) { + ERR("calloc() Fail"); + return PHONE_NUMBER_ERROR_OUT_OF_MEMORY; + } + *out_record = (phone_number_blocking_rule_h)p; + + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_record_destroy(phone_number_blocking_rule_h record) +{ + RETV_IF(NULL == record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + PHN_FREE(p->number); + PHN_FREE(p->normalized_number); + PHN_FREE(p); + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_record_get_str(phone_number_blocking_rule_h record, unsigned int property_id, char** out_value) +{ + RETV_IF(NULL == record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == out_value, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + switch (property_id) { + case PHN_PROPERTY_BLOCKING_RULE_NUMBER: + *out_value = PHN_STRDUP(p->number); + break; + case PHN_PROPERTY_BLOCKING_RULE_NORMALIZED_NUMBER: + *out_value = PHN_STRDUP(p->normalized_number); + break; + default: + ERR("Invalid parameter(perperty:0x%x)", property_id); + return PHONE_NUMBER_ERROR_INVALID_PARAMETER; + } + + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_record_get_int(phone_number_blocking_rule_h record, unsigned int property_id, int* out_value) +{ + RETV_IF(NULL == record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == out_value, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + switch (property_id) { + case PHN_PROPERTY_BLOCKING_RULE_ID: + *out_value = (p->id); + break; + case PHN_PROPERTY_BLOCKING_RULE_MATCH_TYPE: + *out_value = (p->match_type); + break; + case PHN_PROPERTY_BLOCKING_RULE_USER_ID: + *out_value = (p->user_id); + break; + default: + ERR("Invalid parameter(perperty:0x%x)", property_id); + return PHONE_NUMBER_ERROR_INVALID_PARAMETER; + } + + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_record_set_str(phone_number_blocking_rule_h record, unsigned int property_id, const char *value) +{ + RETV_IF(NULL == record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + switch (property_id) { + case PHN_PROPERTY_BLOCKING_RULE_NUMBER: + PHN_FREE(p->number); + p->number = PHN_STRDUP(value); + break; + default: + ERR("Invalid parameter(perperty:0x%x)", property_id); + return PHONE_NUMBER_ERROR_INVALID_PARAMETER; + } + + return PHONE_NUMBER_ERROR_NONE; +} + +int phn_record_set_int(phone_number_blocking_rule_h record, unsigned int property_id, int value) +{ + RETV_IF(NULL == record, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + phn_blocking_rule_s *p = (phn_blocking_rule_s *)record; + switch (property_id) { + case PHN_PROPERTY_BLOCKING_RULE_MATCH_TYPE: + p->match_type = value; + break; + case PHN_PROPERTY_BLOCKING_RULE_USER_ID: + p->user_id = value; + break; + default: + ERR("Invalid parameter(perperty:0x%x)", property_id); + return PHONE_NUMBER_ERROR_INVALID_PARAMETER; + } + + return PHONE_NUMBER_ERROR_NONE; +} + +void phn_record_free(gpointer data) +{ + phone_number_blocking_rule_h record = data; + + phn_record_destroy(record); +} + + diff --git a/common/phn-record.h b/common/phn-record.h new file mode 100644 index 0000000..90a6997 --- /dev/null +++ b/common/phn-record.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHN_RECORD_H__ +#define __PHN_RECORD_H__ + +#include + +#include "phone_number_types.h" + +typedef struct { + int id; + int match_type; + int user_id; + char *number; + char *normalized_number; +} phn_blocking_rule_s; + +int phn_record_create(phone_number_blocking_rule_h* out_record); +int phn_record_destroy(phone_number_blocking_rule_h record); +int phn_record_get_str(phone_number_blocking_rule_h record, unsigned int property_id, char** out_value); +int phn_record_get_str_p(phone_number_blocking_rule_h record, unsigned int property_id, char** out_value); +int phn_record_get_int(phone_number_blocking_rule_h record, unsigned int property_id, int* out_value); +int phn_record_set_str(phone_number_blocking_rule_h record, unsigned int property_id, const char* value); +int phn_record_set_int(phone_number_blocking_rule_h record, unsigned int property_id, int value); +void phn_record_free(gpointer data); + +#endif /* __PHN_RECORD_H__ */ + diff --git a/common/phn-utils.h b/common/phn-utils.h new file mode 100644 index 0000000..27471e1 --- /dev/null +++ b/common/phn-utils.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHN_UTILS_H__ +#define __PHN_UTILS_H__ + +#include + +#define PHN_FREE(x) do {\ + free(x); \ + x = NULL; \ +} while (0) + +#define PHN_STRDUP(x) (x) ? strdup(x) : NULL; + +#endif /* __PHN_UTILS_H__ */ + diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 41ea3f9..fea2f3c 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -1,21 +1,19 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) -SET(DAEMON_SRCS - phnd.c - phnd-dbus.c - phnd-region-data.c - phnd-utils.c - phnd-libphonenumber.cpp -) - -SET(DAEMON_SRCS ${DAEMON_SRCS} ${CMAKE_SOURCE_DIR}/common/phn-dbus.c) +FILE(GLOB DAEMON_SRCS *.c*) +SET(DAEMON_SRCS ${DAEMON_SRCS} + ${CMAKE_SOURCE_DIR}/common/phn-dbus.c + ${CMAKE_SOURCE_DIR}/common/phn-dbus-utils.c + ${CMAKE_SOURCE_DIR}/common/phn-record.c) SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/common/phn-dbus.c PROPERTIES GENERATED TRUE) pkg_check_modules(daemon_pkgs REQUIRED dlog icu-i18n glib-2.0 gio-2.0 gio-unix-2.0 - capi-base-common capi-system-system-settings tapi libtzplatform-config) + capi-base-common capi-system-system-settings tapi libtzplatform-config sqlite3 + db-util) INCLUDE_DIRECTORIES(${daemon_pkgs_INCLUDE_DIRS}) LINK_DIRECTORIES(${daemon_pkgs_LIBRARY_DIRS}) @@ -24,6 +22,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--hash-style=both -pie") ADD_DEFINITIONS("-DPHN_DBUS_INTERFACE=\"${DBUS_INTERFACE}\"") +ADD_DEFINITIONS("-DPHND_SYS_DB=\"${PHND_SYS_DB}\"") ADD_EXECUTABLE(${DAEMON} ${DAEMON_SRCS}) ADD_DEPENDENCIES(${DAEMON} GENERATED_DBUS_CODE) diff --git a/daemon/phnd-blocking_rule.c b/daemon/phnd-blocking_rule.c new file mode 100644 index 0000000..49c6cc4 --- /dev/null +++ b/daemon/phnd-blocking_rule.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2015 - 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 +#include + +#include "phone_number_errors.h" +#include "phone_number_types.h" +#include "phn-common.h" +#include "phn-log.h" +#include "phn-record.h" +#include "phn-utils.h" +#include "phnd-libphonenumber.h" +#include "phnd-blocking_rule.h" +#include "phnd-db-utils.h" +#include "phnd-sqlite.h" + +#define PHND_TABLE_BLOCKNUMBER "blocknumbers" +#define PHND_BULK_COUNT 100 +#define PHND_BULK_SLEEP 500 + +static int __blocking_rule_add(phone_number_blocking_rule_h rule) +{ + int ret = 0; + char query[PHN_STR_SHORT_LEN] = {0}; + phn_blocking_rule_s *p = (phn_blocking_rule_s *)rule; + phnd_stmt *stmt = NULL; + + snprintf(query, sizeof(query), "INSERT INTO "PHND_TABLE_BLOCKNUMBER" (" + "match_type, user_id, number, normalized_number) VALUES (%d, %d, ?, ?)", + p->match_type, p->user_id); + ret = phnd_sqlite_prepare(query, &stmt); + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_prepare() Fail(%d)", ret); + SECURE_ERR("query[%s]", query); + return ret; + /* LCOV_EXCL_STOP */ + } + + if (p->number) + phnd_sqlite_bind_text(stmt, 1, p->number); + + do { + if (NULL == p->number || '\0' == *p->number) + break; + if (PHONE_NUMBER_MATCH_TYPE_EXACTLY != p->match_type) { + phnd_sqlite_bind_text(stmt, 2, p->number); + } else { + char *normalized_number = NULL; + ret = phn_get_normalized_number(p->number, &normalized_number); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phn_get_normalized_number() Fail(%d)", ret); + break; + } + phnd_sqlite_bind_text(stmt, 2, normalized_number); + } + } while (0); + + ret = phnd_sqlite_step(stmt); + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_step() Fail(%d)", ret); + phnd_sqlite_finalize(stmt); + return ret; + /* LCOV_EXCL_STOP */ + } + phnd_sqlite_finalize(stmt); + + return PHONE_NUMBER_ERROR_NONE; +} + +int phnd_blocking_rule_add(phone_number_blocking_rule_h rule) +{ + FN_CALL; + + RETV_IF(NULL == rule, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + int ret = 0; + + ret = phnd_db_utils_begin_trans(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_db_utils_begin_trans() Fail(%d)", ret); + return ret; + } + + ret = __blocking_rule_add(rule); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("__blocking_rule_add() Fail(%d)", ret); + phnd_db_utils_end_trans(true); + return ret; + } + phnd_db_utils_end_trans(true); + + return PHONE_NUMBER_ERROR_NONE; +} + +int phnd_blocking_rule_remove(int id) +{ + RETV_IF(id <= 0, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + int ret = 0; + char query[PHN_STR_SHORT_LEN] = {0}; + + ret = phnd_db_utils_begin_trans(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_db_utils_begin_trans() Fail(%d)", ret); + return ret; + } + + snprintf(query, sizeof(query), "DELETE FROM "PHND_TABLE_BLOCKNUMBER" WHERE id = %d", id); + ret = phnd_sqlite_exec(query); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_sqlite_exec() Fail(%d)", ret); + phnd_db_utils_end_trans(false); + return ret; + } + phnd_db_utils_end_trans(true); + + return PHONE_NUMBER_ERROR_NONE; +} + +int phnd_blocking_rule_get(int user_id, int offset, int limit, GSList **rule_list) +{ + FN_CALL; + + RETV_IF(NULL == rule_list, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + int ret = 0; + char query[PHN_STR_SHORT_LEN] = {0}; + + GSList *list = NULL; + + ret = phnd_db_utils_begin_trans(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_db_utils_begin_trans() Fail(%d)", ret); + return ret; + } + + int len = 0; + len = snprintf(query, sizeof(query), "SELECT id, match_type, user_id, number, normalized_number " + "FROM "PHND_TABLE_BLOCKNUMBER" WHERE user_id = %d", user_id); + if (0 < offset) + len += snprintf(query + len, sizeof(query) - len, " OFFSET %d", offset); + if (0 < limit) + len += snprintf(query + len, sizeof(query) - len, " LIMIT %d", limit); + + phnd_stmt *stmt = NULL; + ret = phnd_sqlite_prepare(query, &stmt); + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_prepare() Fail(%d)", ret); + SECURE_ERR("query[%s]", query); + phnd_db_utils_end_trans(false); + return ret; + /* LCOV_EXCL_STOP */ + } + while (PHND_SQLITE_ROW == phnd_sqlite_step(stmt)) { + phone_number_blocking_rule_h rule = NULL; + ret = phn_record_create(&rule); + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phn_record_create() Fail(%d)", ret); + phnd_sqlite_finalize(stmt); + phnd_db_utils_end_trans(false); + phn_record_destroy(rule); + g_slist_free_full(list, phn_record_free); + return ret; + /* LCOV_EXCL_STOP */ + } + const unsigned char *temp; + phn_blocking_rule_s *p = (phn_blocking_rule_s *)rule; + p->id = sqlite3_column_int(stmt, 0); + p->match_type = sqlite3_column_int(stmt, 1); + p->user_id = sqlite3_column_int(stmt, 2); + temp = sqlite3_column_text(stmt, 3); + p->number = PHN_STRDUP((const char *)temp); + temp = sqlite3_column_text(stmt, 4); + p->normalized_number = PHN_STRDUP((const char *)temp); + + list = g_slist_append(list, rule); + } + phnd_sqlite_finalize(stmt); + phnd_db_utils_end_trans(true); + + *rule_list = list; + if (NULL == list) + return PHONE_NUMBER_ERROR_NO_DATA; + + return PHONE_NUMBER_ERROR_NONE; +} + +bool __is_valid_number(const char *number) +{ + bool is_valid = true; + char *p = (char *)number; + while (*p) { + switch (*p) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + break; + default: + is_valid = false; + break; + } + if (false == is_valid) + break; + p++; + } + + return is_valid; +} + +/* + * 070 -> nomalized to +82070 + * so it is failed to check +8270xxxxx number + */ +int phnd_blocking_rule_check(int user_id, const char *number, int *is_blocked) +{ + FN_CALL; + + RETV_IF(NULL == number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF('\0' == *number, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == is_blocked, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + int ret = 0; + char query[PHN_STR_SHORT_LEN] = {0}; + + if (false == __is_valid_number(number)) { + ERR("__is_valid_number() Fail"); + return PHONE_NUMBER_ERROR_INVALID_PARAMETER; + } + + ret = phnd_db_utils_begin_trans(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_db_utils_begin_trans() Fail(%d)", ret); + return ret; + } + + char *normalized = NULL; + phn_get_normalized_number(number, &normalized); + ret = snprintf(query, sizeof(query), "SELECT count(*) FROM "PHND_TABLE_BLOCKNUMBER" " + "WHERE user_id = %d AND (CASE " + "WHEN match_type = %d " + "THEN '%s' = number OR '%s' = normalized_number " + "WHEN match_type = %d " + "THEN SUBSTR('%s', 1, LENGTH(number)) = number OR " + "SUBSTR('%s', 1, LENGTH(normalized_number)) = normalized_number " + "WHEN match_type = %d " + "THEN SUBSTR('%s', -LENGTH(normalized_number)) = number " + "WHEN match_type = %d " + "THEN INSTR('%s', number) " + "END) ", + user_id, + PHONE_NUMBER_MATCH_TYPE_EXACTLY, number, normalized, + PHONE_NUMBER_MATCH_TYPE_STARTS_WITH, number, normalized, + PHONE_NUMBER_MATCH_TYPE_ENDS_WITH, number, + PHONE_NUMBER_MATCH_TYPE_INCLUDES, number); + + DBG("query : %s", query); + + phnd_stmt *stmt = NULL; + ret = phnd_sqlite_prepare(query, &stmt); + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_prepare() Fail(%d)", ret); + SECURE_ERR("query[%s]", query); + phnd_db_utils_end_trans(false); + return ret; + /* LCOV_EXCL_STOP */ + } + int count = 0; + if (PHND_SQLITE_ROW == phnd_sqlite_step(stmt)) + count = sqlite3_column_int(stmt, 0); + + *is_blocked = 0 == count ? 0 : 1; + phnd_sqlite_finalize(stmt); + phnd_db_utils_end_trans(true); + + return PHONE_NUMBER_ERROR_NONE; +} + diff --git a/daemon/phnd-blocking_rule.h b/daemon/phnd-blocking_rule.h new file mode 100644 index 0000000..736afbd --- /dev/null +++ b/daemon/phnd-blocking_rule.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHND_BLOCKING_RULE_H__ +#define __PHND_BLOCKING_RULE_H__ + +#include + +#include "phone_number_types.h" + +int phnd_blocking_rule_add(phone_number_blocking_rule_h rule); +int phnd_blocking_rule_remove(int id); +int phnd_blocking_rule_get(int user_id, int offset, int limit, GSList **rule_list); +int phnd_blocking_rule_check(int user_id, const char *number, int *is_blocked); + +#endif /*__PHND_BLOCKING_RULE_H__*/ + diff --git a/daemon/phnd-db-utils.c b/daemon/phnd-db-utils.c new file mode 100644 index 0000000..042dc7e --- /dev/null +++ b/daemon/phnd-db-utils.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015 - 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 + +#include "phone_number_errors.h" +#include "phn-common.h" +#include "phn-log.h" +#include "phnd-sqlite.h" + +#define PHND_COMMIT_TRY_MAX 500000 /* For 3second */ + +static __thread int transaction_count = 0; + +int phnd_db_utils_begin_trans(void) +{ + int ret = 0; + int progress; + + if (transaction_count <= 0) { + ret = phnd_sqlite_exec("BEGIN IMMEDIATE TRANSACTION"); + progress = 100000; + while (PHONE_NUMBER_ERROR_DB_FAILED == ret && progress < PHND_COMMIT_TRY_MAX) { + usleep(progress); + ret = phnd_sqlite_exec("BEGIN IMMEDIATE TRANSACTION"); + progress *= 2; + } + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_exec() Fail(%d)", ret); + return ret; + /* LCOV_EXCL_STOP */ + } + transaction_count = 0; + } + transaction_count++; + INFO("transaction_count : %d.", transaction_count); + + return PHONE_NUMBER_ERROR_NONE; +} + +int phnd_db_utils_end_trans(bool is_success) +{ + int ret = 0; + int progress; + + transaction_count--; + INFO("%s, transaction_count : %d", is_success ? "True" : "False", transaction_count); + + if (0 != transaction_count) { + DBG("contact transaction_count : %d.", transaction_count); + return PHONE_NUMBER_ERROR_NONE; + } + + if (false == is_success) { + ret = phnd_sqlite_exec("ROLLBACK TRANSACTION"); + return PHONE_NUMBER_ERROR_NONE; + } + + INFO("start commit"); + progress = 100000; + ret = phnd_sqlite_exec("COMMIT TRANSACTION"); + while (PHONE_NUMBER_ERROR_DB_FAILED == ret && progress < PHND_COMMIT_TRY_MAX) { + usleep(progress); + ret = phnd_sqlite_exec("COMMIT TRANSACTION"); + progress *= 2; + } + INFO("%s", (PHONE_NUMBER_ERROR_NONE == ret) ? "commit" : "rollback"); + + if (PHONE_NUMBER_ERROR_NONE != ret) { + /* LCOV_EXCL_START */ + ERR("phnd_sqlite_exec() Fail(%d)", ret); + + int tmp_ret = phnd_sqlite_exec("ROLLBACK TRANSACTION"); + if (PHONE_NUMBER_ERROR_NONE != tmp_ret) + ERR("phnd_sqlite_exec(ROLLBACK) Fail(%d)", tmp_ret); + + return ret; + /* LCOV_EXCL_STOP */ + } + + return PHONE_NUMBER_ERROR_NONE; +} + diff --git a/daemon/phnd-db-utils.h b/daemon/phnd-db-utils.h new file mode 100644 index 0000000..ab069e8 --- /dev/null +++ b/daemon/phnd-db-utils.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHND_DB_UTILS_H__ +#define __PHND_DB_UTILS_H__ + +int phnd_db_utils_begin_trans(void); +int phnd_db_utils_end_trans(bool is_success); + +#endif /*__PHND_DB_UTILS_H__*/ + diff --git a/daemon/phnd-dbus.c b/daemon/phnd-dbus.c index eca948b..2029301 100644 --- a/daemon/phnd-dbus.c +++ b/daemon/phnd-dbus.c @@ -13,16 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include +#include -#include "phn-dbus.h" +#include "phone_number_errors.h" #include "phn-log.h" #include "phn-common.h" +#include "phn-utils.h" +#include "phn-record.h" +#include "phn-dbus.h" +#include "phn-dbus-utils.h" #include "phnd.h" #include "phnd-utils.h" #include "phnd-libphonenumber.h" #include "phnd-region-data.h" +#include "phnd-blocking_rule.h" static inline int _dbus_get_location_handler(const char *number, phone_number_region_e region, phone_number_lang_e lang, char **location) @@ -192,6 +199,75 @@ static gboolean _dbus_handle_get_normalized_number(phnDbus *object, return TRUE; } +static gboolean _dbus_handle_add_blocking_rule(phnDbus *object, + GDBusMethodInvocation *invocation, + GVariant *arg_record) +{ + FN_CALL; + + int ret = 0; + phone_number_blocking_rule_h rule = NULL; + phn_dbus_utils_gvariant_to_record(arg_record, &rule); + + ret = phnd_blocking_rule_add(rule); + + phn_dbus_complete_add_blocking_rule(object, invocation, ret); + phn_record_destroy(rule); + phnd_utils_start_timeout(); + + return TRUE; +} + + +static gboolean _dbus_handle_remove_blocking_rule(phnDbus *object, + GDBusMethodInvocation *invocation, + gint id) +{ + int ret = 0; + ret = phnd_blocking_rule_remove(id); + + phn_dbus_complete_remove_blocking_rule(object, invocation, ret); + phnd_utils_start_timeout(); + + return TRUE; +} + +static gboolean _dbus_handle_check_blocking(phnDbus *object, + GDBusMethodInvocation *invocation, + gint user_id, + gchar *number) +{ + int ret = 0; + int is_blocked = 0; + ret = phnd_blocking_rule_check(user_id, number, &is_blocked); + + phn_dbus_complete_check_blocking(object, invocation, is_blocked, ret); + phnd_utils_start_timeout(); + + return TRUE; +} + +static gboolean _dbus_handle_get_blocking_rules(phnDbus *object, + GDBusMethodInvocation *invocation, + gint user_id, + gint offset, + gint limit) +{ + FN_CALL; + + int ret = 0; + GSList *list = NULL; + ret = phnd_blocking_rule_get(user_id, offset, limit, &list); + + GVariant *arg_list = phn_dbus_utils_list_to_gvariant(list); + phn_dbus_complete_get_blocking_rules(object, invocation, arg_list, ret); + g_slist_free_full(list, phn_record_free); + // TODO: g_variant_unref(arg_list); + phnd_utils_start_timeout(); + + return TRUE; +} + static void _dbus_bus_acquired_handler(GDBusConnection *conn, const gchar *name, gpointer user_data) { @@ -210,6 +286,14 @@ static void _dbus_bus_acquired_handler(GDBusConnection *conn, const gchar *name, G_CALLBACK(_dbus_handle_get_number), NULL); g_signal_connect(dbus_object, "handle-get-normalized-number", G_CALLBACK(_dbus_handle_get_normalized_number), NULL); + g_signal_connect(dbus_object, "handle-add-blocking-rule", + G_CALLBACK(_dbus_handle_add_blocking_rule), NULL); + g_signal_connect(dbus_object, "handle-remove-blocking-rule", + G_CALLBACK(_dbus_handle_remove_blocking_rule), NULL); + g_signal_connect(dbus_object, "handle-get-blocking-rules", + G_CALLBACK(_dbus_handle_get_blocking_rules), NULL); + g_signal_connect(dbus_object, "handle-check-blocking", + G_CALLBACK(_dbus_handle_check_blocking), NULL); ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(dbus_object), conn, PHN_DBUS_OBJPATH, &error); @@ -266,3 +350,4 @@ void phnd_dbus_deinit(unsigned int id) { g_bus_unown_name(id); } + diff --git a/daemon/phnd-dbus.h b/daemon/phnd-dbus.h index 9e51a77..9abb6d9 100644 --- a/daemon/phnd-dbus.h +++ b/daemon/phnd-dbus.h @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef __PHONENUMBER_UTILS_DAEMON_DBUS_H__ #define __PHONENUMBER_UTILS_DAEMON_DBUS_H__ unsigned int phnd_dbus_init(); void phnd_dbus_deinit(unsigned int id); - #endif /*__PHONENUMBER_UTILS_DAEMON_DBUS_H__*/ diff --git a/daemon/phnd-libphonenumber.cpp b/daemon/phnd-libphonenumber.cpp index 47d6523..9331d29 100644 --- a/daemon/phnd-libphonenumber.cpp +++ b/daemon/phnd-libphonenumber.cpp @@ -25,6 +25,7 @@ #include #include +#include "phone_number_errors.h" #include "phnd.h" #include "phnd-libphonenumber.h" diff --git a/daemon/phnd-libphonenumber.h b/daemon/phnd-libphonenumber.h index bfbb2b9..1f2c44b 100644 --- a/daemon/phnd-libphonenumber.h +++ b/daemon/phnd-libphonenumber.h @@ -16,8 +16,8 @@ * limitations under the License. * */ -#ifndef __PHONENUMBER_LIBPHONENUMBER_H__ -#define __PHONENUMBER_LIBPHONENUMBER_H__ +#ifndef __PHONENUMBER_UTILS_DAEMON_LIBPHONENUMBER_H__ +#define __PHONENUMBER_UTILS_DAEMON_LIBPHONENUMBER_H__ #ifdef __cplusplus extern "C" { @@ -34,4 +34,4 @@ int phn_get_normalized_number(const char *number, char **out_e164); } #endif -#endif /* __PHONENUMBER_LIBPHONENUMBER_H__ */ +#endif /* __PHONENUMBER_UTILS_DAEMON_LIBPHONENUMBER_H__ */ diff --git a/daemon/phnd-region-data.c b/daemon/phnd-region-data.c index aa0779c..5d0262d 100644 --- a/daemon/phnd-region-data.c +++ b/daemon/phnd-region-data.c @@ -20,6 +20,7 @@ #include #include +#include "phone_number_errors.h" #include "phnd.h" #include "phnd-region-data.h" diff --git a/daemon/phnd-schema.c b/daemon/phnd-schema.c new file mode 100644 index 0000000..8b802ba --- /dev/null +++ b/daemon/phnd-schema.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015 - 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 +#include +#include +#include +#include +#include + +#include "schema.h" +#include "phn-log.h" +#include "phnd-schema.h" + +static int __remake_db_file(void) +{ + int ret; + char *errmsg = NULL; + sqlite3 *db; + + ret = db_util_open(PHND_DB_FILE, &db, 0); + if (SQLITE_OK != ret) { + /* LCOV_EXCL_START */ + ERR("db_util_open() Fail(%d) ", ret); + return -1; + /* LCOV_EXCL_STOP */ + } + + ret = sqlite3_exec(db, schema_query, NULL, 0, &errmsg); + if (SQLITE_OK != ret) { + /* LCOV_EXCL_START */ + ERR("sqlite3_exec() Fail[%s]", errmsg); + sqlite3_free(errmsg); + db_util_close(db); + return -1; + /* LCOV_EXCL_STOP */ + } + db_util_close(db); + return 0; +} + +static int __check_db_file(void) +{ + int fd = -1; + fd = open(PHND_DB_FILE, O_RDONLY); + if (fd < 0) { + /* LCOV_EXCL_START */ + ERR("DB file(%s) is not exist(err:%d) ", PHND_DB_FILE, fd); + return -1; + /* LCOV_EXCL_STOP */ + } + close(fd); + return 0; +} + +int phnd_schema_check(void) +{ + if (__check_db_file()) + __remake_db_file(); + return 0; +} diff --git a/daemon/phnd-schema.h b/daemon/phnd-schema.h new file mode 100644 index 0000000..80e4abf --- /dev/null +++ b/daemon/phnd-schema.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHONENUMBER_UTILS_DAEMONSCHEMA__ +#define __PHONENUMBER_UTILS_DAEMONSCHEMA__ + +#include + +#define PHND_DB_FILE PHND_SYS_DB"/.phonenumber-utils.db" + +int phnd_schema_check(void); + +#endif /*__PHONENUMBER_UTILS_DAEMONSCHEMA__*/ + diff --git a/daemon/phnd-sqlite.c b/daemon/phnd-sqlite.c new file mode 100644 index 0000000..13c6249 --- /dev/null +++ b/daemon/phnd-sqlite.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015 - 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 +#include +#include + +#include "phone_number_errors.h" +#include "phn-common.h" +#include "phn-log.h" +#include "phn-record.h" +#include "phnd-schema.h" +#include "phnd-sqlite.h" +#include "phnd-db-utils.h" + +#define PHND_SQLITE_RETRY_TIME 4 +#define PHND_SQLITE_RETRY_INTERVAL (50*1000) + +static __thread sqlite3 *db = NULL; + +int phnd_sqlite_open_db(void) +{ + FN_CALL; + + int ret = 0; + + if (NULL == db) { + ret = db_util_open(PHND_DB_FILE, &db, 0); + if (SQLITE_OK != ret || NULL == db) { + ERR("db_util_open() Fail(%d), db(0x%x)", ret, db); + return PHONE_NUMBER_ERROR_DB_FAILED; + } + } + + return PHONE_NUMBER_ERROR_NONE; +} + +void phnd_sqlite_close_db(void) +{ + int ret = 0; + if (db) { + ret = db_util_close(db); + if (SQLITE_OK != ret) { + ERR("db_util_close() Fail(%d)", ret); + db = NULL; + } + DBG("The database disconnected really."); + } +} + +int phnd_sqlite_get_last_insert_id(void) +{ + RETV_IF(NULL == db, PHONE_NUMBER_ERROR_DB_FAILED); + + return sqlite3_last_insert_rowid(db); +} + +int phnd_sqlite_exec(const char *query) +{ + RETV_IF(NULL == db, PHONE_NUMBER_ERROR_DB_FAILED); + + int ret = 0; + char *errmsg = NULL; + + ret = sqlite3_exec(db, query, NULL, NULL, &errmsg); + if (SQLITE_OK != ret) { + ERR("sqlite3_exec() Fail(%d:%s)", ret, errmsg); + return PHONE_NUMBER_ERROR_DB_FAILED; + } + return PHONE_NUMBER_ERROR_NONE; +} + +int phnd_sqlite_prepare(const char *query, phnd_stmt **stmt) +{ + RETV_IF(NULL == query, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == db, PHONE_NUMBER_ERROR_DB_FAILED); + + int ret = 0; + struct timeval from, now, diff; + bool retry = false; + + gettimeofday(&from, NULL); + do { + ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL); + if (SQLITE_OK != ret) + ERR("sqlite3_prepare_v2() Fail(%d:%s)", ret, sqlite3_errmsg(db)); + if (SQLITE_BUSY == ret || SQLITE_LOCKED == ret) { + gettimeofday(&now, NULL); + timersub(&now, &from, &diff); + retry = (diff.tv_sec < PHND_SQLITE_RETRY_TIME) ? true : false; + if (retry) + usleep(PHND_SQLITE_RETRY_INTERVAL); + } else { + retry = false; + } + } while (retry); + + switch (ret) { + case SQLITE_OK: + ret = PHONE_NUMBER_ERROR_NONE; + break; + default: + ERR("sqlite3_step() Fail(%d)", ret); + ret = PHONE_NUMBER_ERROR_DB_FAILED; + break; + } + return ret; +} + +int phnd_sqlite_step(phnd_stmt *stmt) +{ + RETV_IF(NULL == db, PHONE_NUMBER_ERROR_DB_FAILED); + + int ret = 0; + struct timeval from, now, diff; + bool retry = false; + + gettimeofday(&from, NULL); + do { + ret = sqlite3_step(stmt); + if (SQLITE_ROW != ret && SQLITE_DONE != ret) { + ERR("sqlite3_step() Fail(%d, %s, %d)", ret, sqlite3_errmsg(db), + sqlite3_extended_errcode(db)); + } + if (SQLITE_BUSY == ret || SQLITE_LOCKED == ret) { + DBG("BUSY or LOCKED(%d)", ret); + gettimeofday(&now, NULL); + timersub(&now, &from, &diff); + retry = (diff.tv_sec < PHND_SQLITE_RETRY_TIME) ? true : false; + if (retry) + usleep(PHND_SQLITE_RETRY_INTERVAL); + } else { + retry = false; + } + } while (retry); + + switch (ret) { + case SQLITE_ROW: + ret = PHND_SQLITE_ROW; + break; + case SQLITE_OK: + case SQLITE_DONE: + ret = PHONE_NUMBER_ERROR_NONE; + break; + default: + ERR("sqlite3_step() Fail(%d)", ret); + ret = PHONE_NUMBER_ERROR_DB_FAILED; + break; + } + + return ret; +} + +int phnd_sqlite_bind_text(phnd_stmt *stmt, int position, const char *text) +{ + RETV_IF(NULL == stmt, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == text, PHONE_NUMBER_ERROR_INVALID_PARAMETER); + + return sqlite3_bind_text(stmt, position, text, strlen(text), SQLITE_STATIC); +} + +void phnd_sqlite_finalize(phnd_stmt *stmt) +{ + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); +} + + diff --git a/daemon/phnd-sqlite.h b/daemon/phnd-sqlite.h new file mode 100644 index 0000000..e217594 --- /dev/null +++ b/daemon/phnd-sqlite.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __PHONENUMBER_UTILS_DAEMONSQLITE_H__ +#define __PHONENUMBER_UTILS_DAEMONSQLITE_H__ + +#include + +#define PHND_SQLITE_ROW 1 + +typedef sqlite3_stmt phnd_stmt; + +int phnd_sqlite_open_db(void); +void phnd_sqlite_close_db(void); +int phnd_sqlite_get_last_insert_id(void); +int phnd_sqlite_exec(const char *query); +int phnd_sqlite_prepare(const char *query, phnd_stmt **stmt); +int phnd_sqlite_step(phnd_stmt *stmt); +int phnd_sqlite_bind_text(phnd_stmt *stmt, int position, const char *text); +void phnd_sqlite_finalize(phnd_stmt *stmt); + +#endif /* __PHONENUMBER_UTILS_DAEMONSQLITE_H__ */ + diff --git a/daemon/phnd-utils.h b/daemon/phnd-utils.h index 71692b2..84617bb 100644 --- a/daemon/phnd-utils.h +++ b/daemon/phnd-utils.h @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef __PHONENUMBER_UTILS_DAEMON_UTIL_H__ -#define __PHONENUMBER_UTILS_DAEMON_UTIL_H__ +#ifndef __PHONENUMBER_UTILS_DAEMON_UTILS_H__ +#define __PHONENUMBER_UTILS_DAEMON_UTILS_H__ void phnd_utils_start_timeout(); void phnd_utils_stop_timeout(); -#endif /*__PHONENUMBER_UTILS_DAEMON_UTIL_H__*/ +#endif /*__PHONENUMBER_UTILS_DAEMON_UTILS_H__*/ diff --git a/daemon/phnd.c b/daemon/phnd.c index d9295b0..db8aa09 100644 --- a/daemon/phnd.c +++ b/daemon/phnd.c @@ -20,8 +20,11 @@ #include #include +#include "phone_number_errors.h" #include "phnd.h" #include "phnd-dbus.h" +#include "phnd-schema.h" +#include "phnd-sqlite.h" static GMainLoop *_main_loop; @@ -36,17 +39,27 @@ void phnd_daemon_quit() int main(int argc, char **argv) { + int ret = 0; guint id; INFO("start phonenumber utils daemon"); + phnd_schema_check(); _main_loop = g_main_loop_new(NULL, FALSE); + ret = phnd_sqlite_open_db(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phnd_sqlite_open_db() Fail(%d)", ret); + g_main_loop_unref(_main_loop); + return ret; + } + id = phnd_dbus_init(); g_main_loop_run(_main_loop); phnd_dbus_deinit(id); + phnd_sqlite_close_db(); g_main_loop_unref(_main_loop); return 0; diff --git a/include/phone_number.h b/include/phone_number.h index cc0425c..177a8d1 100644 --- a/include/phone_number.h +++ b/include/phone_number.h @@ -25,8 +25,11 @@ extern "C" { #endif +#include + #include #include +#include /** * @file phone_number.h @@ -38,7 +41,7 @@ extern "C" * @{ */ - + /** * @brief Connects to the phonenumber-utils service. * @since_tizen 3.0 @@ -141,6 +144,103 @@ int phone_number_get_formatted_number(const char *number, phone_number_region_e int phone_number_get_normalized_number(const char *number, char **normalized_number); +/** + * @brief Adds a blocking rule to the phone number database. + * + * @since_tizen 4.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/blocknumber.write + * + * @param[in] rule The blocking rule handle + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_DB_FAILED Database operation failure + * @retval #PHONE_NUMBER_ERROR_PERMISSION_DENIED Permission denied. This application does not have the privilege to call this method. + * @retval #PHONE_NUMBER_ERROR_IPC Unknown IPC error + * @retval #PHONE_NUMBER_ERROR_OUT_OF_MEMORY Out of memory + * + * @see phone_number_remove_blocking_rule() + */ +int phone_number_add_blocking_rule(phone_number_blocking_rule_h rule); + + +/** + * @brief Removes a blocking rule from the phone number database. + * + * @since_tizen 4.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/blocknumber.write + * + * @remarks The blocking rule to remove should have been gotten from the the phone number database using phone_number_get_blocking_rules(). + * + * @param[in] rule The blocking rule handle + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_DB_FAILED Database operation failure + * @retval #PHONE_NUMBER_ERROR_PERMISSION_DENIED Permission denied. This application does not have the privilege to call this method. + * @retval #PHONE_NUMBER_ERROR_IPC Unknown IPC error + * @retval #PHONE_NUMBER_ERROR_OUT_OF_MEMORY Out of memory + * + * @see phone_number_add_blocking_rule() + */ +int phone_number_remove_blocking_rule(phone_number_blocking_rule_h rule); + + +/** + * @brief Retrieves blocking rules as an array. + * + * @since_tizen 4.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/blocknumber.read + * + * @remarks You must release each blocking rule in the array with phone_number_blocking_rule_destroy() and @a rules using free(). + * + * @param[in] offset The index from which to get results + * @param[in] limit The number to limit results (value 0 is used for all blocking rules) + * @param[out] rules The array of blocking rule handle + * @param[out] length The number of blocking rule handle in the array + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_OUT_OF_MEMORY Out of memory + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_DB_FAILED Database operation failure + * @retval #PHONE_NUMBER_ERROR_PERMISSION_DENIED Permission denied. This application does not have the privilege to call this method. + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * @retval #PHONE_NUMBER_ERROR_IPC Unknown IPC error + * @retval #PHONE_NUMBER_ERROR_NO_DATA Data does not exist + */ +int phone_number_get_blocking_rules(int offset, int limit, phone_number_blocking_rule_h **rules, int *length); + +/** + * @brief Checks if a specific number is blocked or not. + * + * @since_tizen 4.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/blocknumber.read + * + * @param[in] number The number to check blocking + * @param[out] is_blocked The blocking result + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_DB_FAILED Database operation failure + * @retval #PHONE_NUMBER_ERROR_PERMISSION_DENIED Permission denied. This application does not have the privilege to call this method. + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * @retval #PHONE_NUMBER_ERROR_IPC Unknown IPC error + */ +int phone_number_check_blocking(const char *number, bool *is_blocked); + + /** * @} */ diff --git a/include/phone_number_blocking_rule.h b/include/phone_number_blocking_rule.h new file mode 100644 index 0000000..a541d9b --- /dev/null +++ b/include/phone_number_blocking_rule.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#ifndef __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_RULE_H__ +#define __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_RULE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file phone_number_blocking_rule.h + */ + +/** + * @addtogroup CAPI_TELEPHONY_PHONE_NUMBER_UTILS_RULE_MODULE + * + * @{ + */ + +/** + * @brief Creates a blocking rule. + * + * @since_tizen 4.0 + * + * @remarks You must release @a rule using phone_number_blocking_rule_destroy(). + * + * @param[out] rule The blocking rule handle + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_OUT_OF_MEMORY Out of memory + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @pre phone_number_connect() should be called to initialize. + * + * @see phone_number_blocking_rule_destroy() + */ +int phone_number_blocking_rule_create(phone_number_blocking_rule_h *rule); + + +/** + * @brief Destroys a blocking rule and releases all its resources. + * + * @since_tizen 4.0 + * + * @param[in] rule The blocking rule handle + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @see phone_number_blocking_rule_create() + */ +int phone_number_blocking_rule_destroy(phone_number_blocking_rule_h rule); + + +/** + * @brief Gets a blocked number from a rule. + * + * @since_tizen 4.0 + * + * @remarks You must release @a number using free(). + * + * @param[in] rule The blocking rule handle + * @param[out] number The blocked number + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @see phone_number_blocking_rule_set_number() + */ +int phone_number_blocking_rule_get_number(phone_number_blocking_rule_h rule, char **number); + + +/** + * @brief Gets a rule's match type. + * + * @since_tizen 4.0 + * + * @param[in] rule The blocking rule handle + * @param[out] match_type The match type of blocked number + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @see phone_number_blocking_rule_set_match_type() + */ +int phone_number_blocking_rule_get_match_type(phone_number_blocking_rule_h rule, phone_number_blocking_rule_match_type_e *match_type); + + +/** + * @brief Sets a blocked number to a rule. + * + * @since_tizen 4.0 + * + * @param[in] rule The blocking rule handle + * @param[in] number The blocked number + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @see phone_number_blocking_rule_get_number() + */ +int phone_number_blocking_rule_set_number(phone_number_blocking_rule_h rule, const char *number); + + +/** + * @brief Sets a rule's match type. + * + * @since_tizen 4.0 + * + * @param[in] rule The blocking rule handle + * @param[in] match_type The match type of blocked number + * + * @return @c 0 on success, + * otherwise a negative error value + * @retval #PHONE_NUMBER_ERROR_NONE Successful + * @retval #PHONE_NUMBER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PHONE_NUMBER_ERROR_NOT_PERMITTED Operation not permitted + * + * @see phone_number_blocking_rule_get_match_type() + */ +int phone_number_blocking_rule_set_match_type(phone_number_blocking_rule_h rule, phone_number_blocking_rule_match_type_e match_type); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_RULE_H__*/ + diff --git a/include/phone_number_errors.h b/include/phone_number_errors.h index ae2728b..a0155e1 100644 --- a/include/phone_number_errors.h +++ b/include/phone_number_errors.h @@ -22,6 +22,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @file phone_number_errors.h */ @@ -32,7 +36,7 @@ * @{ */ - + /** * @brief Enumeration for phone number errors. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -49,8 +53,9 @@ typedef enum { /* LOGIC & DATA */ PHONE_NUMBER_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< Requested data does not exist */ /* ENVIRONMENT & OTHER MODULE */ - PHONE_NUMBER_ERROR_SYSTEM = TIZEN_ERROR_PHONENUMBER_UTILS | 0xEF, /**< Internal error (Since 3.0) */ - + PHONE_NUMBER_ERROR_SYSTEM = TIZEN_ERROR_PHONENUMBER_UTILS | 0xEF, /**< Internal error (Since 3.0) */ + PHONE_NUMBER_ERROR_DB_FAILED = TIZEN_ERROR_PHONENUMBER_UTILS | 0x02, /**< No access to the database (Since 4.0) */ + PHONE_NUMBER_ERROR_IPC = TIZEN_ERROR_PHONENUMBER_UTILS | 0xBF, /**< Unknown IPC error (Since 4.0) */ } phone_number_error_e; @@ -58,4 +63,8 @@ typedef enum { * @} */ +#ifdef __cplusplus +} +#endif + #endif /* __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_ERRORS_H__ */ diff --git a/include/phone_number_types.h b/include/phone_number_types.h index ce0dadc..ad3293e 100644 --- a/include/phone_number_types.h +++ b/include/phone_number_types.h @@ -20,6 +20,9 @@ #ifndef __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_TYPES_H__ #define __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_TYPES_H__ +#ifdef __cplusplus +extern "C" { +#endif /** * @file phone_number_types.h @@ -31,7 +34,7 @@ * @{ */ - + /** * @brief Enumeration for language type. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -325,9 +328,31 @@ typedef enum { PHONE_NUMBER_REGION_MAX, } phone_number_region_e; +/** + * @brief Enumeration for match type. + * @since_tizen 4.0 + */ +typedef enum { + PHONE_NUMBER_MATCH_TYPE_EXACTLY, /**< Exact match */ + PHONE_NUMBER_MATCH_TYPE_INCLUDES, /**< Includes */ + PHONE_NUMBER_MATCH_TYPE_STARTS_WITH, /**< Starts with */ + PHONE_NUMBER_MATCH_TYPE_ENDS_WITH, /**< Ends with */ +} phone_number_blocking_rule_match_type_e; + +/** + * @brief The blocking rule handle. + * @since_tizen 4.0 + */ +typedef void *phone_number_blocking_rule_h; + /** * @} */ +#ifdef __cplusplus +} +#endif + #endif /* __TIZEN_TELEPHONY_PHONE_NUMBER_UTILS_TYPES_H__ */ + diff --git a/packaging/phonenumber-utils.conf.in b/packaging/phonenumber-utils.conf.in new file mode 100644 index 0000000..d942484 --- /dev/null +++ b/packaging/phonenumber-utils.conf.in @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/phonenumber-utils.spec b/packaging/phonenumber-utils.spec index 0d4333e..59b6e17 100644 --- a/packaging/phonenumber-utils.spec +++ b/packaging/phonenumber-utils.spec @@ -8,6 +8,7 @@ Source0: %{name}-%{version}.tar.gz Source1: %{name}.service Source1001: %{name}.manifest Source1002: %{name}-test.manifest +Source2001: %{name}.conf.in BuildRequires: cmake BuildRequires: gettext-devel BuildRequires: pkgconfig(glib-2.0) @@ -19,8 +20,11 @@ BuildRequires: pkgconfig(capi-system-system-settings) BuildRequires: pkgconfig(tapi) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(db-util) BuildRequires: security-config BuildRequires: libphonenumber-devel +BuildRequires: pkgconfig(libsystemd) %define _unitdir /usr/lib/systemd/system %define _dbus_name org.tizen.PhonenumberUtils.dbus @@ -54,7 +58,10 @@ cp %{SOURCE1002} . %build MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -%cmake . -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DBIN_INSTALL_DIR:PATH=%{_bindir} +%cmake . -DMAJORVER=${MAJORVER} \ + -DFULLVER=%{version} \ + -DBIN_INSTALL_DIR:PATH=%{_bindir} \ + -DPHND_SYS_DB=%{TZ_SYS_GLOBALUSER_DB} %install @@ -67,6 +74,9 @@ cp -f 500.%{name}.sh %{buildroot}%{upgrade_script_path} mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants install -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/%{name}.service +mkdir -p %{buildroot}/%{_sysconfdir}/dbus-1/session.d +sed -i 's/@DBUS_INTERFACE@/%{_dbus_name}/g' %SOURCE2001 +install -m 0644 %SOURCE2001 %{buildroot}%{_sysconfdir}/dbus-1/session.d/%{name}.conf %post /sbin/ldconfig @@ -94,6 +104,7 @@ systemctl daemon-reload %{_libdir}/lib%{name}.so.* %license LICENSE.APLv2 %{upgrade_script_path}/500.%{name}.sh +%config %{_sysconfdir}/dbus-1/session.d/%{name}.conf %files devel diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 870915a..8c8ef66 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,3 @@ -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) @@ -17,4 +16,4 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--hash-style=both -pie") ADD_EXECUTABLE(${TEST_TARGET} ${TEST_SRCS}) ADD_DEPENDENCIES(${TEST_TARGET} GENERATED_DBUS_CODE) TARGET_LINK_LIBRARIES(${TEST_TARGET} ${test_pkgs_LIBRARIES} ${CLIENT}) -INSTALL(TARGETS ${TEST_TARGET} DESTINATION bin) \ No newline at end of file +INSTALL(TARGETS ${TEST_TARGET} DESTINATION bin) diff --git a/test/phn-test.c b/test/phn-test.c deleted file mode 100644 index a6b4216..0000000 --- a/test/phn-test.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Phonenumber Utils - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include -#include - -#include -#include "phn-log.h" - -int main(int argc, char **argv) -{ - int ret; - int count = 0; - char test_number[11] = {0}; - char *location = NULL; - char *formatted_number = NULL; - char *normalized_number = NULL; - int lang = PHONE_NUMBER_LANG_KOREAN; - int region = PHONE_NUMBER_REGION_REPUBLIC_OF_KOREA; - - DBG("start test main !!!"); - - ret = phone_number_connect(); - if (PHONE_NUMBER_ERROR_NONE != ret) { - ERR("phone_number_connect() Fail(%d)", ret); - return 0; - } - - while (1) { - if (5 < count) { - count = 0; - break; - } - - /* test number start from 0212340000 to 0212340005*/ - snprintf(test_number, sizeof(test_number), "021234%04d", count); - DBG("========== start test with number[%s], region[%d], lang[%d] =====", test_number, region, lang); - - DBG("=========== Call get location ======================="); - ret = phone_number_get_location_from_number(test_number, region, lang, &location); - if (PHONE_NUMBER_ERROR_NONE != ret) { - ERR("phone_number_get_location_from_number() Fail(%d)", ret); - phone_number_disconnect(); - return -1; - } - - /* location - 'seoul' */ - DBG("location = %s", location); - free(location); - location = NULL; - - - DBG("=========== Call get formatted number ======================="); - ret = phone_number_get_formatted_number(test_number, region, &formatted_number); - if (PHONE_NUMBER_ERROR_NONE != ret) { - ERR("phone_number_get_formatted_number() Fail(%d)", ret); - phone_number_disconnect(); - return -1; - } - - /* formatted_number - '02-1234-0001' */ - DBG("formatted_number = %s", formatted_number); - free(formatted_number); - formatted_number = NULL; - - DBG("=========== Call get normalized number ======================="); - ret = phone_number_get_normalized_number(test_number, &normalized_number); - if (PHONE_NUMBER_ERROR_NONE != ret) { - ERR("phone_number_get_normalized_number() Fail(%d)", ret); - phone_number_disconnect(); - return -1; - } - - /* normalized_number - '+82212340001' */ - DBG("normalized_number = %s", normalized_number); - free(normalized_number); - normalized_number = NULL; - - count++; - } - phone_number_disconnect(); - - DBG("end test main !!!"); - return 0; -} - diff --git a/test/phnt-log.h b/test/phnt-log.h new file mode 100644 index 0000000..09a5dd2 --- /dev/null +++ b/test/phnt-log.h @@ -0,0 +1,94 @@ +/* + * Phonenumber Utils + * + * Copyright (c) 2015 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 __PHNT_LOG_H__ +#define __PHNT_LOG_H__ + +#define PHN_LOG_RED "\033[0;31m" +#define PHN_LOG_GREEN "\033[0;32m" +#define PHN_LOG_BROWN "\033[0;33m" +#define PHN_LOG_BLUE "\033[0;34m" +#define PHN_LOG_END "\033[0;m" + +#define LOG_TAG "PHONENUMBER_UTILS_TEST" +#include + +#define _DBG(fmt, arg...) SLOGD(fmt, ##arg) +#define _INFO(fmt, arg...) SLOGI(fmt, ##arg) +#define _WARN(fmt, arg...) SLOGW(fmt, ##arg) +#define _ERR(fmt, arg...) SLOGE(fmt, ##arg) + +#define FN_CALL _INFO(">>>>>>>> called") +#define FN_END _INFO("<<<<<<<< ended") +#define DBG(fmt, arg...) _DBG(fmt, ##arg) +#define WARN(fmt, arg...) _WARN(PHN_LOG_BROWN fmt PHN_LOG_END, ##arg) +#define ERR(fmt, arg...) _ERR(PHN_LOG_RED fmt PHN_LOG_END, ##arg) +#define INFO(fmt, arg...) _INFO(PHN_LOG_BLUE fmt PHN_LOG_END, ##arg) +#define SECURE_DBG(fmt, arg...) SECURE_SLOGD(fmt, ##arg) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) + + +#define RET_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + return; \ + } \ + } while (0) + +#define RETV_IF(expr, val) \ + do {\ + if (expr) { \ + ERR("(%s)", #expr); \ + return (val); \ + } \ + } while (0) + +#define RETM_IF(expr, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + } \ + } while (0) + +#define RETVM_IF(expr, val, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while (0) + +#define ERR_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + } \ + } while (0) + +#define WARN_IF(expr, fmt, arg...) \ + do { \ + if (expr) { \ + WARN(fmt, ##arg); \ + } \ + } while (0) + +#endif /* __PHNT_LOG_H__ */ + diff --git a/test/phnt.c b/test/phnt.c new file mode 100644 index 0000000..f52bb09 --- /dev/null +++ b/test/phnt.c @@ -0,0 +1,278 @@ +/* + * Phonenumber Utils + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include + +#include "phone_number.h" +#include "phnt-log.h" + +typedef int (*func)(int argc, char **argv); + +static int phnt_get_location_from_number(char *test_number, int region, int lang) +{ + DBG("%s", __func__); + DBG("number[%s], region[%d], lang[%d]", test_number, region, lang); + + int ret = 0; + char *location = NULL; + ret = phone_number_get_location_from_number(test_number, region, lang, &location); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_location_from_number() Fail(%d)", ret); + return -1; + } + + /* location - 'seoul' */ + DBG("location = %s", location); + free(location); + return 0; +} + +static int phnt_get_formatted_number(char *test_number, int region) +{ + DBG("%s", __func__); + DBG("number[%s], region[%d]", test_number, region); + + int ret = 0; + char *formatted_number = NULL; + ret = phone_number_get_formatted_number(test_number, region, &formatted_number); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_formatted_number() Fail(%d)", ret); + return -1; + } + + /* formatted_number - '02-1234-0001' */ + DBG("formatted_number = %s", formatted_number); + free(formatted_number); + return 0; +} + +static int phnt_get_normalized_number(char *test_number) +{ + DBG("%s", __func__); + DBG("number[%s]", test_number); + + int ret = 0; + char *normalized_number = NULL; + ret = phone_number_get_normalized_number(test_number, &normalized_number); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_normalized_number() Fail(%d)", ret); + return -1; + } + + /* normalized_number - '+82212340001' */ + DBG("normalized_number = %s", normalized_number); + free(normalized_number); + return 0; +} + +#define TEST_LOOP_COUNT 5 +static int phnt_get_location_formatted_normalized_number(int argc, char **argv) +{ + int i; + int ret = 0; + char test_number[32] = {0}; + + for (i = 0; i < TEST_LOOP_COUNT; i++) { + /* test number start from 0212340000 to 0212340005*/ + snprintf(test_number, sizeof(test_number), "021234%04d", i); + + ret = phnt_get_location_from_number(test_number, + PHONE_NUMBER_REGION_REPUBLIC_OF_KOREA, PHONE_NUMBER_LANG_KOREAN); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_location_from_number() Fail(%d)", ret); + break; + } + + ret = phnt_get_formatted_number(test_number, PHONE_NUMBER_REGION_REPUBLIC_OF_KOREA); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_formatted_number() Fail(%d)", ret); + return -1; + } + + ret = phnt_get_normalized_number(test_number); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_normalized_number() Fail(%d)", ret); + return -1; + } + } + return 0; +} + +static int phnt_add_block(char *test_number, int match_type) +{ + int ret = 0; + phone_number_blocking_rule_h rule = NULL; + phone_number_blocking_rule_create(&rule); + phone_number_blocking_rule_set_match_type(rule, match_type); + phone_number_blocking_rule_set_number(rule, test_number); + + ret = phone_number_add_blocking_rule(rule); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_add_blocking_rule() Fail(%d)", ret); + return ret; + } + phone_number_blocking_rule_destroy(rule); + + return 0; +} + +static int phnt_get_blocknumbers(phone_number_blocking_rule_h **rules, int *length) +{ + int ret = 0; + + ret = phone_number_get_blocking_rules(0, 0, rules, length); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_get_blocking_rules() Fail(%d)", ret); + return ret; + } + + DBG("length(%d)", *length); + + int i; + for (i = 0; i < *length; i++) { + phone_number_blocking_rule_match_type_e match_type; + char *number; + phone_number_blocking_rule_get_match_type((*rules)[i], &match_type); + phone_number_blocking_rule_get_number((*rules)[i], &number); + DBG("match_type(%d) number(%s)", match_type, number); + free(number); + } + + return 0; +} + +static int phnt_add_get_remove_block(int argc, char **argv) +{ + char *test_number = "07015881922"; + phnt_add_block(test_number, PHONE_NUMBER_MATCH_TYPE_EXACTLY); + + phone_number_blocking_rule_h *rules = NULL; + int length = 0; + phnt_get_blocknumbers(&rules, &length); + phone_number_remove_blocking_rule(rules[0]); + int i = 0; + for (i = 0; i < length; i++) + phone_number_blocking_rule_destroy(rules[i]); + + free(rules); + rules = NULL; + + phnt_get_blocknumbers(&rules, &length); + for (i = 0; i < length; i++) + phone_number_blocking_rule_destroy(rules[i]); + + free(rules); + rules = NULL; + return 0; +} + +#define TEST_BLOCK_NUMBER 8 +#define TEST_BLOCK_COUNT 35 +static int phnt_add_check_block(int argc, char **argv) +{ + struct block_number { + char *number; + int match_type; + }; + struct block_number bn[TEST_BLOCK_NUMBER] = { + {"+821092381673", PHONE_NUMBER_MATCH_TYPE_EXACTLY}, + {"010-1234-1234", PHONE_NUMBER_MATCH_TYPE_EXACTLY}, + {"01028850863", PHONE_NUMBER_MATCH_TYPE_EXACTLY}, + {"07015001500", PHONE_NUMBER_MATCH_TYPE_EXACTLY}, + {"070", PHONE_NUMBER_MATCH_TYPE_STARTS_WITH}, + {"1588", PHONE_NUMBER_MATCH_TYPE_STARTS_WITH}, + {"0909", PHONE_NUMBER_MATCH_TYPE_ENDS_WITH}, + {"070", PHONE_NUMBER_MATCH_TYPE_INCLUDES}, + }; + + int i; + for (i = 0; i < TEST_BLOCK_NUMBER; i++) + phnt_add_block(bn[i].number, bn[i].match_type); + + bool is_blocked; + const char *test_number[TEST_BLOCK_COUNT] = { + "01092381673", "+821092381673", "010-9238-1673", "+82-010-9238-1673", "01092381674", + "01012341234", "+821012341234", "010-1234-1234", "+82-010-1234-1234", "01012341111", + "01028850863", "01038850863", "07015001500", "07015001505", "07055001500", + "07015881500", "+827011102270", "070-1211-1111", "+82-070-1111-2222", "0771234124", + "15881234", "1588-4321", "01015881234", "+8215881234", "010-1234-1588", + "01022900909", "010-2222-0909", "+82-010-1111-0909", "+821011110909", "010-1212-9090", + "01007001111", "01070121234", "010-1234-0700", "01071001234", "01007101234"}; + + for (i = 0; i < TEST_BLOCK_COUNT; i++) { + is_blocked = false; + phone_number_check_blocking(test_number[i], &is_blocked); + DBG("[%s] with number[%s]", + is_blocked == true ? "This is BLOCKED" : "This is NOT blocked", + test_number[i]); + } + + phone_number_blocking_rule_h *rules = NULL; + int length = 0; + phnt_get_blocknumbers(&rules, &length); + for (i = 0; i < length; i++) { + phone_number_remove_blocking_rule(rules[i]); + phone_number_blocking_rule_destroy(rules[i]); + } + + free(rules); + rules = NULL; + + + return 0; +} + +static const func _func[] = { + phnt_get_location_formatted_normalized_number, + phnt_add_get_remove_block, + phnt_add_check_block, +}; + +/* /opt/usr/phonenumber-utils-test 1 + */ +int main(int argc, char **argv) +{ + int ret = 0; + + ret = phone_number_connect(); + if (PHONE_NUMBER_ERROR_NONE != ret) { + ERR("phone_number_connect() Fail(%d)", ret); + return 0; + } + + if (1 < argc) { + int select = atoi(argv[1]); + if (select < sizeof(_func)/sizeof(func)) + _func[select](argc, argv); + return 0; + } + + int i = 0; + int count = sizeof(_func) / sizeof(func); + for (i = 0; i < count; i++) { + if (_func[i](argc, argv) < 0) + break; + } + return 0; + + phone_number_disconnect(); + + DBG("end test main !!!"); + return 0; +}