4 * Copyright (c) 2014 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.
24 * @desc application statistics entity helper functions
32 #include "net-cls-cgroup.h"
38 static void free_app(gpointer data)
40 struct application_stat *app_stat = (struct application_stat *)data;
44 if (app_stat->application_id)
45 free(app_stat->application_id);
50 static gint compare_classid(gconstpointer a, gconstpointer b,
51 gpointer __attribute__((__unused__)) userdata)
53 const struct classid_iftype_key *a_key = (struct classid_iftype_key*)a;
54 const struct classid_iftype_key *b_key = (struct classid_iftype_key*)b;
57 ret = a_key->classid - b_key->classid;
61 ret = a_key->iftype - b_key->iftype;
65 return strcmp(a_key->ifname, b_key->ifname);
68 static void free_stat(gpointer data)
73 struct application_stat_tree *create_app_stat_tree(void)
76 struct application_stat_tree *app_stat_tree;
78 (struct application_stat_tree *) malloc
79 (sizeof(struct application_stat_tree));
81 _E("Malloc of create_app_stat_tree failed\n");
86 (GTree *)g_tree_new_full(compare_classid,
89 app_stat_tree->last_touch_time = time(0);
90 ret = pthread_rwlock_init(&app_stat_tree->guard, NULL);
92 _E("Could not initialize tree guard %s.", strerror(ret));
99 void free_app_stat_tree(struct application_stat_tree *app_stat_tree)
101 /* do not check null pointer because it makes g_tree_destroy */
102 ret_msg_if(app_stat_tree == NULL,
103 "Please provide valid app_stat_tree!");
104 g_tree_destroy((GTree *)app_stat_tree->tree);
107 void nulify_app_stat_tree(struct application_stat_tree **app_stat_tree)
109 free_app_stat_tree(*app_stat_tree);
110 free(*app_stat_tree);
111 *app_stat_tree = NULL;
114 traffic_stat_tree *create_traffic_stat_tree(void)
116 return g_tree_new_full(compare_classid, NULL, NULL, free_stat);
119 void free_traffic_stat_tree(traffic_stat_tree *tree)
121 g_tree_destroy((GTree *) tree);
124 static gboolean set_app_id(gpointer key, gpointer value,
125 void __attribute__((__unused__)) *data)
127 /* Open closed principle would be better here */
128 struct application_stat *stat = (struct application_stat *)value;
129 u_int32_t classid = ((struct classid_iftype_key*)key)->classid;
131 /* No need to request update classid table per each app entry */
132 stat->application_id = get_app_id_by_classid(classid, false);
136 static inline void identify_application(
137 struct application_stat_tree *app_stat_tree)
139 g_tree_foreach(app_stat_tree->tree, (GTraverseFunc)set_app_id, NULL);
142 static gboolean fill_incomming(gpointer key,
143 gpointer value, gpointer data)
145 struct application_stat_tree *app_tree =
146 (struct application_stat_tree *)data;
147 struct traffic_stat *in_event = (struct traffic_stat *)value;
149 struct application_stat *app_stat = NULL;
150 if (!is_allowed_ifindex(in_event->ifindex))
153 app_stat = (struct application_stat *)
154 g_tree_lookup((GTree *)app_tree->tree, key);
156 app_stat->rcv_count += in_event->bytes;
158 app_stat = g_new(struct application_stat, 1);
159 memset(app_stat, 0, sizeof(struct application_stat));
160 app_stat->rcv_count = in_event->bytes;
161 g_tree_insert((GTree *)app_tree->tree, key, app_stat);
163 app_stat->delta_rcv += in_event->bytes;
165 /*only for debug purpose*/
166 if (!app_stat->ifindex)
167 app_stat->ifindex = in_event->ifindex;
169 app_stat->is_roaming = get_roaming();
173 static gboolean fill_outgoing(gpointer key,
174 gpointer value, gpointer data)
176 struct application_stat_tree *app_tree =
177 (struct application_stat_tree *)data;
178 struct traffic_stat *out_event = (struct traffic_stat *)value;
180 struct application_stat *app_stat = (struct application_stat *)
181 g_tree_lookup((GTree *)app_tree->tree, key);
183 app_stat->snd_count += out_event->bytes;
185 app_stat = g_new(struct application_stat, 1);
186 memset(app_stat, 0, sizeof(struct application_stat));
187 app_stat->snd_count = out_event->bytes;
188 g_tree_insert((GTree *)app_tree->tree, key, app_stat);
190 app_stat->delta_snd += out_event->bytes;
192 if (!app_stat->ifindex)
193 app_stat->ifindex = out_event->ifindex;
195 if (!app_stat->is_roaming)
196 app_stat->is_roaming = get_roaming();
201 static void fill_result(traffic_stat_tree *tree_in,
202 traffic_stat_tree *tree_out,
203 struct application_stat_tree *result)
206 g_tree_foreach(tree_in, (GTraverseFunc)fill_incomming, result);
207 g_tree_foreach(tree_out, (GTraverseFunc)fill_outgoing, result);
210 resourced_ret_c prepare_application_stat(traffic_stat_tree *tree_in,
211 traffic_stat_tree *tree_out,
212 struct application_stat_tree *result,
213 volatile struct daemon_opts *opts)
215 fill_result(tree_in, tree_out, result);
216 identify_application(result);
218 return RESOURCED_ERROR_NONE;