4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 * @desc Entity for storing applications statistics
25 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
36 #include <sys/types.h>
43 #include "datausage-quota-processing.h"
45 #include "protocol-info.h"
47 #include "specific-trace.h"
50 static sqlite3_stmt *update_statistics_query;
51 static sqlite3_stmt *update_iface_query;
53 enum { read_until_null = -1 };
55 static void handle_on_iface(const int ifindex, resourced_option_state state)
57 _D("Handling network interface %d, %d", ifindex, state);
59 if (!update_iface_query) {
60 _E("Uninitialized statement");
63 sqlite3_bind_int(update_iface_query, 1, get_iftype(ifindex));
64 sqlite3_bind_int(update_iface_query, 2, state);
66 if (sqlite3_step(update_iface_query) != SQLITE_DONE)
67 _E("Failed to record iface state. %s",
68 sqlite3_errmsg(resourced_get_database()));
70 sqlite3_reset(update_iface_query);
73 static void handle_on_iface_up(const int ifindex)
75 handle_on_iface(ifindex, RESOURCED_OPTION_ENABLE);
78 static void handle_on_iface_down(const int ifindex)
80 handle_on_iface(ifindex, RESOURCED_OPTION_DISABLE);
83 static int init_update_statistics_query(sqlite3 *db)
87 if (update_statistics_query)
90 rc = sqlite3_prepare_v2(db,
91 "insert into statistics " \
92 "(binpath, received, sent, time_stamp, " \
93 "iftype, is_roaming, hw_net_protocol_type, ifname) " \
94 "values (?, ?, ?, ?, ?, ?, ?, ?)",
95 read_until_null, &update_statistics_query, NULL);
97 if (rc != SQLITE_OK) {
98 _E("Failed to prepare query %s\n", sqlite3_errmsg(db));
99 sqlite3_finalize(update_statistics_query);
104 static int init_update_iface_query(sqlite3 *db)
108 if (update_iface_query)
111 rc = sqlite3_prepare_v2(db,
112 "insert into iface_status " \
113 "(update_time, iftype, ifstatus) " \
114 "values (datetime('now'), ?, ?)", read_until_null,
115 &update_iface_query, NULL);
117 if (rc != SQLITE_OK) {
118 _E("Failed to prepare query %s\n", sqlite3_errmsg(db));
119 sqlite3_finalize(update_iface_query);
124 static gboolean store_application_stat(gpointer key, gpointer value,
125 gpointer __attribute((__unused__)) userdata)
127 struct application_stat *stat = (struct application_stat *)value;
128 struct classid_iftype_key *stat_key = (struct classid_iftype_key *)key;
129 time_t *last_touch_time = (time_t *)userdata;
130 resourced_hw_net_protocol_type hw_net_protocol_type =
131 get_hw_net_protocol_type(stat_key->iftype);
133 if (!update_statistics_query) {
134 _E("Uninitialized statement");
138 if (!stat->rcv_count && !stat->snd_count)
141 if (sqlite3_bind_text(update_statistics_query, 1, stat->application_id, read_until_null,
142 SQLITE_STATIC) != SQLITE_OK) {
143 _SE("Can not bind application_id: %s", stat->application_id);
146 if (sqlite3_bind_int(update_statistics_query, 2, stat->rcv_count) != SQLITE_OK) {
147 _E("Can not bind rcv_count %d:", stat->rcv_count);
150 if (sqlite3_bind_int(update_statistics_query, 3, stat->snd_count) != SQLITE_OK) {
151 _E("Can not bind snd_count: %d", stat->snd_count);
154 if (sqlite3_bind_int64(update_statistics_query, 4, (sqlite3_int64) (*last_touch_time)) !=
156 _E("Can not bind last_touch_time: %ld", *last_touch_time);
159 if (sqlite3_bind_int(update_statistics_query, 5, (int)(stat_key->iftype)) != SQLITE_OK) {
160 _E("Can not bind iftype: %d", (int)stat_key->iftype);
163 if (sqlite3_bind_int(update_statistics_query, 6, (int)(stat->is_roaming)) != SQLITE_OK) {
164 _E("Can not bind is_roaming: %d", (int)(stat->is_roaming));
167 if (sqlite3_bind_int(update_statistics_query, 7,
168 (int)hw_net_protocol_type) != SQLITE_OK) {
169 _E("Can not bind protocol_type: %d", (int)hw_net_protocol_type);
172 if (sqlite3_bind_text(update_statistics_query, 8, stat_key->ifname, read_until_null,
173 SQLITE_STATIC) != SQLITE_OK) {
174 _SE("Can not bind ifname: %s", stat_key->ifname);
178 /*we want to reuse tree*/
181 if (sqlite3_step(update_statistics_query) != SQLITE_DONE)
182 _E("Failed to record appstat. %s", sqlite3_errmsg(resourced_get_database()));
184 sqlite3_reset(update_statistics_query);
188 int store_result(struct application_stat_tree *stats, int flush_period)
194 if (current_time - stats->last_touch_time >= flush_period) {
196 pthread_rwlock_rdlock(&stats->guard);
197 WALK_TREE(stats->tree, print_appstat);
198 pthread_rwlock_unlock(&stats->guard);
200 if (init_update_statistics_query(resourced_get_database()) != SQLITE_OK) {
201 _D("Failed to initialize data usage quota statements: %s\n",
202 sqlite3_errmsg(resourced_get_database()));
203 return 0; /* Do not iterate and free results */
206 /* it's reader only, we don't modify tree, don't reduce it,
207 * due we want to reuse it in next iteration */
208 pthread_rwlock_rdlock(&stats->guard);
209 g_tree_foreach((GTree *) stats->tree,
210 store_application_stat,
211 &stats->last_touch_time);
212 pthread_rwlock_unlock(&stats->guard);
215 stats->last_touch_time = current_time;
221 void finalize_storage_stm(void)
223 sqlite3_finalize(update_statistics_query);
224 sqlite3_finalize(update_iface_query);
227 iface_callback *create_iface_storage_callback(void)
229 iface_callback *ret_arg =
230 (iface_callback *)malloc(sizeof(iface_callback));
232 if (init_update_iface_query(resourced_get_database())
234 _E("Initialization database failed\n");
236 ret_value_msg_if(!ret_arg, NULL, "Malloc of iface_callback failed\n");
237 ret_arg->handle_iface_up = handle_on_iface_up;
238 ret_arg->handle_iface_down = handle_on_iface_down;