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.
17 #include "stc-monitor.h"
18 #include "stc-default-connection.h"
20 #define CONNMAN_SERVICE "net.connman"
21 #define CONNMAN_PATH "/net/connman"
23 #define CONNMAN_MANAGER_PATH "/"
24 #define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
25 #define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
27 #define CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/cellular_"
28 #define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/wifi_"
29 #define CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/ethernet_"
30 #define CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/bluetooth_"
32 #define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged"
34 default_connection_s g_default_connection;
35 guint g_default_connection_sub_id = 0;
37 static void __print_default_connection_info(void)
39 STC_LOGI("============= default connection info ============");
40 STC_LOGI("path [%s]", g_default_connection.path);
41 STC_LOGI("type [%d]", g_default_connection.type);
42 STC_LOGI("ifname [%s]", g_default_connection.ifname);
43 STC_LOGI("roaming [%u]", g_default_connection.roaming ? TRUE : FALSE);
44 STC_LOGI("==================================================");
47 static void __reset_default_connection_data(void)
49 FREE(g_default_connection.path);
50 FREE(g_default_connection.ifname);
51 g_default_connection.type = STC_IFACE_UNKNOWN;
52 g_default_connection.roaming = FALSE;
55 static gboolean __is_cellular_internet_profile(const char *profile)
57 const char internet_suffix[] = "_1";
62 if (g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX)
64 char *suffix = strrchr(profile, '_');
65 if (g_strcmp0(suffix, internet_suffix) == 0)
72 static gboolean __is_cellular_profile(const char *profile)
77 return g_str_has_prefix(profile,
78 CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX);
81 static gboolean __is_wifi_profile(const char *profile)
86 return g_str_has_prefix(profile, CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
89 static gboolean __is_ethernet_profile(const char *profile)
94 return g_str_has_prefix(profile,
95 CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX);
98 static gboolean __is_bluetooth_profile(const char *profile)
103 return g_str_has_prefix(profile,
104 CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX);
107 static gboolean __is_connected(GVariantIter *array)
109 gboolean is_connected = FALSE;
110 GVariant *variant = NULL;
113 while (g_variant_iter_loop(array, "{sv}", &key, &variant)) {
114 if (g_strcmp0(key, "State") != 0)
117 if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
118 const gchar *state = NULL;
120 state = g_variant_get_string(variant, NULL);
121 if (g_strcmp0(state, "ready") == 0 ||
122 g_strcmp0(state, "online") == 0)
127 g_variant_unref(variant);
134 static void __get_default_connection_info(GDBusConnection *connection,
135 const char *object_path)
137 GVariant *message = NULL;
138 GVariantIter *iter = NULL;
139 GVariant *variant = NULL;
142 if (object_path == NULL) {
143 STC_LOGE("Object path is NULL");
147 message = stc_manager_gdbus_call_sync(connection,
150 CONNMAN_SERVICE_INTERFACE,
151 "GetProperties", NULL);
152 if (message == NULL) {
153 STC_LOGE("Failed to get services informations");
157 g_variant_get(message, "(a{sv})", &iter);
159 STC_LOGE("Profile %s doesn't exist", object_path);
163 while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
164 if (g_strcmp0(key, "Ethernet") == 0) {
165 GVariantIter *iter1 = NULL;
166 GVariant *variant1 = NULL;
169 g_variant_get(variant, "a{sv}", &iter1);
173 while (g_variant_iter_loop(iter1, "{sv}", &key1,
175 if (g_strcmp0(key1, "Interface") == 0) {
177 g_variant_get_string(variant1,
179 g_default_connection.ifname =
184 g_variant_iter_free(iter1);
186 } else if (g_strcmp0(key, "Roaming") == 0) {
187 gboolean roaming = 0;
189 if (g_variant_is_of_type(variant,
190 G_VARIANT_TYPE_BOOLEAN)) {
191 roaming = g_variant_get_boolean(variant);
192 g_default_connection.roaming = roaming;
199 g_variant_iter_free(iter);
202 g_variant_unref(message);
207 static stc_error_e __get_default_profile(GDBusConnection *connection)
209 GVariant *message = NULL;
210 GVariantIter *iter = NULL;
214 message = stc_manager_gdbus_call_sync(connection,
216 CONNMAN_MANAGER_PATH,
217 CONNMAN_MANAGER_INTERFACE,
218 "GetServices", NULL);
219 if (message == NULL) {
220 STC_LOGE("Failed to get profiles");
221 return STC_ERROR_FAIL;
224 g_variant_get(message, "(a(oa{sv}))", &iter);
225 while (g_variant_iter_loop(iter, "(oa{sv})", &object_path, &next)) {
226 if (object_path == NULL)
229 if (__is_cellular_profile(object_path) &&
230 !__is_cellular_internet_profile(object_path))
233 if (__is_connected(next) == TRUE) {
234 /* reset old default connection data */
235 FREE(g_default_connection.path);
236 FREE(g_default_connection.ifname);
237 g_default_connection.type = STC_IFACE_UNKNOWN;
238 g_default_connection.roaming = FALSE;
240 g_default_connection.path = g_strdup(object_path);
242 g_variant_iter_free(next);
247 g_variant_iter_free(iter);
248 g_variant_unref(message);
250 if (__is_cellular_profile(g_default_connection.path))
251 g_default_connection.type = STC_IFACE_DATACALL;
252 else if (__is_wifi_profile(g_default_connection.path))
253 g_default_connection.type = STC_IFACE_WIFI;
254 else if (__is_ethernet_profile(g_default_connection.path))
255 g_default_connection.type = STC_IFACE_WIRED;
256 else if (__is_bluetooth_profile(g_default_connection.path))
257 g_default_connection.type = STC_IFACE_BLUETOOTH;
259 g_default_connection.type = STC_IFACE_UNKNOWN;
261 __get_default_connection_info(connection, g_default_connection.path);
263 __print_default_connection_info();
265 stc_monitor_update_rstn_by_default_connection(&g_default_connection);
267 return STC_ERROR_NONE;
270 static void _service_signal_cb(GDBusConnection *conn,
271 const gchar *name, const gchar *path,
272 const gchar *interface, const gchar *sig,
273 GVariant *param, gpointer user_data)
275 gchar *sigvalue = NULL;
276 GVariant *variant = NULL;
277 stc_s *stc = (stc_s *)stc_get_manager();
278 ret_msg_if(stc == NULL, "failed to get stc data");
280 if (path == NULL || param == NULL)
283 g_variant_get(param, "(sv)", &sigvalue, &variant);
284 if (sigvalue == NULL)
287 if (g_strcmp0(sig, CONNMAN_SIGNAL_PROPERTY_CHANGED) != 0)
290 if (g_strcmp0(sigvalue, "State") == 0 &&
291 g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
292 const gchar *state = NULL;
294 state = g_variant_get_string(variant, NULL);
295 if (g_strcmp0(state, "ready") == 0 ||
296 g_strcmp0(state, "online") == 0) {
297 if (g_strcmp0(g_default_connection.path, path)) {
298 __reset_default_connection_data();
299 __get_default_profile(stc->connection);
302 if (g_strcmp0(g_default_connection.path, path) == 0) {
303 __reset_default_connection_data();
304 __get_default_profile(stc->connection);
307 } else if (g_strcmp0(sigvalue, "Roaming") == 0) {
308 if (g_strcmp0(g_default_connection.path, path) == 0) {
309 gboolean roaming = 0;
311 if (g_variant_is_of_type(variant,
312 G_VARIANT_TYPE_BOOLEAN)) {
313 roaming = g_variant_get_boolean(variant);
314 g_default_connection.roaming = roaming;
325 g_variant_unref(variant);
330 stc_error_e stc_default_connection_monitor_init(stc_s *stc)
332 ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
334 __get_default_profile(stc->connection);
335 g_default_connection_sub_id =
336 stc_manager_gdbus_subscribe_signal(stc->connection,
338 CONNMAN_SERVICE_INTERFACE,
339 CONNMAN_SIGNAL_PROPERTY_CHANGED,
341 G_DBUS_SIGNAL_FLAGS_NONE,
345 STC_LOGI("Successfully subscribed connman [%s] signal", CONNMAN_SIGNAL_PROPERTY_CHANGED);
346 return STC_ERROR_NONE;
349 stc_error_e stc_default_connection_monitor_deinit(stc_s *stc)
351 ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
353 stc_manager_gdbus_unsubscribe_signal(stc->connection,
354 g_default_connection_sub_id);
355 FREE(g_default_connection.path);
356 FREE(g_default_connection.ifname);
357 return STC_ERROR_NONE;
360 stc_iface_type_e stc_default_connection_get_type(void)
362 return g_default_connection.type;
365 gchar *stc_default_connection_get_ifname(void)
367 return g_strdup(g_default_connection.ifname);
370 gboolean stc_default_connection_get_roaming(void)
372 return g_default_connection.roaming;
375 default_connection_s *stc_get_default_connection(void)
377 return &g_default_connection;