Add initial source codes for gtest
[platform/core/connectivity/stc-manager.git] / src / stc-statistics.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-statistics.h"
19 #include "stc-statistics.h"
20 #include "stc-manager-gdbus.h"
21
22 #define STATISTICS_DBUS_ERROR_NAME "net.stc.statistics.Error.Failed"
23
24 #define STC_DBUS_REPLY(invocation, parameters) \
25         g_dbus_method_invocation_return_value((invocation), parameters);
26
27 #define STC_STATISTICS_DBUS_REPLY_ERROR(invocation, err_num) \
28         g_dbus_method_invocation_return_dbus_error((invocation), \
29                                                    STATISTICS_DBUS_ERROR_NAME, \
30                                                    stc_err_strs[-(err_num)])
31
32 static const gchar *stc_err_strs[] = {
33         "ERROR_NONE",
34         "FAIL",
35         "DB_FAILED",
36         "OUT_OF_MEMORY",
37         "INVALID_PARAMETER",
38         "NO_DATA",
39         "UNINITIALIZED",
40         "NOTIMPL"
41 };
42
43 void __stc_statistics_print_app_info(const table_statistics_info *info)
44 {
45         if (!info)
46                 return;
47
48         STC_LOGD("========== App data (Statistics) ==========");
49         STC_LOGD("app_id   : [%s]", info->app_id ? info->app_id : "NULL");
50         STC_LOGD("ifname   : [%s]", info->ifname ? info->ifname : "NULL");
51         STC_LOGD("Sent     : [%lld] bytes", info->cnt.out_bytes);
52         STC_LOGD("Received : [%lld] bytes", info->cnt.in_bytes);
53         STC_LOGD("===========================================");
54 }
55
56 void __stc_extract_select_rule(const char *key, GVariant *value,
57                                void *user_data)
58 {
59         __STC_LOG_FUNC_ENTER__;
60
61         table_statistics_select_rule *rule =
62                 (table_statistics_select_rule *) user_data;
63         if (rule == NULL) {
64                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
65                 return; //LCOV_EXCL_LINE
66         }
67
68         if (!g_strcmp0(key, "from")) {
69                 rule->from = g_variant_get_uint64(value);
70                 STC_LOGD("from: [%lu]", rule->from);
71
72         } else if (!g_strcmp0(key, "to")) {
73                 rule->to = g_variant_get_uint64(value);
74                 STC_LOGD("to: [%lu]", rule->to);
75
76         } else if (!g_strcmp0(key, "iftype")) {
77                 rule->iftype = g_variant_get_uint16(value);
78                 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
79
80         } else {
81                 STC_LOGD("Unknown select rule"); //LCOV_EXCL_LINE
82         }
83
84         __STC_LOG_FUNC_EXIT__;
85 }
86
87 void __stc_extract_reset_rule(const char *key, GVariant *value,
88                                void *user_data)
89 {
90         __STC_LOG_FUNC_ENTER__;
91
92         table_statistics_reset_rule *rule =
93                 (table_statistics_reset_rule *) user_data;
94         if (rule == NULL) {
95                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
96                 return; //LCOV_EXCL_LINE
97         }
98
99         if (!g_strcmp0(key, "app_id")) {
100                 gsize len = 0;
101                 rule->app_id = g_variant_dup_string(value, &len);
102                 STC_LOGD("app_id: [%s]", rule->app_id);
103
104         } else if (!g_strcmp0(key, "subscriber_id")) {
105                 gsize len = 0;
106                 rule->subscriber_id = g_variant_dup_string(value, &len);
107                 STC_LOGD("subscriber_id: [%s]", rule->subscriber_id);
108
109         } else if (!g_strcmp0(key, "iftype")) {
110                 rule->iftype = g_variant_get_uint16(value);
111                 STC_LOGD("iftype: [%u]", (unsigned int) rule->iftype);
112
113         } else if (!g_strcmp0(key, "from")) {
114                 if (!(rule->interval)) {
115                         rule->interval = MALLOC0(stc_db_tm_interval_s, 1); //LCOV_EXCL_LINE
116                         if (!(rule->interval)) { //LCOV_EXCL_LINE
117                                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
118                                 return; //LCOV_EXCL_LINE
119                         }
120                 }
121
122                 rule->interval->from = g_variant_get_uint64(value);
123                 STC_LOGD("from: [%lu]", rule->interval->from);
124
125         } else if (!g_strcmp0(key, "to")) {
126                 if (!(rule->interval)) {
127                         rule->interval = MALLOC0(stc_db_tm_interval_s, 1); //LCOV_EXCL_LINE
128                         if (!(rule->interval)) { //LCOV_EXCL_LINE
129                                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
130                                 return; //LCOV_EXCL_LINE
131                         }
132                 }
133
134                 rule->interval->to = g_variant_get_uint64(value);
135                 STC_LOGD("to: [%lu]", rule->interval->to);
136
137         } else {
138                 STC_LOGD("Unknown reset rule"); //LCOV_EXCL_LINE
139         }
140
141         __STC_LOG_FUNC_EXIT__;
142 }
143
144 void __stc_statistics_app_info_builder_add(GVariantBuilder *builder,
145                                            const table_statistics_info *info)
146 {
147         __STC_LOG_FUNC_ENTER__;
148
149         if (!builder || !info) {
150                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
151                 return; //LCOV_EXCL_LINE
152         }
153
154         if (info->app_id)
155                 g_variant_builder_add(builder, "{sv}", "app_id",
156                                       g_variant_new_string(info->app_id));
157
158         if (info->ifname)
159                 g_variant_builder_add(builder, "{sv}", "ifname",
160                                       g_variant_new_string(info->ifname));
161
162         g_variant_builder_add(builder, "{sv}", "subscriber_id",
163                               g_variant_new_string(info->subscriber_id));
164
165         g_variant_builder_add(builder, "{sv}", "iftype",
166                               g_variant_new_uint16(info->iftype));
167
168         if (info->interval != NULL) {
169                 g_variant_builder_add(builder, "{sv}", "interval_to",
170                                       g_variant_new_uint64(info->interval->to));
171
172                 g_variant_builder_add(builder, "{sv}", "interval_from",
173                                       g_variant_new_uint64(info->interval->from));
174         }
175
176         g_variant_builder_add(builder, "{sv}", "cnt_out_bytes",
177                               g_variant_new_int64(info->cnt.out_bytes));
178
179         g_variant_builder_add(builder, "{sv}", "cnt_in_bytes",
180                               g_variant_new_int64(info->cnt.in_bytes));
181
182         g_variant_builder_add(builder, "{sv}", "roaming",
183                               g_variant_new_uint16(info->roaming));
184
185         g_variant_builder_add(builder, "{sv}", "hw_net_protocol_type",
186                               g_variant_new_uint16(info->hw_net_protocol_type));
187
188         g_variant_builder_add(builder, "{sv}", "ground",
189                               g_variant_new_uint16(info->ground));
190
191         __STC_LOG_FUNC_EXIT__;
192 }
193
194 stc_cb_ret_e __table_statistics_foreach_app_cb(const table_statistics_info *info,
195                                                void *user_data)
196 {
197         __STC_LOG_FUNC_ENTER__;
198         GVariantBuilder *builder = (GVariantBuilder *)user_data;
199         GVariantBuilder sub_builder;
200
201         if (!info || !builder) {
202                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
203                 return STC_CANCEL; //LCOV_EXCL_LINE
204         }
205
206         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
207         __stc_statistics_app_info_builder_add(&sub_builder, info);
208         __stc_statistics_print_app_info(info);
209         g_variant_builder_add_value(builder,
210                                     g_variant_builder_end(&sub_builder));
211
212         __STC_LOG_FUNC_EXIT__;
213         return STC_CONTINUE;
214 }
215
216 stc_cb_ret_e __table_statistics_per_app_cb(const table_statistics_info *info,
217                                            void *user_data)
218 {
219         __STC_LOG_FUNC_ENTER__;
220         GVariantBuilder *builder = (GVariantBuilder *)user_data;
221         GVariantBuilder sub_builder;
222
223         if (!info || !builder) {
224                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
225                 return STC_CANCEL; //LCOV_EXCL_LINE
226         }
227
228         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
229         __stc_statistics_app_info_builder_add(&sub_builder, info);
230         __stc_statistics_print_app_info(info);
231         g_variant_builder_add_value(builder,
232                                     g_variant_builder_end(&sub_builder));
233
234         __STC_LOG_FUNC_EXIT__;
235         return STC_CONTINUE;
236 }
237
238 gboolean handle_statistics_get_all(StcStatistics *object,
239                                    GDBusMethodInvocation *invocation,
240                                    GVariant *select_rule,
241                                    void *user_data)
242 {
243         __STC_LOG_FUNC_ENTER__;
244         table_statistics_select_rule rule = {0, };
245         const time_t cur_time = time(0);
246         const time_t epoch = 0;
247         GVariantBuilder *builder = NULL;
248         GVariant *return_parameters = NULL;
249         stc_error_e ret;
250
251         /* Total statistics since epoch */
252         rule.from = epoch;
253         rule.to = cur_time;
254         rule.iftype = STC_IFACE_ALL;
255
256         if (select_rule != NULL) {
257                 DEBUG_GDBUS_VARIANT("Selection rule: ", select_rule);
258                 GVariantIter *iter = NULL;
259
260                 g_variant_get(select_rule, "a{sv}", &iter);
261                 if (iter != NULL) {
262                         stc_manager_gdbus_dict_foreach(iter,
263                                                        __stc_extract_select_rule,
264                                                        &rule);
265                         g_variant_iter_free(iter);
266                 }
267         } else {
268                 STC_LOGD("No selection rule, using default selection rule."); //LCOV_EXCL_LINE
269         }
270
271         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
272
273         ret = table_statistics_foreach_app(&rule,
274                                            __table_statistics_foreach_app_cb,
275                                            builder);
276         if (ret < STC_ERROR_NONE) {
277                 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
278                 STC_STATISTICS_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
279                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
280                 return TRUE; //LCOV_EXCL_LINE
281         }
282
283         return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
284         g_variant_builder_unref(builder);
285
286         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
287         STC_DBUS_REPLY(invocation, return_parameters);
288
289         __STC_LOG_FUNC_EXIT__;
290         return TRUE;
291 }
292
293 gboolean handle_statistics_init(StcStatistics *object,
294                                GDBusMethodInvocation *invocation)
295 {
296         __STC_LOG_FUNC_ENTER__;
297
298         STC_LOGI("stc statistics initialized");
299         stc_statistics_complete_init(object, invocation);
300
301         __STC_LOG_FUNC_EXIT__;
302         return TRUE;
303 }
304
305 gboolean handle_statistics_get(StcStatistics *object,
306                                GDBusMethodInvocation *invocation,
307                                const gchar *app_id,
308                                GVariant *select_rule,
309                                void *user_data)
310 {
311         __STC_LOG_FUNC_ENTER__;
312         table_statistics_select_rule rule = {0, };
313         const time_t cur_time = time(0);
314         const time_t epoch = 0;
315         GVariantBuilder *builder = NULL;
316         GVariant *return_parameters = NULL;
317         stc_error_e ret;
318
319         /* Total statistics since epoch */
320         rule.from = epoch;
321         rule.to = cur_time;
322         rule.iftype = STC_IFACE_ALL;
323
324         if (select_rule != NULL) {
325                 DEBUG_GDBUS_VARIANT("Selection rule: ", select_rule);
326                 GVariantIter *iter = NULL;
327
328                 g_variant_get(select_rule, "a{sv}", &iter);
329                 if (iter != NULL) {
330                         stc_manager_gdbus_dict_foreach(iter,
331                                                        __stc_extract_select_rule,
332                                                        &rule);
333                         g_variant_iter_free(iter);
334                 }
335         } else {
336                 STC_LOGD("No selection rule, using default selection rule."); //LCOV_EXCL_LINE
337         }
338
339         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
340
341         ret = table_statistics_per_app(app_id, &rule,
342                                        __table_statistics_per_app_cb,
343                                        builder);
344         if (ret < STC_ERROR_NONE) {
345                 g_variant_builder_unref(builder); //LCOV_EXCL_LINE
346                 STC_STATISTICS_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
347                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
348                 return TRUE; //LCOV_EXCL_LINE
349         }
350
351         return_parameters = g_variant_new("(iaa{sv})", STC_ERROR_NONE, builder);
352         g_variant_builder_unref(builder);
353
354         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
355         STC_DBUS_REPLY(invocation, return_parameters);
356
357         __STC_LOG_FUNC_EXIT__;
358         return TRUE;
359 }
360
361 gboolean handle_statistics_reset(StcStatistics *object,
362                                  GDBusMethodInvocation *invocation,
363                                  GVariant *reset_rule,
364                                  void *user_data)
365 {
366         __STC_LOG_FUNC_ENTER__;
367         table_statistics_reset_rule rule = {0, };
368         GVariant *return_parameters = NULL;
369         stc_error_e ret;
370
371         if (reset_rule != NULL) {
372                 DEBUG_GDBUS_VARIANT("Selection rule: ", reset_rule);
373                 GVariantIter *iter = NULL;
374
375                 g_variant_get(reset_rule, "a{sv}", &iter);
376                 if (iter != NULL) {
377                         stc_manager_gdbus_dict_foreach(iter,
378                                                        __stc_extract_reset_rule,
379                                                        &rule);
380                         g_variant_iter_free(iter);
381                 }
382         } else {
383                 STC_LOGD("No selection rule, using default selection rule."); //LCOV_EXCL_LINE
384         }
385
386         ret = table_statistics_reset(&rule);
387         if (ret < STC_ERROR_NONE) {
388                 STC_STATISTICS_DBUS_REPLY_ERROR(invocation, ret); //LCOV_EXCL_LINE
389                 goto handle_error; //LCOV_EXCL_LINE
390         }
391
392         return_parameters = g_variant_new("(i)", STC_ERROR_NONE);
393
394         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
395         STC_DBUS_REPLY(invocation, return_parameters);
396
397 handle_error:
398         FREE(rule.app_id);
399         FREE(rule.subscriber_id);
400         FREE(rule.interval);
401         __STC_LOG_FUNC_EXIT__;
402         return TRUE;
403 }