+ return id;
+}
+
+int _bt_register_profile(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
+{
+ GVariantBuilder *option_builder;
+ GVariant *ret;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ proxy = __bt_gdbus_get_profile_proxy();
+ if (proxy == NULL) {
+ BT_ERR("Getting profile proxy failed");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ if (info->authentication)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthentication",
+ g_variant_new_boolean(TRUE));
+ if (info->authorization)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthorization",
+ g_variant_new_boolean(TRUE));
+ if (info->role)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Role",
+ g_variant_new_string(info->role));
+
+ /* Setting RFCOMM channel to default value 0; would allow bluez to assign
+ * RFCOMM channels based on the availability when two services want
+ * to use the RFCOMM along with SPP. Hence bluez makes sure that no
+ * two services use the same SPP RFCOMM channel. */
+ if (use_default_rfcomm)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Channel",
+ g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
+ if (info->service)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Service",
+ g_variant_new_string(info->service));
+
+ ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile",
+ g_variant_new("(osa{sv})", info->obj_path,
+ info->uuid,
+ option_builder),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ if (err) {
+ g_dbus_error_strip_remote_error(err);
+ BT_ERR("RegisterProfile failed: %s", err->message);
+
+ if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
+ result = BLUETOOTH_ERROR_ACCESS_DENIED;
+ else
+ result = BLUETOOTH_ERROR_INTERNAL;
+
+ g_clear_error(&err);
+ }
+
+ g_variant_builder_unref(option_builder);
+
+ if (ret)
+ g_variant_unref(ret);
+
+ return result;
+}
+
+int _bt_register_profile_ex(bt_register_profile_info_t *info, gboolean use_default_rfcomm, const char *name, const char *path)
+{
+ GVariantBuilder *option_builder;
+ GVariant *ret;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ proxy = __bt_gdbus_get_profile_proxy();
+ if (proxy == NULL) {
+ BT_ERR("Getting profile proxy failed");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ if (info->authentication)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthentication",
+ g_variant_new_boolean(TRUE));
+ if (info->authorization)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthorization",
+ g_variant_new_boolean(TRUE));
+ if (info->role)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Role",
+ g_variant_new_string(info->role));
+
+ /* Setting RFCOMM channel to default value 0; would allow bluez to assign
+ * RFCOMM channels based on the availability when two services want
+ * to use the RFCOMM along with SPP. Hence bluez makes sure that no
+ * two services use the same SPP RFCOMM channel. */
+ if (use_default_rfcomm)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Channel",
+ g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
+ if (info->service)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Service",
+ g_variant_new_string(info->service));
+
+ ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile2",
+ g_variant_new("(osssa{sv})", info->obj_path,
+ info->uuid,
+ name,
+ path,
+ option_builder),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ if (err) {
+ g_dbus_error_strip_remote_error(err);
+ BT_ERR("RegisterProfile failed: %s", err->message);
+
+ if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
+ result = BLUETOOTH_ERROR_ACCESS_DENIED;
+ else
+ result = BLUETOOTH_ERROR_INTERNAL;
+
+ g_clear_error(&err);
+ }
+
+ g_variant_builder_unref(option_builder);
+
+ if (ret)
+ g_variant_unref(ret);
+
+ return result;
+}
+
+int _bt_register_profile_platform(bt_register_profile_info_t *info, gboolean use_default_rfcomm)
+{
+ GVariantBuilder *option_builder;
+ GVariant *ret;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ proxy = __bt_gdbus_get_profile_proxy();
+ if (proxy == NULL) {
+ BT_ERR("Getting profile proxy failed");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ option_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ if (info->authentication)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthentication",
+ g_variant_new_boolean(TRUE));
+ if (info->authorization)
+ g_variant_builder_add(option_builder, "{sv}",
+ "RequireAuthorization",
+ g_variant_new_boolean(TRUE));
+ if (info->role)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Role",
+ g_variant_new_string(info->role));
+
+ /* Setting RFCOMM channel to default value 0; would allow bluez to assign
+ * RFCOMM channels based on the availability when two services want
+ * to use the RFCOMM along with SPP. Hence bluez makes sure that no
+ * two services use the same SPP RFCOMM channel. */
+ if (use_default_rfcomm)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Channel",
+ g_variant_new_uint16(RFCOMM_DEFAULT_PROFILE_CHANNEL));
+ if (info->service)
+ g_variant_builder_add(option_builder, "{sv}",
+ "Service",
+ g_variant_new_string(info->service));
+
+ ret = g_dbus_proxy_call_sync(proxy, "RegisterProfile1",
+ g_variant_new("(osa{sv})", info->obj_path,
+ info->uuid,
+ option_builder),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+
+ if (err) {
+ g_dbus_error_strip_remote_error(err);
+ BT_ERR("RegisterProfile failed: %s", err->message);
+
+ if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG))
+ result = BLUETOOTH_ERROR_ACCESS_DENIED;
+ else
+ result = BLUETOOTH_ERROR_INTERNAL;
+
+ g_clear_error(&err);
+ }
+
+ g_variant_builder_unref(option_builder);
+
+ if (ret)
+ g_variant_unref(ret);
+
+ return result;
+}
+
+
+void _bt_unregister_profile(char *path)
+{
+ GVariant *ret;
+ GDBusProxy *proxy;
+ GError *err = NULL;
+
+ proxy = __bt_gdbus_get_profile_proxy();
+ if (proxy == NULL) {
+ BT_ERR("Getting profile proxy failed");
+ return;
+ }
+
+ ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile",
+ g_variant_new("(o)", path),
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &err);
+ if (err) {
+ BT_ERR("UnregisterProfile failed : %s", err->message);
+ g_clear_error(&err);
+ }
+
+ if (ret)
+ g_variant_unref(ret);
+
+ return;
+}
+
+GDBusNodeInfo * _bt_get_gdbus_node(const gchar *xml_data)
+{
+ if (bus_id == 0) {
+ char *name = g_strdup_printf("org.bt.frwk%d", getpid());
+
+ bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ name,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ BT_DBG("Got bus id %d", bus_id);
+ g_free(name);
+ }
+
+ return g_dbus_node_info_new_for_xml(xml_data, NULL);
+}
+
+GDBusNodeInfo * _bt_get_gdbus_node_ex(const gchar *xml_data, const char *bus_name)
+{
+ if (bus_id == 0) {
+ char *name = g_strdup(bus_name);
+ bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ name,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ BT_DBG("Got bus id %d", bus_id);
+ g_free(name);
+ }
+
+ return g_dbus_node_info_new_for_xml(xml_data, NULL);
+}
+
+int _bt_connect_profile(char *address, char *uuid, void *cb,
+ gpointer func_data)
+{
+ GDBusProxy *proxy;
+ GDBusProxy *adapter_proxy;
+ char *object_path;
+ GError *err = NULL;
+
+ object_path = _bt_get_device_object_path(address);
+
+ if (object_path == NULL) {
+ GVariant *ret = NULL;
+ BT_ERR("No searched device");
+ adapter_proxy = __bt_gdbus_get_adapter_proxy();
+
+ if (adapter_proxy == NULL) {
+ BT_ERR("adapter proxy is NULL");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+
+ if (err != NULL) {
+ BT_ERR("CreateDevice Failed: %s", err->message);
+ g_clear_error(&err);
+ }
+ if (ret)
+ g_variant_unref(ret);
+ g_object_unref(adapter_proxy);
+ object_path = _bt_get_device_object_path(address);
+
+ if (object_path == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ proxy = __bt_gdbus_get_device_proxy(object_path);
+ g_free(object_path);
+
+ if (proxy == NULL) {
+ BT_ERR("Error while getting proxy");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_dbus_proxy_call(proxy, "ConnectProfile",
+ g_variant_new("(s)", uuid),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ (GAsyncReadyCallback)cb,
+ func_data);
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_discover_services(char *address, char *uuid, void *cb,
+ gpointer func_data)
+{
+ char *object_path;
+ GDBusProxy *proxy;
+ GDBusProxy *adapter_proxy;
+ GError *err = NULL;
+ object_path = _bt_get_device_object_path(address);
+ if (object_path == NULL) {
+ GVariant *ret = NULL;
+ BT_ERR("No searched device");
+ adapter_proxy = __bt_gdbus_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+ ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err != NULL) {
+ BT_ERR("CreateDevice Failed: %s", err->message);
+ g_clear_error(&err);
+ }
+ if (ret)
+ g_variant_unref(ret);
+
+ g_object_unref(adapter_proxy);
+
+ object_path = _bt_get_device_object_path(address);
+ if (object_path == NULL)
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ proxy = __bt_gdbus_get_device_proxy(object_path);
+ g_free(object_path);
+ if (proxy == NULL) {
+ BT_ERR("Error while getting proxy");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ g_dbus_proxy_call(proxy, "DiscoverServices",
+ g_variant_new("(s)", uuid),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ (GAsyncReadyCallback)cb,
+ func_data);
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_cancel_discovers(char *address)
+{
+ char *object_path;
+ GDBusProxy *proxy;
+ GDBusProxy *adapter_proxy;
+ GError *err = NULL;
+ object_path = _bt_get_device_object_path(address);
+ if (object_path == NULL) {
+ GVariant *ret = NULL;
+ BT_ERR("No searched device");
+ adapter_proxy = __bt_gdbus_get_adapter_proxy();
+ retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+ ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err != NULL) {
+ BT_ERR("CreateDevice Failed: %s", err->message);
+ g_clear_error(&err);