4 * Copyright (c) 2014 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.
21 * @file restriction-handler.c
23 * @desc Callback for working reset restrictions
25 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
29 #include <data_usage.h>
36 #include "net-cls-cgroup.h"
38 #include "restriction-helper.h"
39 #include "datausage-restriction.h"
40 #include "restriction-handler.h"
42 struct restriction_context {
44 list_restrictions_info *restrictions;
47 static gpointer _create_reset_restriction(
48 const resourced_restriction_info *info, const int ifindex)
50 resourced_iface_type iftype;
51 resourced_restriction_info *res_data;
53 iftype = get_iftype(ifindex);
54 if (info->iftype != iftype)
57 res_data = (resourced_restriction_info *)
58 malloc(sizeof(resourced_restriction_info));
60 _E("Malloc of resourced_restriction_info failed\n");
63 res_data->app_id = strdup(info->app_id);
64 res_data->iftype = iftype;
65 res_data->rcv_limit = info->rcv_limit;
66 res_data->send_limit = info->send_limit;
67 res_data->rst_state = info->rst_state;
68 res_data->quota_id = info->quota_id;
69 res_data->roaming = info->roaming;
73 static resourced_cb_ret _restriction_iter(
74 const resourced_restriction_info *info, void *user_data)
76 struct restriction_context *context =
77 (struct restriction_context *)(user_data);
80 _E("Please provide valid pointer!");
81 return RESOURCED_CONTINUE;
84 _SI("we have restriction for appid %s and check it for ifindex %d\n",
85 info->app_id, context->ifindex);
86 gpointer data = _create_reset_restriction(info, context->ifindex);
88 context->restrictions = g_list_prepend(context->restrictions,
90 return RESOURCED_CONTINUE;
93 enum restriction_apply_type
101 enum restriction_apply_type apply_type;
104 static void _reset_restrictions_iter(gpointer data, gpointer user_data)
106 resourced_restriction_info *arg = (resourced_restriction_info *)data;
107 struct apply_param *param = (struct apply_param *)user_data;
109 u_int32_t app_classid = RESOURCED_UNKNOWN_CLASSID;
110 resourced_net_restrictions rst = {0};
111 int error_code = RESOURCED_ERROR_NONE;
112 enum traffic_restriction_type rst_type;
114 ret_msg_if(!arg || !param, "Please provide valid pointer!");
116 rst.iftype = arg->iftype;
117 rst.send_limit = arg->send_limit;
118 rst.rcv_limit = arg->rcv_limit;
119 rst.roaming = arg->roaming;
121 if (param->apply_type == KEEP_AS_IS)
122 rst_type = convert_to_restriction_type(arg->rst_state);
123 else if (param->apply_type == UNSET)
124 rst_type = RST_UNSET;
126 rst_type = RST_UNDEFINDED;
128 app_classid = get_classid_by_app_id(arg->app_id, false);
130 error_code = process_kernel_restriction(app_classid,
133 ret_msg_if(error_code != RESOURCED_ERROR_NONE,
134 "restriction type %d failed, error %d\n", rst_type,
138 static void _apply_restrictions(const list_restrictions_info *restrictions)
140 struct apply_param param = {.apply_type = KEEP_AS_IS};
142 _D("No restrictions!");
145 g_list_foreach((GList *)restrictions, _reset_restrictions_iter, ¶m);
148 static void _reset_restrictions(const list_restrictions_info *restrictions)
150 struct apply_param param = {.apply_type = UNSET};
152 _D("No restrictions!");
155 g_list_foreach((GList *)restrictions, _reset_restrictions_iter, ¶m);
158 static void _free_restriction_iter(gpointer data)
160 resourced_restriction_info *arg = (resourced_restriction_info *)data;
162 _D("No restrictions!");
165 free((char *)arg->app_id);
169 static void _free_reset_restrictions(list_restrictions_info *restrictions)
172 _E("Plese provide valid pointer!");
175 g_list_free_full(restrictions, _free_restriction_iter);
178 static void process_on_iface_up(const int ifindex)
180 struct restriction_context context = {
185 restrictions_foreach(_restriction_iter, &context);
186 if (!context.restrictions) {
187 _D("No restrictions!");
190 _apply_restrictions(context.restrictions);
191 _free_reset_restrictions(context.restrictions);
194 static void handle_on_iface_up(const int ifindex)
196 process_on_iface_up(ifindex);
199 static void handle_on_iface_down(const int ifindex)
201 struct restriction_context context = {
206 restrictions_foreach(_restriction_iter, &context);
207 if (!context.restrictions) {
208 _D("No restrictions!");
211 _reset_restrictions(context.restrictions);
212 _free_reset_restrictions(context.restrictions);
215 static resourced_cb_ret roaming_restrictions_iter(
216 const resourced_restriction_info *info, void *user_data)
218 struct apply_param param = {.apply_type = KEEP_AS_IS};
219 _reset_restrictions_iter((gpointer)info, ¶m);
220 return RESOURCED_CONTINUE;
223 static void handle_roaming_change(void)
225 restrictions_foreach(roaming_restrictions_iter, NULL);
228 roaming_cb get_roaming_restriction_cb(void)
230 return handle_roaming_change;
233 iface_callback *create_restriction_callback(void)
235 iface_callback *ret_arg = (iface_callback *)
236 malloc(sizeof(iface_callback));
239 _E("Malloc of iface_callback failed\n");
242 ret_arg->handle_iface_up = handle_on_iface_up;
243 ret_arg->handle_iface_down = handle_on_iface_down;
248 void reactivate_restrictions(void)
251 struct if_nameindex *ids = if_nameindex();
253 ret_msg_if(ids == NULL,
254 "Failed to initialize iftype table! errno: %d, %s",
255 errno, strerror(errno));
257 for (i = 0; ids[i].if_index != 0; ++i) {
258 if (!is_address_exists(ids[i].if_name))
260 process_on_iface_up(ids[i].if_index);
263 if_freenameindex(ids);