2 * Smart bonding service client
4 * Copyright (c) 2013 - 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 #include <vconf-keys.h>
26 #include "multirat_SB_http.h"
27 #include "smartbonding-client.h"
29 #define DBUS_REPLY_TIMEOUT (120 * 1000)
30 #define SMBD_SERVICE_DBUS "net.smartbonding"
31 #define SMBD_PATH_DBUS "/org/tizen/smartbonding"
32 #define SMBD_SERVICE_INTERFACE "org.tizen.smartbonding"
33 #define SMBD_SIGNAL_PROPERTYCHANGED "PropertyChanged"
34 #define SMBD_SIGNAL_USERRESPONSE "UserResponse"
35 #define SMBD_SIGNAL_VALUE_CELLULAR "cellular_device_info"
36 #define SMBD_SIGNAL_VALUE_WIFI "wifi_device_info"
37 #define SMBD_SIGNAL_VALUE_SMARTBONDING "smartbonding"
38 #define SMBD_SIGNAL_VALUE_DATA "data"
39 #define SMBD_SIGNAL_VALUE_USERRESPONSE "user_response"
40 #define VCONF_SMART_BONDING_POLICY "file/private/wifi/network_bonding"
43 SMART_BONDING_WIFI_ONLY = 0x00,
44 SMART_BONDING_SPEED_PRIORITIZED = 0x01,
45 } SMART_BONDING_TYPES;
47 struct gdbus_connection_data {
48 GDBusConnection *connection;
50 GCancellable *cancellable;
53 struct _smartbonding_cb_s {
55 void *action_user_data;
64 static GSList *handle_list = NULL;
65 static struct _smartbonding_cb_s smartbonding_callbacks = { 0, };
66 static struct gdbus_connection_data gdbus_conn = { NULL, 0, NULL };
67 static guint gdbus_conn_sub_id_smbd_cellular = 0;
68 //static guint gdbus_conn_sub_id_smbd_wifi = 0;
69 static guint gdbus_conn_sub_id_smbd_smartbonding = 0;
70 static guint gdbus_conn_sub_id_smbd_user = 0;
71 static smbd_cellular_profile_info_t smbd_cellular_profile_info;
73 static GDBusConnection *_dbus_get_gdbus_conn(void)
75 return gdbus_conn.connection;
78 void get_proxy_ip_port(char *proxy_ip, int *proxy_port)
80 if(strcmp(smbd_cellular_profile_info.proxy,"") == 0)
86 temp = strchr(smbd_cellular_profile_info.proxy,':');
89 len = (int)(temp - smbd_cellular_profile_info.proxy);
90 memcpy(proxy_ip, smbd_cellular_profile_info.proxy, len);
91 *proxy_port = atoi(smbd_cellular_profile_info.proxy + len + 1);
93 SECURE_DB_INFO("Proxy IP %s", proxy_ip);
94 SECURE_DB_INFO("Proxy PORT %d", *proxy_port);
100 void get_dns_ip(char *dns_1, char *dns_2)
102 if((strcmp(smbd_cellular_profile_info.dns_1,"")))
104 memcpy(dns_1,smbd_cellular_profile_info.dns_1, strlen(smbd_cellular_profile_info.dns_1));
105 SECURE_DB_INFO("DNS %s", smbd_cellular_profile_info.dns_1);
107 if((strcmp(smbd_cellular_profile_info.dns_2,"")))
109 memcpy(dns_2,smbd_cellular_profile_info.dns_2, strlen(smbd_cellular_profile_info.dns_2));
110 SECURE_DB_INFO("DNS %s", smbd_cellular_profile_info.dns_2);
115 static GCancellable *_dbus_get_gdbus_cancellable(void)
117 return gdbus_conn.cancellable;
120 static guint32 _handle_remove_with_user_data(void *data)
122 GSList *list = handle_list;
123 guint32 handle_id = 0;
126 event_info_t *temp = (event_info_t *)list->data;
127 if (temp->user_data == data) {
128 TIZEN_LOGD("Removed the handle - [%d] from the list", temp->handle);
130 /* Get the handle id to pass the same to daemon for cleanup */
131 handle_id = temp->handle;
132 handle_list = g_slist_remove(handle_list, temp);
137 list = g_slist_next(list);
143 static void _handle_remove_post_event_send(guint handle, gboolean user_option)
145 GSList *list = handle_list;
146 smbd_event_info_t event_info = { 0, };
149 event_info_t *temp = (event_info_t *)list->data;
150 if (temp->handle != handle) {
151 list = g_slist_next(list);
155 if (temp->cb != NULL) {
157 TIZEN_LOGD("Sending SMBD_EVENT_USER_OPTION_OK");
159 event_info.Event = SMBD_EVENT_USER_OPTION_OK;
160 event_info.Error = SMBD_ERR_NONE;
162 temp->cb(event_info, temp->user_data);
164 TIZEN_LOGD("Sending SMBD_EVENT_USER_OPTION_CANCEL");
166 event_info.Event = SMBD_EVENT_USER_OPTION_CANCEL;
167 event_info.Error = SMBD_ERR_NONE;
169 temp->cb(event_info, temp->user_data);
177 static int __error_string_to_enum(const char *error)
179 TIZEN_LOGD("Passed error value [%s]\n", error);
182 return SMBD_ERR_UNKNOWN;
184 else if (NULL != strstr(error, ".PermissionDenied"))
185 return SMBD_ERR_PERMISSION_DENIED;
186 else if (NULL != strstr(error, ".InProgress"))
187 return SMBD_ERR_IN_PROGRESS;
188 return SMBD_ERR_UNKNOWN;
191 static void __dbus_reply(GObject *source_object, GAsyncResult *res,
194 GDBusConnection *conn = NULL;
195 GError *error = NULL;
196 smbd_err_t Error = SMBD_ERR_NONE;
197 //GVariant *dbus_result;
199 TIZEN_LOGD("DBus reply callback\n");
201 conn = G_DBUS_CONNECTION (source_object);
202 //dbus_result = g_dbus_connection_call_finish(conn, res, &error);
203 g_dbus_connection_call_finish(conn, res, &error);
205 TIZEN_LOGD("Smartbonding action failed. Error Msg [%s]\n", error->message);
206 Error = __error_string_to_enum(error->message);
210 if (Error != SMBD_ERR_NONE) {
211 TIZEN_LOGD("Smartbonding action failed. Error [%d]\n", Error);
213 TIZEN_LOGD("Smartbonding action success.");
217 static int __invoke_dbus_method_nonblock(const char *dest, const char *path,
218 char *interface_name, char *method, GVariant *params,
219 GAsyncReadyCallback notify_func)
221 GDBusConnection *connection;
223 TIZEN_LOGD("Sending dbus request");
224 connection = _dbus_get_gdbus_conn();
225 if (connection == NULL) {
226 TIZEN_LOGD("GDBusconnection is NULL!!\n");
227 return SMBD_ERR_UNKNOWN;
230 g_dbus_connection_call(connection,
237 G_DBUS_CALL_FLAGS_NONE,
239 _dbus_get_gdbus_cancellable(),
240 (GAsyncReadyCallback) notify_func,
243 return SMBD_ERR_NONE;
246 static GVariant *__invoke_dbus_method(const char *dest, const char *path,
247 char *interface_name, char *method, GVariant *params,
250 GError *error = NULL;
251 GVariant *reply = NULL;
252 *dbus_error = SMBD_ERR_NONE;
253 GDBusConnection *connection;
255 connection = _dbus_get_gdbus_conn();
256 if (connection == NULL) {
257 TIZEN_LOGD("GDBusconnection is NULL\n");
259 *dbus_error = SMBD_ERR_UNKNOWN;
263 reply = g_dbus_connection_call_sync(connection,
270 G_DBUS_CALL_FLAGS_NONE,
272 _dbus_get_gdbus_cancellable(),
276 TIZEN_LOGD("g_dbus_connection_call_sync() failed."
278 error->code, error->message);
281 TIZEN_LOGD("g_dbus_connection_call_sync() failed.\n");
284 *dbus_error = SMBD_ERR_UNKNOWN;
292 static int __dbus_create_gdbus_call(void)
294 GError *error = NULL;
296 if (gdbus_conn.connection != NULL) {
297 TIZEN_LOGD("Already connection exists");
298 return SMBD_ERR_UNKNOWN;
303 gdbus_conn.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
304 if (gdbus_conn.connection == NULL) {
305 TIZEN_LOGD("Failed to connect to the D-BUS daemon: [%s]\n", error->message);
307 return SMBD_ERR_UNKNOWN;
310 gdbus_conn.cancellable = g_cancellable_new();
312 return SMBD_ERR_NONE;
315 static int __dbus_close_gdbus_call(void)
317 g_cancellable_cancel(gdbus_conn.cancellable);
318 g_object_unref(gdbus_conn.cancellable);
319 gdbus_conn.cancellable = NULL;
321 if (gdbus_conn.conn_ref_count < 1) {
322 /* TODO: Use later. TIZEN_LOGD("There is no pending call\n"); */
324 g_object_unref(gdbus_conn.connection);
325 gdbus_conn.connection = NULL;
327 /* TIZEN_LOGD("There are %d pending calls, waiting to be cleared\n",
328 gdbus_conn.conn_ref_count); */
330 g_object_unref(gdbus_conn.connection);
333 return SMBD_ERR_NONE;
336 static void __dbus_smbd_cellular_signal_filter(GDBusConnection *conn,
337 const gchar *name, const gchar *path, const gchar *interface,
338 const gchar *sig, GVariant *param, gpointer user_data)
340 const char *key = NULL;
343 GVariant *var = NULL;
344 GVariantIter *iter = NULL;
346 TIZEN_LOGD("Signal PropertyChanged:cellular_device_info received");
347 if (g_strcmp0(sig, SMBD_SIGNAL_PROPERTYCHANGED) == 0) {
348 g_variant_get(param, "(sa{ss})", &key, &iter);
349 TIZEN_LOGD("signal - [%s] key - [%s]", sig, key);
351 if (g_strcmp0(key, SMBD_SIGNAL_VALUE_CELLULAR) == 0) {
352 while ((var = g_variant_iter_next_value(iter))) {
353 g_variant_get(var, "{ss}", &field, &value);
354 SECURE_DB_INFO("field - [%s] value [%s]", field, value);
355 if(strncmp(field,"proxy",5) == 0)
356 memcpy(smbd_cellular_profile_info.proxy,value,strlen(value));
357 else if(strncmp(field,"dns1",4) == 0)
358 memcpy(smbd_cellular_profile_info.dns_1,value,strlen(value));
359 else if(strncmp(field,"dns2",4) == 0)
360 memcpy(smbd_cellular_profile_info.dns_2,value,strlen(value));
363 g_variant_unref(var);
366 /* ToDo: Need to send the event */
369 g_free((gchar *)key);
373 static void __dbus_smbd_wifi_signal_filter(GDBusConnection *conn,
374 const gchar *name, const gchar *path, const gchar *interface,
375 const gchar *sig, GVariant *param, gpointer user_data)
377 const char *key = NULL;
378 const char *ipaddr = NULL;
379 GVariant *var = NULL;
381 smbd_event_info_t event_info = { 0, };
383 TIZEN_LOGD("Signal PropertyChanged:wifi_device_info received");
384 if (g_strcmp0(sig, SMBD_SIGNAL_PROPERTYCHANGED) == 0) {
385 g_variant_get(param, "(sv)", &key, &var);
386 TIZEN_LOGD("signal - [%s] key - [%s]", sig, key);
388 if (g_strcmp0(key, SMBD_SIGNAL_VALUE_WIFI) == 0) {
389 g_variant_get(var, "s", &ipaddr);
390 TIZEN_LOGD("value - [%s]", ipaddr);
392 TIZEN_LOGD("Sending SMBD_EVENT_WIFI_INFO");
394 event_info.Event = SMBD_EVENT_WIFI_INFO;
395 event_info.Error = SMBD_ERR_NONE;
396 event_info.EventData = (void *)ipaddr;
398 if (smartbonding_callbacks.cb != NULL) {
399 smartbonding_callbacks.cb(event_info, NULL);
402 g_free((gchar *)ipaddr);
405 g_free((gchar *)key);
407 g_variant_unref(var);
411 static void __dbus_smbd_smartbonding_signal_filter(GDBusConnection *conn,
412 const gchar *name, const gchar *path, const gchar *interface,
413 const gchar *sig, GVariant *param, gpointer user_data)
415 const char *key = NULL;
416 gboolean smartbonding = FALSE;
417 GVariant *var = NULL;
418 smbd_event_info_t event_info = { 0, };
420 TIZEN_LOGD("Signal PropertyChanged:smartbonding received");
421 if (g_strcmp0(sig, SMBD_SIGNAL_PROPERTYCHANGED) == 0) {
422 g_variant_get(param, "(sv)", &key, &var);
423 TIZEN_LOGD("signal - [%s] key - [%s]", sig, key);
425 if (g_strcmp0(key, SMBD_SIGNAL_VALUE_SMARTBONDING) == 0) {
426 g_variant_get(var, "b", &smartbonding);
427 TIZEN_LOGD("value - [%d]", smartbonding);
429 TIZEN_LOGD("Sending SMBD_EVENT_SMARTBONDING_STATUS");
431 event_info.Event = SMBD_EVENT_SMARTBONDING_STATUS;
432 event_info.Error = SMBD_ERR_NONE;
433 event_info.EventData = (void *)smartbonding;
435 if (smartbonding_callbacks.cb != NULL) {
436 smartbonding_callbacks.cb(event_info, NULL);
440 g_free((gchar *)key);
442 g_variant_unref(var);
446 static void __dbus_smbd_user_signal_filter(GDBusConnection *conn,
447 const gchar *name, const gchar *path, const gchar *interface,
448 const gchar *sig, GVariant *param, gpointer user_data)
450 const char *key = NULL;
451 gint32 user_option = 0;
453 //GVariant *var = NULL;
455 TIZEN_LOGD("Signal UserResponse received");
456 if (g_strcmp0(sig, SMBD_SIGNAL_USERRESPONSE) == 0) {
457 g_variant_get(param, "(s(iu))", &key, &user_option, &handle);
458 TIZEN_LOGD("signal - [%s] key - [%s]", sig, key);
459 TIZEN_LOGD("user_option - [%d] handle - [%d]", user_option, handle);
461 _handle_remove_post_event_send((guint)handle, user_option);
463 g_free((gchar *)key);
465 // g_variant_unref(var);
469 static int __dbus_register_signal(void)
471 GDBusConnection *connection = _dbus_get_gdbus_conn();;
472 smbd_err_t Error = SMBD_ERR_NONE;
474 gdbus_conn_sub_id_smbd_cellular = g_dbus_connection_signal_subscribe(
477 SMBD_SERVICE_INTERFACE,
478 SMBD_SIGNAL_PROPERTYCHANGED,
480 SMBD_SIGNAL_VALUE_CELLULAR,
481 G_DBUS_SIGNAL_FLAGS_NONE,
482 __dbus_smbd_cellular_signal_filter,
486 gdbus_conn_sub_id_smbd_wifi = g_dbus_connection_signal_subscribe(
489 SMBD_SERVICE_INTERFACE,
490 SMBD_SIGNAL_PROPERTYCHANGED,
492 SMBD_SIGNAL_VALUE_WIFI,
493 G_DBUS_SIGNAL_FLAGS_NONE,
494 __dbus_smbd_wifi_signal_filter,
498 gdbus_conn_sub_id_smbd_smartbonding = g_dbus_connection_signal_subscribe(
501 SMBD_SERVICE_INTERFACE,
502 SMBD_SIGNAL_PROPERTYCHANGED,
504 SMBD_SIGNAL_VALUE_SMARTBONDING,
505 G_DBUS_SIGNAL_FLAGS_NONE,
506 __dbus_smbd_smartbonding_signal_filter,
510 gdbus_conn_sub_id_smbd_user = g_dbus_connection_signal_subscribe(
513 SMBD_SERVICE_INTERFACE,
514 SMBD_SIGNAL_USERRESPONSE,
516 SMBD_SIGNAL_VALUE_USERRESPONSE,
517 G_DBUS_SIGNAL_FLAGS_NONE,
518 __dbus_smbd_user_signal_filter,
522 if (gdbus_conn_sub_id_smbd_cellular == 0 ||
523 //gdbus_conn_sub_id_smbd_wifi == 0 ||
524 gdbus_conn_sub_id_smbd_smartbonding == 0 ||
525 gdbus_conn_sub_id_smbd_user == 0) {
526 TIZEN_LOGD("Failed to register signals smbd cellular id(%d) "
528 "smbd smartbonding id(%d) smbd user id(%d)\n",
529 gdbus_conn_sub_id_smbd_cellular,
530 //gdbus_conn_sub_id_smbd_wifi,
531 gdbus_conn_sub_id_smbd_smartbonding,
532 gdbus_conn_sub_id_smbd_user);
533 Error = SMBD_ERR_UNKNOWN;
535 TIZEN_LOGD("Signals registered successfully");
541 static int __dbus_deregister_signal(void)
543 GDBusConnection *connection = _dbus_get_gdbus_conn();
544 smbd_err_t Error = SMBD_ERR_NONE;
546 if (connection == NULL) {
547 TIZEN_LOGD("Connection NULL\n");
548 return SMBD_ERR_UNKNOWN;
551 g_dbus_connection_signal_unsubscribe(connection,
552 gdbus_conn_sub_id_smbd_cellular);
553 /* g_dbus_connection_signal_unsubscribe(connection,
554 gdbus_conn_sub_id_smbd_wifi); */
555 g_dbus_connection_signal_unsubscribe(connection,
556 gdbus_conn_sub_id_smbd_smartbonding);
557 g_dbus_connection_signal_unsubscribe(connection,
558 gdbus_conn_sub_id_smbd_user);
563 int smart_bonding_init(void)
565 smbd_err_t Error = SMBD_ERR_NONE;
567 TIZEN_LOGD("Smartbonding client: Init API");
569 Error = __dbus_create_gdbus_call();
570 if (Error != SMBD_ERR_NONE) {
571 TIZEN_LOGD("Connection creation failed - [%d]\n", Error);
575 Error = __dbus_register_signal();
576 if (Error != SMBD_ERR_NONE) {
577 TIZEN_LOGD("Signal registration failed - [%d]\n", Error);
581 return SMBD_ERR_NONE;
584 int smart_bonding_deinit(void)
586 smbd_err_t Error = SMBD_ERR_NONE;
588 TIZEN_LOGD("Smartbonding client: De-init API");
590 Error = __dbus_deregister_signal();
591 if (Error != SMBD_ERR_NONE) {
592 TIZEN_LOGD("Signal de-registration failed - [%d]\n", Error);
596 Error = __dbus_close_gdbus_call();
597 if (Error != SMBD_ERR_NONE) {
598 TIZEN_LOGD("Connection close failed - [%d]\n", Error);
602 return SMBD_ERR_NONE;
605 int smart_bonding_start(char *file_name, int file_size,
606 smartbonding_cb callback, void *user_data)
608 smbd_err_t Error = SMBD_ERR_NONE;
611 int smartbonding_value;
612 event_info_t *event_info = NULL;
615 TIZEN_LOGD("Smartbonding client: Start smartbonding API");
616 SECURE_DB_INFO("File - [%s] file size - [%d]", file_name, file_size);
618 vconf_get_int(VCONF_SMART_BONDING_POLICY, &smartbonding_value);
620 if (smartbonding_value == SMART_BONDING_WIFI_ONLY) {
621 TIZEN_LOGD("Smart bonding policy is OFF");
622 return SMBD_ERR_POLICY_OFF;
625 if (callback == NULL) {
626 TIZEN_LOGD("Smart bonding callback not set");
627 return SMBD_ERR_INVALID_PARAMETER;
630 params = g_variant_new("(su)", file_name, file_size);
632 msg = __invoke_dbus_method(SMBD_SERVICE_DBUS, SMBD_PATH_DBUS,
633 SMBD_SERVICE_INTERFACE, "StartBonding", params, &Error);
635 TIZEN_LOGD("Start smart bonding request failed");
640 g_variant_get(msg, "(u)", &handle);
641 g_variant_unref(msg);
644 TIZEN_LOGD("Start smart bonding request failed."
645 " Erroneous handle");
646 return SMBD_ERR_UNKNOWN;
649 event_info = g_try_new0(event_info_t, 1);
650 if (event_info == NULL) {
651 TIZEN_LOGD("Start smart bonding request failed."
652 "Memory allocation failed");
653 return SMBD_ERR_UNKNOWN;
655 event_info->cb = callback;
656 event_info->user_data = user_data;
657 event_info->handle = handle;
659 handle_list = g_slist_append(handle_list, event_info);
660 TIZEN_LOGD("Added the handle - [%d] into the list", handle);
662 TIZEN_LOGD("Start smart bonding request successful");
666 int smart_bonding_stop(void *user_data)
668 smbd_err_t Error = SMBD_ERR_NONE;
669 guint32 handle_id = 0;
672 TIZEN_LOGD("Smartbonding client: Stop smartbonding API");
674 handle_id = _handle_remove_with_user_data(user_data);
676 params = g_variant_new("(u)", handle_id);
678 Error = __invoke_dbus_method_nonblock(SMBD_SERVICE_DBUS, SMBD_PATH_DBUS,
679 SMBD_SERVICE_INTERFACE, "StopBonding", params, __dbus_reply);
680 if (Error != SMBD_ERR_NONE) {
681 TIZEN_LOGD("Stop smart bonding request failed");
685 TIZEN_LOGD("Stop smart bonding request successful");
690 void smart_bonding_notify_interface_usage(const char *message)
692 smbd_err_t Error = SMBD_ERR_NONE;
697 params = g_variant_new("(s)", message);
699 msg = __invoke_dbus_method(SMBD_SERVICE_DBUS, SMBD_PATH_DBUS,
700 SMBD_SERVICE_INTERFACE, "NotifyInterfaceUsage", params, &Error);
702 TIZEN_LOGD("Notify smart bonding info failed, Error=%d", Error);
706 g_variant_get(msg, "(u)", &handle);
707 g_variant_unref(msg);