简体   繁体   English

如何使用dbus / gio在bluez中注册配置文件?

[英]How do I register a profile with bluez using dbus/gio?

I'm trying to register a profile with bluez through D-Bus/Gio. 我正在尝试通过D-Bus / Gio向bluez注册个人资料。 When I call RegisterProfile everything goes OK. 当我致电RegisterProfile时,一切正常。 I check my GError and it's NULL and my return value is an empty GVariant. 我检查了我的GError,它为NULL,并且我的返回值是一个空的GVariant。 I've tried many things, but here is my latest code. 我已经尝试了很多事情,但这是我的最新代码。 When I run it, it prints "g_dbus_connection_call_sync succeeded", but I can't see my new profile in D-Bus using d-feet and I cannot connect to it using a my test device. 当我运行它时,它会显示“ g_dbus_connection_call_sync成功”,但是我无法使用d-feet在D-Bus中看到我的新配置文件,并且无法使用我的测试设备连接到它。 I know the code on the test device works, or at least did work with straight bluez, but I'm trying to figure out how to use bluez with D-Bus. 我知道测试设备上的代码可以工作,或者至少可以使用纯正的bluez进行工作,但是我想弄清楚如何在D-Bus中使用bluez。

Here is my code .h file: 这是我的代码.h文件:

#ifndef BT_SERVER_H
#define BT_SERVER_H

#include <glib.h>
#include <gio/gio.h>

// ---------------------------------------------------------------------------

class BTProfile
{
public:
    BTProfile();
    void init();
    void destroy();

    static void method_call(GDBusConnection *connection,
        const gchar *sender, const gchar *object_path,
        const gchar *interface_name, const gchar *method_name,
        GVariant *parameters, GDBusMethodInvocation *invocation,
        gpointer user_data);
    static GVariant *get_property(GDBusConnection *connection,
        const gchar *sender, const gchar *object_path,
        const gchar *interface_name, const gchar *property_name,
        GError **error, gpointer user_data);
    static gboolean set_property(GDBusConnection *connection,
        const gchar *sender, const gchar *object_path,
        const gchar *interface_name, const gchar *property_name,
        GVariant *value, GError **error, gpointer userData);

protected:
    GDBusConnection *bus_connection;
};

Here is my .cpp file: 这是我的.cpp文件:

#include <stdio.h>
#include "bt_server.h"

static const char *serial_service_class_uuid =
    "00001101-0000-1000-8000-00805F9B34FB";
static const char *my_service_uuid =
    "E62C4DCA-9ABC-11E5-8994-FEFF819CDC9F";

static const gchar btp_introspection_xml[] =
    "<node>"
    "  <interface name='org.bluez.Profile1'>"
    "    <method name='Release' />"
    "    <method name='NewConnection'>"
    "      <arg type='o' name='device' direction='in' />"
    "      <arg type='h' name='fd' direction='in' />"
    "      <arg type='a{sv}' name='fd_properties' direction='in' />"
    "    </method>"
    "    <method name='RequestDisconnection'>"
    "      <arg type='o' name='device' direction='in' />"
    "    </method>"
    "  </interface>"
    "</node>";

static const GDBusInterfaceVTable btp_interface_vtable =
{
    BTProfile::method_call,
    BTProfile::get_property,
    BTProfile::set_property
};

BTProfile::BTProfile() : bus_connection(NULL)
{
}

// ---------------------------------------------------------------------------

void BTProfile::init()
{
    GError *error = NULL;
    GDBusNodeInfo *introspection = g_dbus_node_info_new_for_xml(
        btp_introspection_xml, &error);
    if (!error)
    {
        GDBusInterfaceInfo *interface_info = g_dbus_node_info_lookup_interface(
            introspection, "org.bluez.Profile1");
        bus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
        if (!error)
        {
            g_dbus_connection_register_object(bus_connection,
                "/org/bluez/myprofile", interface_info, &btp_interface_vtable,
                this, NULL, &error);
            if (!error)
            {
                GVariantBuilder builder;
                g_variant_builder_init(&builder, G_VARIANT_TYPE_DICTIONARY);
                g_variant_builder_add(&builder, "{sv}", "Name",
                    g_variant_new("s", "myprofile"));
                g_variant_builder_add(&builder, "{sv}", "Service",
                    g_variant_new("s", serial_service_class_uuid));
                g_variant_builder_add(&builder, "{sv}", "Channel",
                    g_variant_new("q", 1));
                g_variant_builder_add(&builder, "{sv}", "RequireAuthentication",
                    g_variant_new("b", FALSE));
                g_variant_builder_add(&builder, "{sv}", "Role",
                    g_variant_new("s", "client"));
                g_variant_builder_add(&builder, "{sv}", "Version",
                    g_variant_new("q", 1));
                g_variant_builder_add(&builder, "{sv}", "AutoConnect",
                    g_variant_new("b", true));
                g_dbus_connection_call_sync(bus_connection, "org.bluez",
                    "/org/bluez", "org.bluez.ProfileManager1",
                    "RegisterProfile", g_variant_new("(osa{sv})",
                    "/org/bluez/myprofile", my_service_uuid, &builder),
                    NULL, G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error);
                if (!error)
                {
                    g_print("g_dbus_connection_call_sync succeeded\n");
                }
                else
                {
                    g_print("g_dbus_connection_call_sync failed: %s\n",
                        error->message);
                    g_error_free(error);
                }
            }
            else
            {
                g_print("g_dbus_connection_register_object failed: %s\n",
                    error->message);
                g_error_free(error);
            }
        }
        else
        {
            g_print("g_bus_get_sync failed: %s\n", error->message);
            g_error_free(error);
        }
    }
    else
    {
        g_print("g_dbus_node_info_new_for_xml failed: %s\n", error->message);
        g_error_free(error);
    }
}

