Add number blocking feature. 42/97342/39
authorJeesun Kim <iamjs.kim@samsung.com>
Mon, 14 Nov 2016 02:24:32 +0000 (11:24 +0900)
committerJongkyu Koo <jk.koo@samsung.com>
Mon, 10 Jul 2017 08:01:30 +0000 (17:01 +0900)
Change-Id: Ib8f725c51a3c60fba06cd970b15e671eec290e29

46 files changed:
CMakeLists.txt
build-util/DB-schema-gen.c [new file with mode: 0644]
build-util/Makefile [new file with mode: 0644]
build-util/generator.sh [new file with mode: 0755]
build-util/schema.sql [new file with mode: 0644]
client/CMakeLists.txt
client/phnc-blocking_rule.c [new file with mode: 0644]
client/phnc-dbus.c [new file with mode: 0644]
client/phnc-dbus.h [new file with mode: 0644]
client/phnc.c
client/phnc.h
common/phn-common.h
common/phn-dbus-utils.c [new file with mode: 0644]
common/phn-dbus-utils.h [new file with mode: 0644]
common/phn-dbus.xml
common/phn-log.h
common/phn-property.h [new file with mode: 0644]
common/phn-record.c [new file with mode: 0644]
common/phn-record.h [new file with mode: 0644]
common/phn-utils.h [new file with mode: 0644]
daemon/CMakeLists.txt
daemon/phnd-blocking_rule.c [new file with mode: 0644]
daemon/phnd-blocking_rule.h [new file with mode: 0644]
daemon/phnd-db-utils.c [new file with mode: 0644]
daemon/phnd-db-utils.h [new file with mode: 0644]
daemon/phnd-dbus.c
daemon/phnd-dbus.h
daemon/phnd-libphonenumber.cpp
daemon/phnd-libphonenumber.h
daemon/phnd-region-data.c
daemon/phnd-schema.c [new file with mode: 0644]
daemon/phnd-schema.h [new file with mode: 0644]
daemon/phnd-sqlite.c [new file with mode: 0644]
daemon/phnd-sqlite.h [new file with mode: 0644]
daemon/phnd-utils.h
daemon/phnd.c
include/phone_number.h
include/phone_number_blocking_rule.h [new file with mode: 0644]
include/phone_number_errors.h
include/phone_number_types.h
packaging/phonenumber-utils.conf.in [new file with mode: 0644]
packaging/phonenumber-utils.spec
test/CMakeLists.txt
test/phn-test.c [deleted file]
test/phnt-log.h [new file with mode: 0644]
test/phnt.c [new file with mode: 0644]

index 8b3513c318198c96250f03c64883f43690f0bd61..33d60f959c78fdff2dccc2d9826481f7a908dd98 100644 (file)
@@ -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 (file)
index 0000000..d609485
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+
+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 (file)
index 0000000..125a31e
--- /dev/null
@@ -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 (executable)
index 0000000..517d47e
--- /dev/null
@@ -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 (file)
index 0000000..dd73a09
--- /dev/null
@@ -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
+);
+
index dea8482440849c4795edcf809efe261e1ee8b91b..60b87c93c1a067cb103efd67643f1c6f6515f38a 100644 (file)
@@ -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 (file)
index 0000000..a43f8b9
--- /dev/null
@@ -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 <unistd.h>
+
+#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 (file)
index 0000000..7bc707d
--- /dev/null
@@ -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 <stdlib.h>
+
+#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 (file)
index 0000000..55362c0
--- /dev/null
@@ -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__*/
+
index 74a0c3f6ab2b62983f9dbb59ffbc0c3f720ef79a..42a18ccb2c7d506eb16a200111fafdf0dc423f23 100644 (file)
  */
 
 #include <stdio.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <glib-object.h>
-#include <gio/gio.h>
 #include <system_info.h>
+#include <unistd.h>
+#include <systemd/sd-login.h>
 
 #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"
 #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);
