Use dbus_free for deallocation, when allocated with dbus_malloc0
[platform/upstream/connman.git] / client / dbus_helpers.c
index 2cc6e61..1c68a28 100644 (file)
 
 #include <stdio.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <glib.h>
 
 #include "input.h"
 #include "dbus_helpers.h"
 
-#define TIMEOUT         60000
+#define TIMEOUT         120000
+
+#ifndef DBUS_ERROR_UNKNOWN_METHOD
+#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
+#endif
+
+#ifndef DBUS_ERROR_UNKNOWN_PROPERTY
+#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty"
+#endif
+
+#ifndef DBUS_ERROR_UNKNOWN_OBJECT
+#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject"
+#endif
+
+static int string2errno(const char *error)
+{
+       if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_METHOD))
+               return -ENOTSUP;
+       if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_PROPERTY))
+               return -ENOENT;
+       if (!g_strcmp0(error, DBUS_ERROR_UNKNOWN_OBJECT))
+               return -ENODEV;
+       if (!g_strcmp0(error, "net.connman.Error.AlreadyEnabled"))
+               return -EALREADY;
+       if (!g_strcmp0(error, "net.connman.Error.AlreadyDisabled"))
+               return -EALREADY;
+
+       return -EINVAL;
+}
 
 void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
                const char *dict, const char *sep)
@@ -35,13 +64,16 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
        int arg_type;
        dbus_bool_t b;
        unsigned char c;
-       unsigned int i;
+       dbus_uint16_t u16;
+       dbus_uint32_t u;
+       dbus_int32_t i;
+       dbus_uint64_t u64;
        double d;
 
        char *str;
        DBusMessageIter entry;
 
-       if (pre == NULL)
+       if (!pre)
                pre = "";
 
        while ((arg_type = dbus_message_iter_get_arg_type(iter))
@@ -85,7 +117,7 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
 
                case DBUS_TYPE_BOOLEAN:
                        dbus_message_iter_get_basic(iter, &b);
-                       if (b == FALSE)
+                       if (!b)
                                fprintf(stdout, "False");
                        else
                                fprintf(stdout, "True");
@@ -97,11 +129,25 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
                        break;
 
                case DBUS_TYPE_UINT16:
+                       dbus_message_iter_get_basic(iter, &u16);
+                       fprintf(stdout, "%u", u16);
+                       break;
+
                case DBUS_TYPE_UINT32:
+                       dbus_message_iter_get_basic(iter, &u);
+                       fprintf(stdout, "%d", u);
+                       break;
+
+               case DBUS_TYPE_INT32:
                        dbus_message_iter_get_basic(iter, &i);
                        fprintf(stdout, "%d", i);
                        break;
 
+               case DBUS_TYPE_UINT64:
+                       dbus_message_iter_get_basic(iter, &u64);
+                       fprintf(stdout, "%"PRIu64, u64);
+                       break;
+
                case DBUS_TYPE_DOUBLE:
                        dbus_message_iter_get_basic(iter, &d);
                        fprintf(stdout, "%f", d);
@@ -112,7 +158,7 @@ void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
                        break;
                }
 
-               if (dbus_message_iter_has_next(iter) == TRUE)
+               if (dbus_message_iter_has_next(iter))
                        fprintf(stdout, "%s", sep);
 
                dbus_message_iter_next(iter);
