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;
49 rule->rcv_warn_limit = 0;
50 rule->send_warn_limit = 0;
51 rule->roaming = STC_ROAMING_DISABLE;
55 gboolean __validate_rstn_rule(table_restrictions_info *rule,
56 enum traffic_restriction_type rst_type)
58 __STC_LOG_FUNC_ENTER__;
61 __STC_LOG_FUNC_EXIT__;
65 if (rst_type <= RST_UNDEFINDED || rst_type >= RST_MAX_VALUE) {
66 __STC_LOG_FUNC_EXIT__;
70 if (rule->iftype <= STC_IFACE_UNKNOWN ||
71 rule->iftype >= STC_IFACE_LAST_ELEM) {
72 __STC_LOG_FUNC_EXIT__;
76 if (rule->roaming >= STC_ROAMING_LAST_ELEM) {
77 __STC_LOG_FUNC_EXIT__;
81 if (rule->imsi == NULL) {
82 __STC_LOG_FUNC_EXIT__;
86 if (rule->app_id == NULL) {
87 __STC_LOG_FUNC_EXIT__;
91 __STC_LOG_FUNC_EXIT__;
95 void __stc_restriction_app_info_builder_add(GVariantBuilder *builder,
96 const table_restrictions_info *info)
98 __STC_LOG_FUNC_ENTER__;
100 if (!builder || !info) {
101 __STC_LOG_FUNC_EXIT__;
105 g_variant_builder_add(builder, "{sv}", "app_id",
106 g_variant_new_string(info->app_id));
108 g_variant_builder_add(builder, "{sv}", "ifname",
109 g_variant_new_string(info->ifname));
111 g_variant_builder_add(builder, "{sv}", "iftype",
112 g_variant_new_uint16(info->iftype));
114 g_variant_builder_add(builder, "{sv}", "rst_state",
115 g_variant_new_uint16(info->rst_state));
117 g_variant_builder_add(builder, "{sv}", "rcv_limit",
118 g_variant_new_int64(info->rcv_limit));
120 g_variant_builder_add(builder, "{sv}", "send_limit",
121 g_variant_new_int64(info->send_limit));
123 g_variant_builder_add(builder, "{sv}", "rcv_warn_limit",
124 g_variant_new_int64(info->rcv_warn_limit));
126 g_variant_builder_add(builder, "{sv}", "send_warn_limit",
127 g_variant_new_int64(info->send_warn_limit));
129 g_variant_builder_add(builder, "{sv}", "roaming",
130 g_variant_new_uint16(info->roaming));
132 g_variant_builder_add(builder, "{sv}", "imsi",
133 g_variant_new_string(info->imsi));
135 __STC_LOG_FUNC_EXIT__;
138 stc_cb_ret_e __table_restrictions_foreach_app_cb(const table_restrictions_info *info,
141 __STC_LOG_FUNC_ENTER__;
142 GVariantBuilder *builder = (GVariantBuilder *)user_data;
143 GVariantBuilder sub_builder;
145 if (!info || !builder) {
146 __STC_LOG_FUNC_EXIT__;
150 g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
151 __stc_restriction_app_info_builder_add(&sub_builder, info);
153 g_variant_builder_add_value(builder,
154 g_variant_builder_end(&sub_builder));
156 __STC_LOG_FUNC_EXIT__;
160 stc_cb_ret_e __table_restrictions_per_app_cb(const table_restrictions_info *info,
163 __STC_LOG_FUNC_ENTER__;
164 GVariantBuilder *builder = (GVariantBuilder *)user_data;
166 if (!info || !builder) {
167 __STC_LOG_FUNC_EXIT__;
171 __stc_restriction_app_info_builder_add(builder, info);
173 __STC_LOG_FUNC_EXIT__;
177 static void __stc_extract_restriction_rule(const char *key, GVariant *value,
180 __STC_LOG_FUNC_ENTER__;
182 table_restrictions_info *rule =
183 (table_restrictions_info *) user_data;
185 __STC_LOG_FUNC_EXIT__;
189 if (!g_strcmp0(key, "app_id")) {
191 const gchar *str = g_variant_get_string(value, &str_length);
192 rule->app_id = g_strdup(str);
193 STC_LOGD("app_id: [%s]", (unsigned int) rule->app_id);
195 } else if (!g_strcmp0(key, "ifname")) {
197 const gchar *str = g_variant_get_string(value, &str_length);
198 rule->ifname = g_strdup(str);
199 STC_LOGD("ifname: [%s]", rule->ifname);
201 } else if (!g_strcmp0(key, "iftype")) {
202 rule->iftype = g_variant_get_uint16(value);
203 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
205 } else if (!g_strcmp0(key, "rcv_limit")) {
206 rule->rcv_limit = g_variant_get_int64(value);
207 STC_LOGD("rcv_limit: [%lld]", rule->rcv_limit);
209 } else if (!g_strcmp0(key, "send_limit")) {
210 rule->send_limit = g_variant_get_int64(value);
211 STC_LOGD("send_limit: [%lld]", rule->send_limit);
213 } else if (!g_strcmp0(key, "rcv_warn_limit")) {
214 rule->rcv_warn_limit = g_variant_get_int64(value);
215 STC_LOGD("rcv_warn_limit: [%lld]", rule->rcv_warn_limit);
217 } else if (!g_strcmp0(key, "send_warn_limit")) {
218 rule->send_warn_limit = g_variant_get_int64(value);
219 STC_LOGD("send_warn_limit: [%lld]", rule->send_warn_limit);
221 } else if (!g_strcmp0(key, "roaming")) {
222 rule->roaming = g_variant_get_uint16(value);
223 STC_LOGD("roaming: [%u]", rule->roaming);
225 } else if (!g_strcmp0(key, "imsi")) {
227 const gchar *str = g_variant_get_string(value, &str_length);
228 rule->imsi = g_strdup(str);
229 STC_LOGD("imsi: [%s]", rule->imsi);
232 STC_LOGD("Unknown select rule");
235 __STC_LOG_FUNC_EXIT__;
238 gboolean handle_restriction_set(StcRestriction *object,
239 GDBusMethodInvocation *invocation,
240 GVariant *parameters,
243 __STC_LOG_FUNC_ENTER__;
244 GVariantIter *iter = NULL;
245 table_restrictions_info rule;
247 memset(&rule, 0, sizeof(table_restrictions_info));
248 __initialize_rstn_rule(&rule);
250 g_variant_get(parameters, "a{sv}", &iter);
252 stc_manager_gdbus_dict_foreach(iter,
253 __stc_extract_restriction_rule,
255 g_variant_iter_free(iter);
258 rule.rst_state = STC_RESTRICTION_REMOVED;
260 if (__validate_rstn_rule(&rule, RST_SET) == FALSE) {
261 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
262 STC_ERROR_INVALID_PARAMETER);
263 __STC_LOG_FUNC_EXIT__;
267 table_restrictions_update(&rule);
268 /* update restriction rule in runtime structure */
269 stc_monitor_rstns_tree_add(&rule);
271 STC_DBUS_REPLY_ERROR_NONE(invocation);
272 __STC_LOG_FUNC_EXIT__;
276 gboolean handle_restriction_exclude(StcRestriction *object,
277 GDBusMethodInvocation *invocation,
278 GVariant *parameters,
281 __STC_LOG_FUNC_ENTER__;
282 GVariantIter *iter = NULL;
283 table_restrictions_info rule;
285 memset(&rule, 0, sizeof(table_restrictions_info));
286 __initialize_rstn_rule(&rule);
288 g_variant_get(parameters, "a{sv}", &iter);
290 stc_manager_gdbus_dict_foreach(iter,
291 __stc_extract_restriction_rule,
293 g_variant_iter_free(iter);
296 rule.rst_state = STC_RESTRICTION_EXCLUDED;
298 if (__validate_rstn_rule(&rule, RST_EXCLUDE) == FALSE) {
299 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
300 STC_ERROR_INVALID_PARAMETER);
301 __STC_LOG_FUNC_EXIT__;
305 table_restrictions_update(&rule);
306 /* update restriction rule in runtime structure */
307 stc_monitor_rstns_tree_add(&rule);
309 STC_DBUS_REPLY_ERROR_NONE(invocation);
310 __STC_LOG_FUNC_EXIT__;
314 gboolean handle_restriction_remove(StcRestriction *object,
315 GDBusMethodInvocation *invocation,
316 GVariant *parameters,
319 __STC_LOG_FUNC_ENTER__;
320 GVariantIter *iter = NULL;
321 table_restrictions_info rule;
323 memset(&rule, 0, sizeof(table_restrictions_info));
324 __initialize_rstn_rule(&rule);
326 g_variant_get(parameters, "a{sv}", &iter);
328 stc_manager_gdbus_dict_foreach(iter,
329 __stc_extract_restriction_rule,
331 g_variant_iter_free(iter);
334 if (__validate_rstn_rule(&rule, RST_UNSET) == FALSE) {
335 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation,
336 STC_ERROR_INVALID_PARAMETER);
337 __STC_LOG_FUNC_EXIT__;
341 table_restrictions_delete(rule.app_id, rule.iftype, rule.imsi);
342 /* remove restriction rule from runtime structure */
343 stc_monitor_rstns_tree_remove(&rule);
345 STC_DBUS_REPLY_ERROR_NONE(invocation);
346 __STC_LOG_FUNC_EXIT__;
350 gboolean handle_restriction_get(StcRestriction *object,
351 GDBusMethodInvocation *invocation,
355 __STC_LOG_FUNC_ENTER__;
356 GVariantBuilder *builder = NULL;
357 GVariant *return_parameters = NULL;
360 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
362 ret = table_restrictions_per_app(app_id,
363 __table_restrictions_per_app_cb,
365 if (ret < STC_ERROR_NONE) {
366 g_variant_builder_unref(builder);
367 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
368 __STC_LOG_FUNC_EXIT__;
372 return_parameters = g_variant_new("(ia{sv})", STC_ERROR_NONE, builder);
373 g_variant_builder_unref(builder);
375 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
376 STC_DBUS_REPLY(invocation, return_parameters);
377 __STC_LOG_FUNC_EXIT__;
381 gboolean handle_restriction_get_all(StcRestriction *object,
382 GDBusMethodInvocation *invocation,
385 __STC_LOG_FUNC_ENTER__;
386 GVariantBuilder *builder = NULL;
387 GVariant *return_parameters = NULL;
390 builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
392 ret = table_restrictions_foreach(__table_restrictions_foreach_app_cb,
394 if (ret < STC_ERROR_NONE) {
395 g_variant_builder_unref(builder);
396 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
397 __STC_LOG_FUNC_EXIT__;
401 return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
402 g_variant_builder_unref(builder);
404 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
405 STC_DBUS_REPLY(invocation, return_parameters);
406 __STC_LOG_FUNC_EXIT__;
410 gboolean handle_restriction_get_state(StcRestriction *object,
411 GDBusMethodInvocation *invocation,
416 __STC_LOG_FUNC_ENTER__;
417 GVariant *return_parameters = NULL;
418 stc_restriction_state_e state = STC_RESTRICTION_UNKNOWN;
421 ret = table_restrictions_get_restriction_state(app_id, iftype, &state);
422 if (ret < STC_ERROR_NONE) {
423 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret);
424 __STC_LOG_FUNC_EXIT__;
428 return_parameters = g_variant_new("(ii)", STC_ERROR_NONE, state);
429 STC_DBUS_REPLY(invocation, return_parameters);
430 __STC_LOG_FUNC_EXIT__;