+}
+
+
index 0aed10adaafe033ea64730d5ceaa4f96374b4a45..fab230e21a30e541c113a89d71203f82bd17a16e 100644 (file)
@@ -24,5 +24,7 @@
 #endif
 #define API __attribute__((visibility("default")))
 
+int phnc_get_uid(void);
+
 #endif /*__PHONENUMBER_UTILS_CLIENT_H__*/
 
index 435aa60bc33da0fa186f3eebceb5510fcfbb3297..be4c8ffc955aa68ef01cf918f868a19a270a96cb 100644 (file)
  * 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 (file)
index 0000000..b975b59
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#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 (file)
index 0000000..dc08615
--- /dev/null
@@ -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__ */
+
index 2b1e983af3703d102bd84d5cead99b9988abacd0..ad5075c4d88ada2fe6abdd2198d2702e3a420584 100644 (file)
                        <arg type="s" name="normalized_number" direction="out"/>
                        <arg type="i" name="ret" direction="out"/>
                </method>
+               <method name="add_blocking_rule">
+                       <arg type="(iiiss)" name="rule" direction="in"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
+               <method name="remove_blocking_rule">
+                       <arg type="i" name="id" direction="in"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
+               <method name="check_blocking">
+                       <arg type="i" name="user_id" direction="in"/>
+                       <arg type="s" name="number" direction="in"/>
+                       <arg type="i" name="is_blcoked" direction="out"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
+               <method name="get_blocking_rules">
+                       <arg type="i" name="user_id" direction="in"/>
+                       <arg type="i" name="offset" direction="in"/>
+                       <arg type="i" name="limit" direction="in"/>
+                       <arg type="av" name="rules" direction="out"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
        </interface>
 </node>
 
index 72f16a529ffdfa0fd585777355509cdb751b19e7..7a30c61bda7a2ddbbc9e024cca6428dce4e521f5 100644 (file)
@@ -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"
                } \
        } 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 (file)
index 0000000..3e18591
--- /dev/null
@@ -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 (file)
index 0000000..bdccf38
--- /dev/null
@@ -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 (file)
index 0000000..90a6997
--- /dev/null
@@ -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 <glib.h>
+
+#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 (file)
index 0000000..27471e1
--- /dev/null
@@ -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 <stdlib.h>
+
+#define PHN_FREE(x) do {\
+       free(x); \
+       x = NULL; \
+} while (0)
+
+#define PHN_STRDUP(x) (x) ? strdup(x) : NULL;
+
+#endif /* __PHN_UTILS_H__ */
+
index 41ea3f988b37c969c84873ef374f4f9511817f1c..fea2f3ceee589a7e319df76faab540d4c8596ca5 100644 (file)
@@ -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 (file)
index 0000000..49c6cc4
--- /dev/null
@@ -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 <stdio.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..736afbd
--- /dev/null
@@ -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 <glib.h>
+
+#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 (file)
index 0000000..042dc7e
--- /dev/null
@@ -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 <unistd.h>
+
+#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 (file)
index 0000000..ab069e8
--- /dev/null
@@ -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__*/
+
index eca948bec4ea232f3ced73c96ae602fa4a28929d..20293013287c8902623985d4eea8205050dfeb58 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <stdlib.h>
 #include <gio/gio.h>
+#include <glib.h>
 
-#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);
 }
+
index 9e51a77f0f355667aded7d16e3f8c6d576fb1528..9abb6d9f32c917a436a6e48dd5aa6e85d0715f6c 100644 (file)
  * 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__*/
 
index 47d6523e69702eb1b7c6819783c16aeca88af6c8..9331d29718748a011f87696da1efec97cbf69870 100644 (file)
@@ -25,6 +25,7 @@
 #include <phonenumbers/asyoutypeformatter.h>
 #include <phonenumbers/geocoding/phonenumber_offline_geocoder.h>
 
+#include "phone_number_errors.h"
 #include "phnd.h"
 #include "phnd-libphonenumber.h"
 
index bfbb2b95f2152a0984160ec1201fa71e08ab1735..1f2c44b3c95838de5c8e546d49a3fa0bfa774110 100644 (file)
@@ -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__ */
index aa0779c0a0ca63ffb4777d768beeae3e7e5f5285..5d0262d27086d066730d7732cae5cacd56a5926d 100644 (file)
@@ -20,6 +20,7 @@
 #include <glib.h>
 #include <system_settings.h>
 
+#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 (file)
index 0000000..8b802ba
--- /dev/null
@@ -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 <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <sqlite3.h>
+#include <db-util.h>
+
+#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 (file)
index 0000000..80e4abf
--- /dev/null
@@ -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 <tzplatform_config.h>
+
+#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 (file)
index 0000000..13c6249
--- /dev/null
@@ -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 <sys/time.h>
+#include <unistd.h>
+#include <db-util.h>
+
+#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 (file)
index 0000000..e217594
--- /dev/null
@@ -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 <sqlite3.h>
+
+#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__ */
+
index 71692b28134ee31cf9ebe23eaa2577e81473d98e..84617bbbf2ae7efbfa12f7c74ecc7543e6967231 100644 (file)
  * 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__*/
 
index d9295b05f52049a9c8791c3fe3128379b6a6ea6a..db8aa099eb795411e91378d82984a8d03934f53b 100644 (file)
 #include <pthread.h>
 #include <glib.h>
 
+#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;
index cc0425c9fc8e47fad8f84e0107aa25fc0fa70c4a..177a8d1cc1615de1328e035155d62726a231b27a 100644 (file)
@@ -25,8 +25,11 @@ extern "C"
 {
 #endif
 
+#include <tizen.h>
+
 #include <phone_number_types.h>
 #include <phone_number_errors.h>
+#include <phone_number_blocking_rule.h>
 
 /**
  * @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 (file)
index 0000000..a541d9b
--- /dev/null
@@ -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 <phone_number_types.h>
+
+#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__*/
+
index ae2728bcfa4a5785462bc1cba9704b113f7501cb..a0155e14fdd59079b92d89e6cbb994f9eac911e8 100644 (file)
 
 #include <tizen.h>
 
+#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__ */
index ce0dadcf346ca0229e2a0ef3c3986e44e5934156..ad3293e7d34efa1abe3c5b796c8955cf71a5b049 100644 (file)
@@ -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 (file)
index 0000000..d942484
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+    <policy user="root">
+        <allow own="@DBUS_INTERFACE@"/>
+               <allow send_destination="@DBUS_INTERFACE@" send_interface="@DBUS_INTERFACE@"/>
+               <allow receive_sender="@DBUS_INTERFACE@"/>
+    </policy>
+    <policy user="system">
+        <allow own="@DBUS_INTERFACE@"/>
+               <allow send_destination="@DBUS_INTERFACE@" send_interface="@DBUS_INTERFACE@"/>
+               <allow receive_sender="@DBUS_INTERFACE@"/>
+    </policy>
+    <policy context="default">
+        <allow send_destination="@DBUS_INTERFACE@"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="add_block_number"
+                               privilege="http://tizen.org/privilege/phonenumber_utils.write"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="remove_block_number"
+                               privilege="http://tizen.org/privilege/phonenumber_utils.write"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="check_block_number"
+                               privilege="http://tizen.org/privilege/phonenumber_utils.read"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="get_block_numbers"
+                               privilege="http://tizen.org/privilege/phonenumber_utils.read"/>
+    </policy>
+</busconfig>
+
index 0d4333e936816a6eae319c6f7545eaa6424c881f..59b6e17f25be085270caffb7b52de624263ab7b5 100644 (file)
@@ -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
index 870915a16d104277b03ca1232af1d6b78f030549..8c8ef66f50ecbfa403b495441c2f776630b15ded 100644 (file)
@@ -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 (file)
index a6b4216..0000000
+++ /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 <stdio.h>
-#include <stdlib.h>
-
-#include <phone_number.h>
-#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 (file)
index 0000000..09a5dd2
--- /dev/null
@@ -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 <dlog.h>
+
+#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 (file)
index 0000000..f52bb09
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+
+#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;
+}