@@ -127,30 +173,33 @@ struct dbus_callback {
 static void dbus_method_reply(DBusPendingCall *call, void *user_data)
 {
        struct dbus_callback *callback = user_data;
+       int res = 0;
        DBusMessage *reply;
        DBusMessageIter iter;
 
        __connmanctl_save_rl();
 
        reply = dbus_pending_call_steal_reply(call);
+       dbus_pending_call_unref(call);
        if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
                DBusError err;
 
                dbus_error_init(&err);
                dbus_set_error_from_message(&err, reply);
 
-               callback->cb(NULL, err.message, callback->user_data);
+               callback->cb(NULL, string2errno(err.name), err.message,
+                       callback->user_data);
 
                dbus_error_free(&err);
                goto end;
        }
 
        dbus_message_iter_init(reply, &iter);
-       callback->cb(&iter, NULL, callback->user_data);
+       res = callback->cb(&iter, 0, NULL, callback->user_data);
 
 end:
        __connmanctl_redraw_rl();
-       if (__connmanctl_is_interactive() == false)
+       if (__connmanctl_is_interactive() == false && res != -EINPROGRESS)
                __connmanctl_quit();
 
        g_free(callback);
@@ -165,14 +214,13 @@ static int send_method_call(DBusConnection *connection,
        DBusPendingCall *call;
        struct dbus_callback *callback;
 
-       if (dbus_connection_send_with_reply(connection, message, &call,
-                                       TIMEOUT) == FALSE)
+       if (!dbus_connection_send_with_reply(connection, message, &call, TIMEOUT))
                goto end;
 
-        if (call == NULL)
-                goto end;
+       if (!call)
+               goto end;
 
-       if (cb != NULL) {
+       if (cb) {
                callback = g_new0(struct dbus_callback, 1);
                callback->cb = cb;
                callback->user_data = user_data;
@@ -202,6 +250,14 @@ static int append_variant(DBusMessageIter *iter, const char *property,
         case DBUS_TYPE_STRING:
                 type_str = DBUS_TYPE_STRING_AS_STRING;
                 break;
+       case DBUS_TYPE_INT32:
+               type_str = DBUS_TYPE_INT32_AS_STRING;
+               break;
+#if defined TIZEN_EXT_WIFI_MESH
+       case DBUS_TYPE_UINT16:
+               type_str = DBUS_TYPE_UINT16_AS_STRING;
+               break;
+#endif
        default:
                return -EOPNOTSUPP;
        }
@@ -215,23 +271,25 @@ static int append_variant(DBusMessageIter *iter, const char *property,
        return 0;
 }
 
-int __connmanctl_dbus_method_call(DBusConnection *connection, const char *path,
-               const char *interface, const char *method,
-               connmanctl_dbus_method_return_func_t cb, void *user_data,
-               int arg1, ...)
+int __connmanctl_dbus_method_call(DBusConnection *connection,
+               const char *service, const char *path, const char *interface,
+               const char *method, connmanctl_dbus_method_return_func_t cb,
+               void *user_data, connmanctl_dbus_append_func_t append_func,
+               void *append_data)
 {
        DBusMessage *message;
-       va_list args;
+       DBusMessageIter iter;
 
-       message = dbus_message_new_method_call("net.connman", path,
-                       interface, method);
+       message = dbus_message_new_method_call(service, path, interface,
+                       method);
 
-       if (message == NULL)
+       if (!message)
                return -ENOMEM;
 
-       va_start(args, arg1);
-       dbus_message_append_args_valist(message, arg1, args);
-       va_end(args);
+       if (append_func) {
+               dbus_message_iter_init_append(message, &iter);
+               append_func(&iter, append_data);
+       }
 
        return send_method_call(connection, message, cb, user_data);
 }
@@ -247,7 +305,7 @@ int __connmanctl_dbus_set_property(DBusConnection *connection,
        message = dbus_message_new_method_call("net.connman", path,
                        interface, "SetProperty");
 
-       if (message == NULL)
+       if (!message)
                return -ENOMEM;
 
        dbus_message_iter_init_append(message, &iter);
@@ -260,8 +318,24 @@ int __connmanctl_dbus_set_property(DBusConnection *connection,
        return send_method_call(connection, message, cb, user_data);
 }
 
-void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter, char *property,
-               int type, void *value)
+void __connmanctl_dbus_append_dict(DBusMessageIter *iter,
+               connmanctl_dbus_append_func_t append_fn, void *append_data)
+{
+       DBusMessageIter dict;
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+       if (append_fn)
+               append_fn(&dict, append_data);
+
+       dbus_message_iter_close_container(iter, &dict);
+}
+
+void __connmanctl_dbus_append_dict_entry(DBusMessageIter *iter,
+               const char *property, int type, void *value)
 {
        DBusMessageIter dict_entry;
 
@@ -277,7 +351,8 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
                const char *path, const char *interface,
                connmanctl_dbus_method_return_func_t cb, void *user_data,
                const char *property, int type,
-               connman_dbus_append_cb_t append_fn, void *append_user_data)
+               connmanctl_dbus_append_func_t append_fn,
+               void *append_user_data)
 {
        DBusMessage *message;
        DBusMessageIter iter, variant, dict;
@@ -285,7 +360,7 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
        message = dbus_message_new_method_call("net.connman", path,
                        interface, "SetProperty");
 
-       if (message == NULL)
+       if (!message)
                return -ENOMEM;
 
        dbus_message_iter_init_append(message, &iter);
@@ -313,8 +388,53 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
        return send_method_call(connection, message, cb, user_data);
 }
 
+#if defined TIZEN_EXT_WIFI_MESH
+int __connmanctl_dbus_mesh_dict(DBusConnection *connection,
+               const char *path, const char *interface,
+               connmanctl_dbus_method_return_func_t cb, void *user_data,
+               const char *property, int type,
+               connmanctl_dbus_append_func_t append_fn,
+               void *append_user_data)
+{
+       DBusMessage *message;
+       DBusMessageIter iter, variant, dict;
+
+       message = dbus_message_new_method_call(CONNMAN_SERVICE, path,
+                       interface, "MeshCommands");
+
+       if (!message)
+               return -ENOMEM;
+
+       dbus_message_iter_init_append(message, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+                       DBUS_TYPE_ARRAY_AS_STRING
+                               DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                                       DBUS_TYPE_STRING_AS_STRING
+                                       DBUS_TYPE_VARIANT_AS_STRING
+                               DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                       &variant);
+
+       dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+                       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                               DBUS_TYPE_STRING_AS_STRING
+                               DBUS_TYPE_VARIANT_AS_STRING
+                       DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+                       &dict);
+
+       if (append_fn)
+               append_fn(&dict, append_user_data);
+
+       dbus_message_iter_close_container(&variant, &dict);
+       dbus_message_iter_close_container(&iter, &variant);
+
+       return send_method_call(connection, message, cb, user_data);
+}
+#endif
+
 static void append_variant_array(DBusMessageIter *iter, const char *property,
-               connman_dbus_append_cb_t append_fn, void *append_user_data)
+               connmanctl_dbus_append_func_t append_fn,
+               void *append_user_data)
 {
        DBusMessageIter variant, array;
 
@@ -334,7 +454,7 @@ static void append_variant_array(DBusMessageIter *iter, const char *property,
 }
 
 void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter,
-               const char *property, connman_dbus_append_cb_t append_fn,
+               const char *property, connmanctl_dbus_append_func_t append_fn,
                void *append_user_data)
 {
        DBusMessageIter dict_entry;
@@ -352,7 +472,8 @@ int __connmanctl_dbus_set_property_array(DBusConnection *connection,
                const char *path, const char *interface,
                connmanctl_dbus_method_return_func_t cb, void *user_data,
                const char *property, int type,
-               connman_dbus_append_cb_t append_fn, void *append_user_data)
+               connmanctl_dbus_append_func_t append_fn,
+               void *append_user_data)
 {
        DBusMessage *message;
        DBusMessageIter iter;
@@ -363,7 +484,54 @@ int __connmanctl_dbus_set_property_array(DBusConnection *connection,
        message = dbus_message_new_method_call("net.connman", path,
                        interface, "SetProperty");
 
-       if (message == NULL)
+       if (!message)
+               return -ENOMEM;
+
+       dbus_message_iter_init_append(message, &iter);
+
+       append_variant_array(&iter, property, append_fn, append_user_data);
+
+       return send_method_call(connection, message, cb, user_data);
+}
+
+int __connmanctl_dbus_session_change(DBusConnection *connection,
+               const char *session_path,
+               connmanctl_dbus_method_return_func_t cb, void * user_data,
+               const char *property, int type, void *value)
+{
+       DBusMessage *message;
+       DBusMessageIter iter;
+
+       message = dbus_message_new_method_call("net.connman", session_path,
+                       "net.connman.Session", "Change");
+
+       if (!message)
+               return -ENOMEM;
+
+       dbus_message_iter_init_append(message, &iter);
+
+       if (append_variant(&iter, property, type, value) < 0) {
+               dbus_message_unref(message);
+               return -EINVAL;
+       }
+
+       return send_method_call(connection, message, cb, user_data);
+}
+
+int __connmanctl_dbus_session_change_array(DBusConnection *connection,
+               const char *session_path,
+               connmanctl_dbus_method_return_func_t cb, void *user_data,
+               const char *property,
+               connmanctl_dbus_append_func_t append_fn,
+               void *append_user_data)
+{
+       DBusMessage *message;
+       DBusMessageIter iter;
+
+       message = dbus_message_new_method_call("net.connman", session_path,
+                       "net.connman.Session", "Change");
+
+       if (!message)
                return -ENOMEM;
 
        dbus_message_iter_init_append(message, &iter);