Corrected file permissions
[platform/core/connectivity/stc-manager.git] / src / stc-restriction.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "stc-db.h"
18 #include "table-restrictions.h"
19 #include "stc-restriction.h"
20 #include "stc-manager-gdbus.h"
21 #include "stc-monitor.h"
22
23 #define RESTRICTION_DBUS_ERROR_NAME "net.stc.restriction.Error.Failed"
24
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)])
29
30 static const gchar *stc_err_strs[] = {
31         "ERROR_NONE",
32         "FAIL",
33         "DB_FAILED",
34         "OUT_OF_MEMORY",
35         "INVALID_PARAMETER",
36         "NO_DATA",
37         "ALREADY_DATA",
38         "UNINITIALIZED",
39         "PERMISSION_DENIED",
40         "NOTIMPL"
41 };
42
43 void __initialize_rstn_rule(table_restrictions_info *rule)
44 {
45         rule->app_id = NULL;
46         rule->ifname = NULL;
47         rule->iftype = STC_IFACE_ALL;
48         rule->rstn_type = STC_RSTN_TYPE_UNKNOWN;
49         rule->data_limit = 0;
50         rule->data_warn_limit = 0;
51         rule->roaming = STC_ROAMING_DISABLE;
52         rule->subscriber_id = NULL;
53 }
54
55 gboolean __validate_rstn_rule(table_restrictions_info *rule)
56 {
57         __STC_LOG_FUNC_ENTER__;
58
59         if (rule == NULL) {
60                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
61                 return FALSE; //LCOV_EXCL_LINE
62         }
63
64         if (rule->iftype <= STC_IFACE_UNKNOWN ||
65             rule->iftype >= STC_IFACE_LAST_ELEM) {
66                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
67                 return FALSE; //LCOV_EXCL_LINE
68         }
69
70         if (rule->roaming >= STC_ROAMING_LAST_ELEM) {
71                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
72                 return FALSE; //LCOV_EXCL_LINE
73         }
74
75         if (rule->subscriber_id == NULL) {
76                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
77                 return FALSE; //LCOV_EXCL_LINE
78         }
79
80         if (rule->app_id == NULL) {
81                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
82                 return FALSE; //LCOV_EXCL_LINE
83         }
84
85         __STC_LOG_FUNC_EXIT__;
86         return TRUE;
87 }
88
89 void __stc_restriction_app_info_builder_add(GVariantBuilder *builder,
90                                             const table_restrictions_info *info)
91 {
92         __STC_LOG_FUNC_ENTER__;
93
94         if (!builder || !info) {
95                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
96                 return; //LCOV_EXCL_LINE
97         }
98
99         g_variant_builder_add(builder, "{sv}", "app_id",
100                               g_variant_new_string(info->app_id));
101
102         g_variant_builder_add(builder, "{sv}", "ifname",
103                               g_variant_new_string(info->ifname));
104
105         g_variant_builder_add(builder, "{sv}", "iftype",
106                               g_variant_new_uint16(info->iftype));
107
108         g_variant_builder_add(builder, "{sv}", "rstn_type",
109                               g_variant_new_uint16(info->rstn_type));
110
111         g_variant_builder_add(builder, "{sv}", "data_limit",
112                               g_variant_new_int64(info->data_limit));
113
114         g_variant_builder_add(builder, "{sv}", "data_warn_limit",
115                               g_variant_new_int64(info->data_warn_limit));
116
117         g_variant_builder_add(builder, "{sv}", "roaming",
118                               g_variant_new_uint16(info->roaming));
119
120         g_variant_builder_add(builder, "{sv}", "subscriber_id",
121                               g_variant_new_string(info->subscriber_id));
122
123         __STC_LOG_FUNC_EXIT__;
124 }
125
126 stc_cb_ret_e __table_restrictions_foreach_app_cb(const table_restrictions_info *info,
127                                                  void *user_data)
128 {
129         __STC_LOG_FUNC_ENTER__;
130         GVariantBuilder *builder = (GVariantBuilder *)user_data;
131         GVariantBuilder sub_builder;
132
133         if (!info || !builder) {
134                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
135                 return STC_CANCEL; //LCOV_EXCL_LINE
136         }
137
138         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
139         __stc_restriction_app_info_builder_add(&sub_builder, info);
140
141         g_variant_builder_add_value(builder,
142                                     g_variant_builder_end(&sub_builder));
143
144         __STC_LOG_FUNC_EXIT__;
145         return STC_CONTINUE;
146 }
147
148 stc_cb_ret_e __table_restrictions_per_app_cb(const table_restrictions_info *info,
149                                              void *user_data)
150 {
151         __STC_LOG_FUNC_ENTER__;
152         GVariantBuilder *builder = (GVariantBuilder *)user_data;
153
154         if (!info || !builder) {
155                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
156                 return STC_CANCEL; //LCOV_EXCL_LINE
157         }
158
159         __stc_restriction_app_info_builder_add(builder, info);
160
161         __STC_LOG_FUNC_EXIT__;
162         return STC_CONTINUE;
163 }
164
165 static void __stc_extract_restriction_rule(const char *key, GVariant *value,
166                                            void *user_data)
167 {
168         __STC_LOG_FUNC_ENTER__;
169
170         table_restrictions_info *rule =
171                 (table_restrictions_info *) user_data;
172         if (rule == NULL) {
173                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
174                 return; //LCOV_EXCL_LINE
175         }
176
177         if (!g_strcmp0(key, "app_id")) {
178                 guint str_length;
179                 const gchar *str = g_variant_get_string(value, &str_length);
180                 rule->app_id = g_strdup(str);
181                 STC_LOGD("app_id: [%s]", rule->app_id);
182
183         } else if (!g_strcmp0(key, "ifname")) {
184                 guint str_length;
185                 const gchar *str = g_variant_get_string(value, &str_length);
186                 rule->ifname = g_strdup(str);
187                 STC_LOGD("ifname: [%s]", rule->ifname);
188
189         } else if (!g_strcmp0(key, "iftype")) {
190                 rule->iftype = g_variant_get_uint16(value);
191                 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
192
193         } else if (!g_strcmp0(key, "data_limit")) {
194                 rule->data_limit = g_variant_get_int64(value);
195                 STC_LOGD("data_limit: [%lld]", rule->data_limit);
196
197         } else if (!g_strcmp0(key, "data_warn_limit")) {
198                 rule->data_warn_limit = g_variant_get_int64(value);
199                 STC_LOGD("data_warn_limit: [%lld]", rule->data_warn_limit);
200
201         } else if (!g_strcmp0(key, "roaming")) {
202                 rule->roaming = g_variant_get_uint16(value);
203                 STC_LOGD("roaming: [%u]", rule->roaming);
204
205         } else if (!g_strcmp0(key, "subscriber_id")) {
206                 guint str_length;
207                 const gchar *str = g_variant_get_string(value, &str_length);
208                 rule->subscriber_id = g_strdup(str);
209                 STC_LOGD("subscriber_id: [%s]", rule->subscriber_id);
210
211         } else if (!g_strcmp0(key, "type")) {
212                 rule->rstn_type = g_variant_get_uint16(value);
213                 STC_LOGD("type: [%u]", (unsigned int) rule->rstn_type);
214
215         } else {
216                 STC_LOGD("Unknown select rule"); //LCOV_EXCL_LINE
217         }
218
219         __STC_LOG_FUNC_EXIT__;
220 }
221
222 gboolean handle_restriction_set(StcRestriction *object,
223                                 GDBusMethodInvocation *invocation,
224                                 GVariant *parameters,
225                                 void *user_data)
226 {
227         __STC_LOG_FUNC_ENTER__;
228         GVariantIter *iter = NULL;
229         table_restrictions_info rule;
230
231         memset(&rule, 0, sizeof(table_restrictions_info));
232         __initialize_rstn_rule(&rule);
233
234         g_variant_get(parameters, "a{sv}", &iter);
235         if (iter != NULL) {
236                 stc_manager_gdbus_dict_foreach(iter,
237                                                __stc_extract_restriction_rule,
238                                                &rule);
239                 g_variant_iter_free(iter);
240         }
241
242         if (__validate_rstn_rule(&rule) == FALSE) {
243                 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
244                                                  STC_ERROR_INVALID_PARAMETER);
245                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
246                 return TRUE;
247         }
248
249         table_restrictions_update(&rule);
250         /* update restriction rule in runtime structure */
251         stc_monitor_rstns_tree_add(&rule);
252
253         STC_DBUS_REPLY_ERROR_NONE(invocation);
254         __STC_LOG_FUNC_EXIT__;
255         return TRUE;
256 }
257
258 gboolean handle_restriction_unset(StcRestriction *object,
259                                    GDBusMethodInvocation *invocation,
260                                    GVariant *parameters,
261                                    void *user_data)
262 {
263         __STC_LOG_FUNC_ENTER__;
264         GVariantIter *iter = NULL;
265         table_restrictions_info rule;
266
267         memset(&rule, 0, sizeof(table_restrictions_info));
268         __initialize_rstn_rule(&rule);
269
270         g_variant_get(parameters, "a{sv}", &iter);
271         if (iter != NULL) {
272                 stc_manager_gdbus_dict_foreach(iter,
273                                                __stc_extract_restriction_rule,
274                                                &rule);
275                 g_variant_iter_free(iter);
276         }
277
278         if (__validate_rstn_rule(&rule) == FALSE) {
279                 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, //LCOV_EXCL_LINE
280                                                  STC_ERROR_INVALID_PARAMETER);
281                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
282                 return TRUE;
283         }
284
285         table_restrictions_delete(rule.app_id, rule.iftype, rule.subscriber_id);
286         /* remove restriction rule from runtime structure */
287         stc_monitor_rstns_tree_remove(&rule);
288
289         STC_DBUS_REPLY_ERROR_NONE(invocation);
290         __STC_LOG_FUNC_EXIT__;
291         return TRUE;
292 }
293
294 gboolean handle_restriction_get(StcRestriction *object,
295                                 GDBusMethodInvocation *invocation,
296                                 const gchar *app_id,
297                                 void *user_data)
298 {
299         __STC_LOG_FUNC_ENTER__;
300         GVariantBuilder *builder = NULL;
301         GVariant *return_parameters = NULL;
302         stc_error_e ret;
303
304         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
305
306         ret = table_restrictions_per_app(app_id,
307                                          __table_restrictions_per_app_cb,
308                                          builder);
309         if (ret < STC_ERROR_NONE) {
310                 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
311                 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
312                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
313                 return TRUE; //LCOV_EXCL_LINE
314         }
315
316         return_parameters = g_variant_new("(ia{sv})", STC_ERROR_NONE, builder);
317         g_variant_builder_unref(builder);
318
319         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
320         STC_DBUS_REPLY(invocation, return_parameters);
321         __STC_LOG_FUNC_EXIT__;
322         return TRUE;
323 }
324
325 gboolean handle_restriction_get_all(StcRestriction *object,
326                                     GDBusMethodInvocation *invocation,
327                                     void *user_data)
328 {
329         __STC_LOG_FUNC_ENTER__;
330         GVariantBuilder *builder = NULL;
331         GVariant *return_parameters = NULL;
332         stc_error_e ret;
333
334         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
335
336         ret = table_restrictions_foreach(__table_restrictions_foreach_app_cb,
337                                          builder);
338         if (ret < STC_ERROR_NONE) {
339                 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
340                 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
341                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
342                 return TRUE; //LCOV_EXCL_LINE
343         }
344
345         return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
346         g_variant_builder_unref(builder);
347
348         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
349         STC_DBUS_REPLY(invocation, return_parameters);
350         __STC_LOG_FUNC_EXIT__;
351         return TRUE;
352 }
353
354 gboolean handle_restriction_get_type(StcRestriction *object,
355                                       GDBusMethodInvocation *invocation,
356                                       const gchar *app_id,
357                                       int iftype,
358                                       void *user_data)
359 {
360         __STC_LOG_FUNC_ENTER__;
361         GVariant *return_parameters = NULL;
362         stc_rstn_type_e type = STC_RSTN_TYPE_UNKNOWN;
363         stc_error_e ret;
364
365         ret = table_restrictions_get_restriction_type(app_id, iftype, &type);
366         if (ret < STC_ERROR_NONE) {
367                 STC_RESTRICTION_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
368                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
369                 return TRUE;
370         }
371
372         return_parameters = g_variant_new("(ii)", STC_ERROR_NONE, type);
373         STC_DBUS_REPLY(invocation, return_parameters);
374         __STC_LOG_FUNC_EXIT__;
375         return TRUE;
376 }