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-manager-plugin-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[] = {
43 void __initialize_rstn_rule(table_restrictions_info *rule)
47 rule->iftype = STC_IFACE_ALL;
50 rule->subscriber_id = NULL;
51 rule->roaming = STC_ROAMING_DISABLE;
53 rule->rstn_type = STC_RSTN_TYPE_UNKNOWN;
54 rule->data_limit = -1;
55 rule->data_warn_limit = -1;
57 rule->month_start_date = 1;
58 rule->monthly_limit = -1;
59 rule->weekly_limit = -1;
60 rule->daily_limit = -1;
65 gboolean __validate_rstn_rule(table_restrictions_info *rule)
67 __STC_LOG_FUNC_ENTER__;
70 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
71 return FALSE; //LCOV_EXCL_LINE
74 if (rule->iftype <= STC_IFACE_UNKNOWN ||
75 rule->iftype >= STC_IFACE_LAST_ELEM) {
76 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
77 return FALSE; //LCOV_EXCL_LINE
80 if (rule->roaming > STC_ROAMING_DISABLE) {
81 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
82 return FALSE; //LCOV_EXCL_LINE
85 if (rule->subscriber_id == NULL) {
86 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
87 return FALSE; //LCOV_EXCL_LINE
90 if (rule->app_id == NULL) {
91 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
92 return FALSE; //LCOV_EXCL_LINE
95 __STC_LOG_FUNC_EXIT__;
99 void __stc_restriction_app_info_builder_add(GVariantBuilder *builder,
100 const table_restrictions_info *info)
102 __STC_LOG_FUNC_ENTER__;
104 if (!builder || !info) {
105 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
106 return; //LCOV_EXCL_LINE
109 g_variant_builder_add(builder, "{sv}", "app_id",
110 g_variant_new_string(info->app_id));
112 g_variant_builder_add(builder, "{sv}", "ifname",
113 g_variant_new_string(info->ifname));
115 g_variant_builder_add(builder, "{sv}", "iftype",
116 g_variant_new_uint16(info->iftype));
118 g_variant_builder_add(builder, "{sv}", "rstn_type",
119 g_variant_new_uint16(info->rstn_type));
121 g_variant_builder_add(builder, "{sv}", "data_limit",
122 g_variant_new_int64(info->data_limit));
124 g_variant_builder_add(builder, "{sv}", "data_warn_limit",
125 g_variant_new_int64(info->data_warn_limit));
127 g_variant_builder_add(builder, "{sv}", "month_start_date",
128 g_variant_new_int32(info->month_start_date));
130 g_variant_builder_add(builder, "{sv}", "monthly_limit",
131 g_variant_new_int64(info->monthly_limit));
133 g_variant_builder_add(builder, "{sv}", "weekly_limit",
134 g_variant_new_int64(info->weekly_limit));
136 g_variant_builder_add(builder, "{sv}", "daily_limit",
137 g_variant_new_int64(info->daily_limit));
139 g_variant_builder_add(builder, "{sv}", "roaming",
140 g_variant_new_uint16(info->roaming));
142 g_variant_builder_add(builder, "{sv}", "subscriber_id",
143 g_variant_new_string(info->subscriber_id));
145 __STC_LOG_FUNC_EXIT__;
148 stc_cb_ret_e __table_restrictions_foreach_app_cb(const table_restrictions_info *info,
151 __STC_LOG_FUNC_ENTER__;
152 GVariantBuilder *builder = (GVariantBuilder *)user_data;
153 GVariantBuilder sub_builder;
155 if (!info || !builder) {
156 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
157 return STC_CANCEL; //LCOV_EXCL_LINE
160 g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
161 __stc_restriction_app_info_builder_add(&sub_builder, info);
163 g_variant_builder_add_value(builder,
164 g_variant_builder_end(&sub_builder));
166 __STC_LOG_FUNC_EXIT__;
170 stc_cb_ret_e __table_restrictions_per_app_cb(const table_restrictions_info *info,
173 __STC_LOG_FUNC_ENTER__;
174 GVariantBuilder *builder = (GVariantBuilder *)user_data;
176 if (!info || !builder) {
177 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
178 return STC_CANCEL; //LCOV_EXCL_LINE
181 __stc_restriction_app_info_builder_add(builder, info);
183 __STC_LOG_FUNC_EXIT__;
187 static void __stc_extract_restriction_rule(const char *key, GVariant *value,
190 table_restrictions_info *rule =
191 (table_restrictions_info *) user_data;
193 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
194 return; //LCOV_EXCL_LINE
197 if (!g_strcmp0(key, "app_id")) {
199 const gchar *str = g_variant_get_string(value, &str_length);
200 rule->app_id = g_strdup(str);
201 STC_LOGD("app_id: [%s]", rule->app_id);
203 } else if (!g_strcmp0(key, "ifname")) {
205 const gchar *str = g_variant_get_string(value, &str_length);
206 rule->ifname = g_strdup(str);
207 STC_LOGD("ifname: [%s]", rule->ifname);
209 } else if (!g_strcmp0(key, "iftype")) {
210 rule->iftype = g_variant_get_uint16(value);
211 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
213 } else if (!g_strcmp0(key, "data_limit")) {
214 rule->data_limit = g_variant_get_int64(value);
215 STC_LOGD("data_limit: [%lld]", rule->data_limit);
217 } else if (!g_strcmp0(key, "data_warn_limit")) {
218 rule->data_warn_limit = g_variant_get_int64(value);
219 STC_LOGD("data_warn_limit: [%lld]", rule->data_warn_limit);
221 } else if (!g_strcmp0(key, "month_start_date")) {
222 rule->month_start_date = g_variant_get_int32(value);
223 STC_LOGD("month_start_date: [%d]", rule->month_start_date);
225 } else if (!g_strcmp0(key, "monthly_limit")) {
226 rule->monthly_limit = g_variant_get_int64(value);
227 STC_LOGD("monthly_limit: [%lld]", rule->monthly_limit);
229 } else if (!g_strcmp0(key, "weekly_limit")) {
230 rule->weekly_limit = g_variant_get_int64(value);
231 STC_LOGD("weekly_limit: [%lld]", rule->weekly_limit);
233 } else if (!g_strcmp0(key, "daily_limit")) {
234 rule->daily_limit = g_variant_get_int64(value);
235 STC_LOGD("daily_limit: [%lld]", rule->daily_limit);
237 } else if (!g_strcmp0(key, "roaming")) {
238 rule->roaming = g_variant_get_uint16(value);
239 STC_LOGD("roaming: [%u]", rule->roaming);
241 } else if (!g_strcmp0(key, "subscriber_id")) {
243 const gchar *str = g_variant_get_string(value, &str_length);
244 rule->subscriber_id = g_strdup(str);
245 STC_LOGD("subscriber_id: [%s]", rule->subscriber_id);
247 } else if (!g_strcmp0(key, "rstn_type")) {
248 rule->rstn_type = g_variant_get_uint16(value);
249 STC_LOGD("type: [%u]", (unsigned int) rule->rstn_type);
251 } else if (!g_strcmp0(key, "mac")) {
253 const gchar *str = g_variant_get_string(value, &str_length);
254 rule->mac = g_strdup(str);
255 STC_LOGD("mac: [%s]", rule->mac);
258 STC_LOGD("Unknown select rule"); //LCOV_EXCL_LINE
262 static void __stc_free_restriction_rule_members(table_restrictions_info *rule)
266 FREE(rule->subscriber_id);
270 gboolean handle_restriction_set(StcRestriction *object,
271 GDBusMethodInvocation *invocation,
272 GVariant *parameters,
275 __STC_LOG_FUNC_ENTER__;
276 GVariantIter *iter = NULL;
277 table_restrictions_info rule;
278 stc_error_e ret = STC_ERROR_NONE;
280 stc_set_keep_alive(TRUE);
282 memset(&rule, 0, sizeof(table_restrictions_info));
283 __initialize_rstn_rule(&rule);
285 g_variant_get(parameters, "a{sv}", &iter);
287 stc_manager_gdbus_dict_foreach(iter,
288 __stc_extract_restriction_rule,
290 g_variant_iter_free(iter);
293 if (__validate_rstn_rule(&rule) == FALSE) {
294 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
295 STC_ERROR_INVALID_PARAMETER);
296 __stc_free_restriction_rule_members(&rule);
297 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
301 ret = table_restrictions_update(&rule);
302 if (ret != STC_ERROR_NONE) {
303 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
304 STC_ERROR_DB_FAILED);
305 __stc_free_restriction_rule_members(&rule);
306 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
310 ret = stc_plugin_monitor_add_rstn(&rule);
311 if (ret == STC_ERROR_UNINITIALIZED) {
312 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
313 STC_ERROR_UNINITIALIZED);
314 table_restrictions_delete(rule.app_id, rule.iftype, rule.ifname,
315 rule.subscriber_id, rule.roaming);
316 __stc_free_restriction_rule_members(&rule);
317 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
319 } else if (ret == STC_ERROR_NO_DATA || ret == STC_ERROR_OUT_OF_MEMORY) {
320 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
322 __stc_free_restriction_rule_members(&rule);
323 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
326 STC_DBUS_REPLY_ERROR_NONE(invocation);
327 __stc_free_restriction_rule_members(&rule);
328 __STC_LOG_FUNC_EXIT__;
332 gboolean handle_restriction_unset(StcRestriction *object,
333 GDBusMethodInvocation *invocation,
334 GVariant *parameters,
337 __STC_LOG_FUNC_ENTER__;
338 GVariantIter *iter = NULL;
339 table_restrictions_info rule;
340 stc_error_e ret = STC_ERROR_NONE;
342 stc_set_keep_alive(TRUE);
344 memset(&rule, 0, sizeof(table_restrictions_info));
345 __initialize_rstn_rule(&rule);
347 g_variant_get(parameters, "a{sv}", &iter);
349 stc_manager_gdbus_dict_foreach(iter,
350 __stc_extract_restriction_rule,
352 g_variant_iter_free(iter);
355 if (__validate_rstn_rule(&rule) == FALSE) {
356 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
357 STC_ERROR_INVALID_PARAMETER);
358 __stc_free_restriction_rule_members(&rule);
359 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
363 ret = table_restrictions_delete(rule.app_id, rule.iftype, rule.ifname,
364 rule.subscriber_id, rule.roaming);
365 if (ret != STC_ERROR_NONE) {
366 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
367 STC_ERROR_DB_FAILED);
368 __stc_free_restriction_rule_members(&rule);
369 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
373 ret = stc_plugin_monitor_remove_rstn(&rule);
374 if (ret == STC_ERROR_UNINITIALIZED) {
375 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
376 STC_ERROR_UNINITIALIZED);
377 __stc_free_restriction_rule_members(&rule);
378 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
380 } else if (ret == STC_ERROR_NO_DATA) {
381 table_restrictions_update(&rule);
382 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
384 __stc_free_restriction_rule_members(&rule);
385 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
389 STC_DBUS_REPLY_ERROR_NONE(invocation);
390 __stc_free_restriction_rule_members(&rule);
391 __STC_LOG_FUNC_EXIT__;
395 gboolean handle_restriction_set_list(StcRestriction *object,
396 GDBusMethodInvocation *invocation,
397 GVariant *parameters,
400 __STC_LOG_FUNC_ENTER__;
401 GVariantIter *iter = NULL;
402 GVariantIter *iter_row = NULL;
403 stc_error_e ret = STC_ERROR_NONE;
405 stc_set_keep_alive(TRUE);
407 g_variant_get(parameters, "aa{sv}", &iter);
408 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
409 table_restrictions_info rule;
411 memset(&rule, 0, sizeof(table_restrictions_info));
412 __initialize_rstn_rule(&rule);
414 stc_manager_gdbus_dict_foreach(iter_row,
415 __stc_extract_restriction_rule, &rule);
417 if (__validate_rstn_rule(&rule)) {
418 ret = table_restrictions_update(&rule);
419 if (ret != STC_ERROR_NONE) {
420 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
421 g_variant_iter_free(iter_row);
422 g_variant_iter_free(iter);
423 __stc_free_restriction_rule_members(&rule);
424 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
428 ret = stc_plugin_monitor_add_rstn(&rule);
429 if (ret != STC_ERROR_NONE) {
430 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
431 g_variant_iter_free(iter_row);
432 g_variant_iter_free(iter);
433 __stc_free_restriction_rule_members(&rule);
434 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
439 __stc_free_restriction_rule_members(&rule);
440 g_variant_iter_free(iter_row);
442 g_variant_iter_free(iter);
444 STC_DBUS_REPLY_ERROR_NONE(invocation);
445 __STC_LOG_FUNC_EXIT__;
449 gboolean handle_restriction_unset_list(StcRestriction *object,
450 GDBusMethodInvocation *invocation,
451 GVariant *parameters,
454 __STC_LOG_FUNC_ENTER__;
455 GVariantIter *iter = NULL;
456 GVariantIter *iter_row = NULL;
457 stc_error_e ret = STC_ERROR_NONE;
459 stc_set_keep_alive(TRUE);
461 g_variant_get(parameters, "aa{sv}", &iter);
462 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
463 table_restrictions_info rule;
465 memset(&rule, 0, sizeof(table_restrictions_info));
466 __initialize_rstn_rule(&rule);
468 stc_manager_gdbus_dict_foreach(iter_row,
469 __stc_extract_restriction_rule, &rule);
471 if (__validate_rstn_rule(&rule)) {
472 ret = table_restrictions_delete(rule.app_id, rule.iftype,
473 rule.ifname, rule.subscriber_id, rule.roaming);
474 if (ret != STC_ERROR_NONE) {
475 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
476 g_variant_iter_free(iter_row);
477 g_variant_iter_free(iter);
478 __stc_free_restriction_rule_members(&rule);
479 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
483 ret = stc_plugin_monitor_remove_rstn(&rule);
484 if (ret != STC_ERROR_NONE) {
485 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
486 g_variant_iter_free(iter_row);
487 g_variant_iter_free(iter);
488 __stc_free_restriction_rule_members(&rule);
489 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
494 __stc_free_restriction_rule_members(&rule);
495 g_variant_iter_free(iter_row);
497 g_variant_iter_free(iter);
499 STC_DBUS_REPLY_ERROR_NONE(invocation);
500 __STC_LOG_FUNC_EXIT__;
504 gboolean handle_restriction_get(StcRestriction *object,
505 GDBusMethodInvocation *invocation,
509 __STC_LOG_FUNC_ENTER__;
510 GVariantBuilder *builder = NULL;
511 GVariant *return_parameters = NULL;
514 stc_set_keep_alive(TRUE);
516 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
518 ret = table_restrictions_per_app(app_id,
519 __table_restrictions_per_app_cb,
521 if (ret < STC_ERROR_NONE) {
522 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
523 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
524 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
525 return TRUE; //LCOV_EXCL_LINE
528 return_parameters = g_variant_new("(ia{sv})", STC_ERROR_NONE, builder);
529 g_variant_builder_unref(builder);
531 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
532 STC_DBUS_REPLY(invocation, return_parameters);
533 __STC_LOG_FUNC_EXIT__;
537 gboolean handle_restriction_get_all(StcRestriction *object,
538 GDBusMethodInvocation *invocation,
541 __STC_LOG_FUNC_ENTER__;
542 GVariantBuilder *builder = NULL;
543 GVariant *return_parameters = NULL;
546 stc_set_keep_alive(TRUE);
548 builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
550 ret = table_restrictions_foreach(__table_restrictions_foreach_app_cb,
552 if (ret < STC_ERROR_NONE) {
553 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
554 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
555 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
556 return TRUE; //LCOV_EXCL_LINE
559 return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
560 g_variant_builder_unref(builder);
562 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
563 STC_DBUS_REPLY(invocation, return_parameters);
564 __STC_LOG_FUNC_EXIT__;
568 gboolean handle_restriction_get_type(StcRestriction *object,
569 GDBusMethodInvocation *invocation,
574 __STC_LOG_FUNC_ENTER__;
575 GVariant *return_parameters = NULL;
576 stc_rstn_type_e type = STC_RSTN_TYPE_UNKNOWN;
579 stc_set_keep_alive(TRUE);
581 ret = table_restrictions_get_restriction_type(app_id, iftype, &type);
582 if (ret < STC_ERROR_NONE) {
583 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
584 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
588 return_parameters = g_variant_new("(ii)", STC_ERROR_NONE, type);
589 STC_DBUS_REPLY(invocation, return_parameters);
590 __STC_LOG_FUNC_EXIT__;