// ---------------------------------------------------------------------------

void BTProfile::destroy()
{
    if (bus_connection)
    {
        g_object_unref(bus_connection);
    }
}

// ---------------------------------------------------------------------------

void BTProfile::method_call(GDBusConnection *connection, const gchar *sender,
    const gchar *object_path, const gchar *interface_name,
    const gchar *method_name, GVariant *parameters,
    GDBusMethodInvocation *invocation, gpointer user_data)
{
    g_print("handle_method_call: called\n");
    g_dbus_method_invocation_return_value(invocation, NULL);
}

// ---------------------------------------------------------------------------

GVariant *BTProfile::get_property(GDBusConnection *connection,
    const gchar *sender, const gchar *object_path, const gchar *interface_name,
    const gchar *property_name, GError **error, gpointer user_data)
{
    g_print("get_property: called\n");
    return NULL;
}

// ---------------------------------------------------------------------------

gboolean BTProfile::set_property(GDBusConnection *connection,
    const gchar *sender, const gchar *object_path, const gchar *interface_name,
    const gchar *property_name, GVariant *value, GError **error,
    gpointer userData)
{
    g_print("set_property: called\n");
    return false;
}

I'm a bit lost seeing as how I get no error information. 我有点迷茫,看不到错误信息。 Thanks everyone. 感谢大家。

EDIT: After digging around I found the dbus bluetooth.conf file, here is mine: 编辑:挖掘后,我发现了dbus bluetooth.conf文件,这是我的:

<!-- This configuration file specifies the required security policies
     for Bluetooth core daemon to work. -->

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

  <!-- ../system.conf have denied everything, so we just punch some holes -->

  <policy user="root">
    <allow own="org.bluez"/>
    <allow send_destination="org.bluez"/>
    <allow send_interface="org.bluez.Agent1"/>
    <allow send_interface="org.bluez.MediaEndpoint1"/>
    <allow send_interface="org.bluez.MediaPlayer1"/>
    <allow send_interface="org.bluez.ThermometerWatcher1"/>
    <allow send_interface="org.bluez.AlertAgent1"/>
    <allow send_interface="org.bluez.Profile1"/>
    <allow send_interface="org.bluez.HeartRateWatcher1"/>
    <allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
    <allow send_interface="org.bluez.GattCharacteristic1"/>
    <allow send_interface="org.bluez.GattDescriptor1"/>
    <allow send_interface="org.bluez.ProfileManager1"/>
    <allow send_interface="org.bluez.Device1"/>
    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
    <allow send_interface="org.freedesktop.DBus.Properties"/>
  </policy>

  <policy at_console="true">
    <allow send_destination="org.bluez"/>
  </policy>

  <!-- allow users of lp group (printing subsystem) to 
       communicate with bluetoothd -->
  <policy group="lp">
    <allow send_destination="org.bluez"/>
  </policy>

  <policy context="default">
    <deny send_destination="org.bluez"/>
  </policy>

</busconfig>

I added ProfileManager1 and Device1 to it, but still no luck. 我向其中添加了ProfileManager1和Device1,但还是没有运气。 Does anyone know what I'm missing here? 有人知道我在这里想念的吗? I can register and use profiles using straight bluez, so I know it's a bluez/dbus issue. 我可以使用直接bluez注册和使用配置文件,所以我知道这是bluez / dbus的问题。

I believe I've figured it out. 我相信我已经解决了。 I have it working anyway. 无论如何我都在工作。 After much re-reading of the examples I ended up doing this: 在重新阅读了示例之后,我最终这样做了:

1: own a bus name with g_bus_own_name. 1:使用g_bus_own_name拥有总线名称。

2: in my on_bus_acquired callback I use that GDBusConnection as a parameter for g_dbus_connection_register_object (as opposed to trying to create the GDBusConnection myself) 2:在我的on_bus_acquired回调中,我将该GDBusConnection用作g_dbus_connection_register_object的参数(与尝试自己创建GDBusConnection相对)

3: call the RegisterProfile method 3:调用RegisterProfile方法

I can post code if anyone is interested. 如果有人感兴趣,我可以发布代码。

Everything seems to be working now. 现在一切似乎都正常了。 Another thing that tripped me up were the parameters to RegisterProfile. 使我震惊的另一件事是RegisterProfile的参数。 I'm using the SerialUUID to connect, but at first I was also setting the role paramter to "server". 我正在使用SerialUUID进行连接,但起初我还将角色参数设置为“服务器”。 It was causing my profile to reject connections. 这导致我的个人资料拒绝连接。 I think that parameter is only for a different kind of profile, but I'm not sure. 我认为该参数仅适用于其他类型的配置文件,但我不确定。 Does anyone know for certain? 有人知道吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM