4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 * @desc Implementation of the network restriction
26 #include <resourced.h>
27 #include <data_usage.h>
28 #include <rd-network.h>
30 #include "cgroup.h" /*get_classid_by_pkg_name */
33 #include "datausage-restriction.h"
34 #include "edbus-handler.h"
36 #include "netlink-restriction.h"
37 #include "restriction-helper.h"
38 #include "tethering-restriction.h"
41 #define SELECT_RESTRICTIONS "SELECT binpath, rcv_limit, " \
42 "send_limit, iftype, rst_state, quota_id, roaming FROM restrictions"
44 #define SELECT_RESTRICTION_STATE "SELECT rst_state FROM restrictions " \
45 "WHERE binpath = ? AND iftype = ?"
47 static sqlite3_stmt *datausage_restriction_select;
48 static sqlite3_stmt *restriction_get_state_stmt;
50 static int init_datausage_restriction(sqlite3 *db)
53 if (datausage_restriction_select)
56 rc = sqlite3_prepare_v2(db, SELECT_RESTRICTIONS, -1 ,
57 &datausage_restriction_select, NULL);
58 if (rc != SQLITE_OK) {
59 _E("can not prepare datausage_restriction_select\n");
60 datausage_restriction_select = NULL;
66 static void serialize_restriction(const char *appid,
67 const enum traffic_restriction_type rst_type,
68 const resourced_net_restrictions *rst,
71 params[0] = (char *)appid;
72 params[1] = (char *)rst_type;
73 params[2] = (char *)rst->rs_type;
74 params[3] = (char *)rst->iftype;
75 params[4] = (char *)rst->send_limit;
76 params[5] = (char *)rst->rcv_limit;
77 params[6] = (char *)rst->snd_warning_limit;
78 params[7] = (char *)rst->rcv_warning_limit;
79 params[8] = (char *)rst->roaming;
82 static resourced_ret_c process_restriction(
83 const char *app_id, const resourced_net_restrictions *rst,
84 const enum traffic_restriction_type rst_type)
90 resourced_ret_c ret_val;
92 ret = check_restriction_arguments(app_id, rst, rst_type);
93 ret_value_msg_if(ret != RESOURCED_ERROR_NONE,
94 RESOURCED_ERROR_INVALID_PARAMETER,
95 "Invalid restriction arguments\n");
97 serialize_restriction(app_id, rst_type, rst, params);
100 msg = dbus_method_sync(BUS_NAME, RESOURCED_PATH_NETWORK,
101 RESOURCED_INTERFACE_NETWORK,
102 RESOURCED_NETWORK_PROCESS_RESTRICTION,
103 "sdddddddd", params);
106 _E("Re-try to sync DBUS message, err_count : %d", i);
107 } while (i++ < RETRY_MAX);
110 _E("Failed to sync DBUS message.");
111 return RESOURCED_ERROR_FAIL;
114 dbus_error_init(&err);
116 ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val,
120 _E("no message : [%s:%s]\n", err.name, err.message);
121 ret_val = RESOURCED_ERROR_FAIL;
124 dbus_message_unref(msg);
125 dbus_error_free(&err);
130 API resourced_ret_c restrictions_foreach(
131 resourced_restriction_cb restriction_cb, void *user_data)
133 resourced_restriction_info data;
135 resourced_ret_c error_code = NETWORK_ERROR_NONE;
137 libresourced_db_initialize_once();
138 if (init_datausage_restriction(resourced_get_database()) != SQLITE_OK) {
139 _D("Failed to initialize data usage restriction statement: %s\n",
140 sqlite3_errmsg(resourced_get_database()));
141 return RESOURCED_ERROR_DB_FAILED;
145 rc = sqlite3_step(datausage_restriction_select);
150 data.app_id = (char *)sqlite3_column_text(
151 datausage_restriction_select, 0);
152 data.iftype = (resourced_iface_type)sqlite3_column_int(
153 datausage_restriction_select, 3);
154 data.rcv_limit = sqlite3_column_int(
155 datausage_restriction_select, 1);
156 data.send_limit = sqlite3_column_int(
157 datausage_restriction_select, 2);
159 (resourced_restriction_state)sqlite3_column_int(
160 datausage_restriction_select, 4);
161 data.quota_id = sqlite3_column_int(
162 datausage_restriction_select, 5);
163 data.roaming = sqlite3_column_int(
164 datausage_restriction_select, 6);
166 if (restriction_cb(&data, user_data) == RESOURCED_CANCEL)
171 _E("Failed to enumerate restrictions: %s\n",
172 sqlite3_errmsg(resourced_get_database()));
174 error_code = RESOURCED_ERROR_DB_FAILED;
176 } while (rc == SQLITE_ROW);
178 sqlite3_reset(datausage_restriction_select);
182 API resourced_ret_c set_net_restriction(const char *app_id,
183 const resourced_net_restrictions *rst)
185 return process_restriction(app_id, rst, RST_SET);
188 API resourced_ret_c remove_restriction(const char *app_id)
190 return remove_restriction_by_iftype(app_id, RESOURCED_IFACE_ALL);
193 API resourced_ret_c remove_restriction_by_iftype(
194 const char *app_id, const resourced_iface_type iftype)
196 resourced_net_restrictions rst = { 0 };
199 return process_restriction(app_id, &rst, RST_UNSET);
202 API resourced_ret_c exclude_restriction(const char *app_id)
204 return exclude_restriction_by_iftype(app_id, RESOURCED_IFACE_ALL);
207 API resourced_ret_c exclude_restriction_by_iftype(
208 const char *app_id, const resourced_iface_type iftype)
210 resourced_net_restrictions rst = { 0 };
213 return process_restriction(app_id, &rst, RST_EXCLUDE);
216 API resourced_ret_c set_net_exclusion(const char *app_id,
217 const resourced_net_restrictions *rst)
219 return process_restriction(app_id, rst, RST_EXCLUDE);
222 void finalize_datausage_restriction(void)
224 if (datausage_restriction_select) {
225 sqlite3_finalize(datausage_restriction_select);
226 datausage_restriction_select = NULL;
230 static int init_get_rst_statement(sqlite3* db)
234 rc = sqlite3_prepare_v2(db, SELECT_RESTRICTION_STATE, -1 ,
235 &restriction_get_state_stmt, NULL);
236 if (rc != SQLITE_OK) {
237 _E("can not prepare restriction_get_state: %d\n", rc);
238 restriction_get_state_stmt = NULL;
239 return NETWORK_ERROR_DB_FAILED;
244 API resourced_ret_c get_restriction_state(const char *pkg_id,
245 resourced_iface_type iftype, resourced_restriction_state *state)
248 int error_code = RESOURCED_ERROR_NONE;
252 _E("Please provide valid argument!");
253 return RESOURCED_ERROR_INVALID_PARAMETER;
256 db = resourced_get_database();
259 _E("Can't get database.");
260 return RESOURCED_ERROR_DB_FAILED;
264 error_code = init_get_rst_statement(db);
265 if (error_code != RESOURCED_ERROR_NONE)
269 *state = RESOURCED_RESTRICTION_UNKNOWN;
270 sqlite3_reset(restriction_get_state_stmt);
271 DB_ACTION(sqlite3_bind_text(restriction_get_state_stmt, 1, pkg_id, -1,
273 DB_ACTION(sqlite3_bind_int(restriction_get_state_stmt, 2, iftype));
275 error_code = sqlite3_step(restriction_get_state_stmt);
276 switch (error_code) {
280 *state = (network_restriction_state)sqlite3_column_int(
281 restriction_get_state_stmt, 0);
285 _E("Can't perform sql query: %s \n%s",
286 SELECT_RESTRICTION_STATE, sqlite3_errmsg(db));
287 error_code = RESOURCED_ERROR_DB_FAILED;
292 sqlite3_reset(restriction_get_state_stmt);