2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "table-restrictions.h"
19 #include "stc-restriction.h"
20 #include "stc-manager-gdbus.h"
21 #include "stc-monitor.h"
23 #define RESTRICTION_DBUS_ERROR_NAME "net.stc.restriction.Error.Failed"
25 #define STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, err_num) \
26 g_dbus_method_invocation_return_dbus_error((invocation), \
27 RESTRICTION_DBUS_ERROR_NAME, \
28 stc_err_strs[-(err_num)])
30 static const gchar *stc_err_strs[] = {
41 void __initialize_rstn_rule(table_restrictions_info *rule)
45 rule->iftype = STC_IFACE_ALL;
46 rule->rst_state = STC_RESTRICTION_REMOVED;
48 rule->data_warn_limit = 0;
49 rule->roaming = STC_ROAMING_DISABLE;
53 gboolean __validate_rstn_rule(table_restrictions_info *rule,
54 enum traffic_restriction_type rst_type)
56 __STC_LOG_FUNC_ENTER__;
59 __STC_LOG_FUNC_EXIT__;
63 if (rst_type <= RST_UNDEFINDED || rst_type >= RST_MAX_VALUE) {
64 __STC_LOG_FUNC_EXIT__;
68 if (rule->iftype <= STC_IFACE_UNKNOWN ||
69 rule->iftype >= STC_IFACE_LAST_ELEM) {
70 __STC_LOG_FUNC_EXIT__;
74 if (rule->roaming >= STC_ROAMING_LAST_ELEM) {
75 __STC_LOG_FUNC_EXIT__;
79 if (rule->imsi == NULL) {
80 __STC_LOG_FUNC_EXIT__;
84 if (rule->app_id == NULL) {
85 __STC_LOG_FUNC_EXIT__;
89 __STC_LOG_FUNC_EXIT__;
93 void __stc_restriction_app_info_builder_add(GVariantBuilder *builder,
94 const table_restrictions_info *info)
96 __STC_LOG_FUNC_ENTER__;
98 if (!builder || !info) {
99 __STC_LOG_FUNC_EXIT__;
103 g_variant_builder_add(builder, "{sv}", "app_id",
104 g_variant_new_string(info->app_id));
106 g_variant_builder_add(builder, "{sv}", "ifname",
107 g_variant_new_string(info->ifname));
109 g_variant_builder_add(builder, "{sv}", "iftype",
110 g_variant_new_uint16(info->iftype));
112 g_variant_builder_add(builder, "{sv}", "rst_state",
113 g_variant_new_uint16(info->rst_state));
115 g_variant_builder_add(builder, "{sv}", "data_limit",
116 g_variant_new_int64(info->data_limit));
118 g_variant_builder_add(builder, "{sv}", "data_warn_limit",
119 g_variant_new_int64(info->data_warn_limit));
121 g_variant_builder_add(builder, "{sv}", "roaming",
122 g_variant_new_uint16(info->roaming));
124 g_variant_builder_add(builder, "{sv}", "imsi",
125 g_variant_new_string(info->imsi));
127 __STC_LOG_FUNC_EXIT__;
130 stc_cb_ret_e __table_restrictions_foreach_app_cb(const table_restrictions_info *info,
133 __STC_LOG_FUNC_ENTER__;
134 GVariantBuilder *builder = (GVariantBuilder *)user_data;
135 GVariantBuilder sub_builder;
137 if (!info || !builder) {
138 __STC_LOG_FUNC_EXIT__;
142 g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
143 __stc_restriction_app_info_builder_add(&sub_builder, info);
145 g_variant_builder_add_value(builder,
146 g_variant_builder_end(&sub_builder));
148 __STC_LOG_FUNC_EXIT__;
152 stc_cb_ret_e __table_restrictions_per_app_cb(const table_restrictions_info *info,
155 __STC_LOG_FUNC_ENTER__;
156 GVariantBuilder *builder = (GVariantBuilder *)user_data;
158 if (!info || !builder) {
159 __STC_LOG_FUNC_EXIT__;
163 __stc_restriction_app_info_builder_add(builder, info);
165 __STC_LOG_FUNC_EXIT__;
169 static void __stc_extract_restriction_rule(const char *key, GVariant *value,
172 __STC_LOG_FUNC_ENTER__;
174 table_restrictions_info *rule =
175 (table_restrictions_info *) user_data;
177 __STC_LOG_FUNC_EXIT__;
181 if (!g_strcmp0(key, "app_id")) {
183 const gchar *str = g_variant_get_string(value, &str_length);
184 rule->app_id = g_strdup(str);
185 STC_LOGD("app_id: [%s]", (unsigned int) rule->app_id);
187 } else if (!g_strcmp0(key, "ifname")) {
189 const gchar *str = g_variant_get_string(value, &str_length);
190 rule->ifname = g_strdup(str);
191 STC_LOGD("ifname: [%s]", rule->ifname);
193 } else if (!g_strcmp0(key, "iftype")) {
194 rule->iftype = g_variant_get_uint16(value);
195 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
197 } else if (!g_strcmp0(key, "data_limit")) {
198 rule->data_limit = g_variant_get_int64(value);
199 STC_LOGD("data_limit: [%lld]", rule->data_limit);
201 } else if (!g_strcmp0(key, "data_warn_limit")) {
202 rule->data_warn_limit = g_variant_get_int64(value);
203 STC_LOGD("data_warn_limit: [%lld]", rule->data_warn_limit);
205 } else if (!g_strcmp0(key, "roaming")) {
206 rule->roaming = g_variant_get_uint16(value);
207 STC_LOGD("roaming: [%u]", rule->roaming);
209 } else if (!g_strcmp0(key, "imsi")) {
211 const gchar *str = g_variant_get_string(value, &str_length);
212 rule->imsi = g_strdup(str);
213 STC_LOGD("imsi: [%s]", rule->imsi);
216 STC_LOGD("Unknown select rule");
219 __STC_LOG_FUNC_EXIT__;
222 gboolean handle_restriction_set(StcRestriction *object,
223 GDBusMethodInvocation *invocation,
224 GVariant *parameters,
227 __STC_LOG_FUNC_ENTER__;
228 GVariantIter *iter = NULL;
229 table_restrictions_info rule;
231 memset(&rule, 0, sizeof(table_restrictions_info));
232 __initialize_rstn_rule(&rule);
234 g_variant_get(parameters, "a{sv}", &iter);
236 stc_manager_gdbus_dict_foreach(iter,
237 __stc_extract_restriction_rule,
239 g_variant_iter_free(iter);
242 rule.rst_state = STC_RESTRICTION_REMOVED;
244 if (__validate_rstn_rule(&rule, RST_SET) == FALSE) {
245 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
246 STC_ERROR_INVALID_PARAMETER);
247 __STC_LOG_FUNC_EXIT__;
251 table_restrictions_update(&rule);
252 /* update restriction rule in runtime structure */
253 stc_monitor_rstns_tree_add(&rule);
255 STC_DBUS_REPLY_ERROR_NONE(invocation);
256 __STC_LOG_FUNC_EXIT__;
260 gboolean handle_restriction_exclude(StcRestriction *object,
261 GDBusMethodInvocation *invocation,
262 GVariant *parameters,
265 __STC_LOG_FUNC_ENTER__;
266 GVariantIter *iter = NULL;
267 table_restrictions_info rule;
269 memset(&rule, 0, sizeof(table_restrictions_info));
270 __initialize_rstn_rule(&rule);
272 g_variant_get(parameters, "a{sv}", &iter);
274 stc_manager_gdbus_dict_foreach(iter,
275 __stc_extract_restriction_rule,
277 g_variant_iter_free(iter);
280 rule.rst_state = STC_RESTRICTION_EXCLUDED;
282 if (__validate_rstn_rule(&rule, RST_EXCLUDE) == FALSE) {
283 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
284 STC_ERROR_INVALID_PARAMETER);
285 __STC_LOG_FUNC_EXIT__;
289 table_restrictions_update(&rule);
290 /* update restriction rule in runtime structure */
291 stc_monitor_rstns_tree_add(&rule);
293 STC_DBUS_REPLY_ERROR_NONE(invocation);
294 __STC_LOG_FUNC_EXIT__;
298 gboolean handle_restriction_unset(StcRestriction *object,
299 GDBusMethodInvocation *invocation,
300 GVariant *parameters,
303 __STC_LOG_FUNC_ENTER__;
304 GVariantIter *iter = NULL;
305 table_restrictions_info rule;
307 memset(&rule, 0, sizeof(table_restrictions_info));
308 __initialize_rstn_rule(&rule);
310 g_variant_get(parameters, "a{sv}", &iter);
312 stc_manager_gdbus_dict_foreach(iter,
313 __stc_extract_restriction_rule,
315 g_variant_iter_free(iter);
318 if (__validate_rstn_rule(&rule, RST_UNSET) == FALSE) {
319 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
320 STC_ERROR_INVALID_PARAMETER);
321 __STC_LOG_FUNC_EXIT__;
325 table_restrictions_delete(rule.app_id, rule.iftype, rule.imsi);
326 /* remove restriction rule from runtime structure */
327 stc_monitor_rstns_tree_remove(&rule);
329 STC_DBUS_REPLY_ERROR_NONE(invocation);
330 __STC_LOG_FUNC_EXIT__;
334 gboolean handle_restriction_get(StcRestriction *object,
335 GDBusMethodInvocation *invocation,
339 __STC_LOG_FUNC_ENTER__;
340 GVariantBuilder *builder = NULL;
341 GVariant *return_parameters = NULL;
344 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
346 ret = table_restrictions_per_app(app_id,
347 __table_restrictions_per_app_cb,
349 if (ret < STC_ERROR_NONE) {
350 g_variant_builder_unref(builder);
351 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
352 __STC_LOG_FUNC_EXIT__;
356 return_parameters = g_variant_new("(ia{sv})", STC_ERROR_NONE, builder);
357 g_variant_builder_unref(builder);
359 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
360 STC_DBUS_REPLY(invocation, return_parameters);
361 __STC_LOG_FUNC_EXIT__;
365 gboolean handle_restriction_get_all(StcRestriction *object,
366 GDBusMethodInvocation *invocation,
369 __STC_LOG_FUNC_ENTER__;
370 GVariantBuilder *builder = NULL;
371 GVariant *return_parameters = NULL;
374 builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
376 ret = table_restrictions_foreach(__table_restrictions_foreach_app_cb,
378 if (ret < STC_ERROR_NONE) {
379 g_variant_builder_unref(builder);
380 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
381 __STC_LOG_FUNC_EXIT__;
385 return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
386 g_variant_builder_unref(builder);
388 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
389 STC_DBUS_REPLY(invocation, return_parameters);
390 __STC_LOG_FUNC_EXIT__;
394 gboolean handle_restriction_get_state(StcRestriction *object,
395 GDBusMethodInvocation *invocation,
400 __STC_LOG_FUNC_ENTER__;
401 GVariant *return_parameters = NULL;
402 stc_restriction_state_e state = STC_RESTRICTION_UNKNOWN;
405 ret = table_restrictions_get_restriction_state(app_id, iftype, &state);
406 if (ret < STC_ERROR_NONE) {
407 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
408 __STC_LOG_FUNC_EXIT__;
412 return_parameters = g_variant_new("(ii)", STC_ERROR_NONE, state);
413 STC_DBUS_REPLY(invocation, return_parameters);
414 __STC_LOG_FUNC_EXIT__;