2016-06-01 5 views
0

D-Bus/Gio를 통해 bluez 프로필을 등록하려고합니다. RegisterProfile을 호출하면 모든 것이 정상적으로 처리됩니다. 내 GError를 확인하고 그것은 NULL이고 반환 값은 빈 GVariant입니다. 나는 많은 것을 시도했지만, 여기에 최신 코드가 있습니다. 실행하면 "g_dbus_connection_call_sync succeeded"가 인쇄되지만 d-feet을 사용하여 D-Bus에서 새 프로파일을 볼 수 없으며 테스트 장치를 사용하여 연결할 수 없습니다. 테스트 장치의 코드가 작동하는지, 아니면 적어도 직선의 bluez로 작동했는지는 알고 있지만 D-Bus에서 bluez를 사용하는 방법을 파악하려고합니다.dbus/gio를 사용하여 bluez에 프로파일을 등록하려면 어떻게합니까?

#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; 
} 

내가 조금 나는 오류 정보를 얻을 방법으로보고 잃었어요 :

#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; 
}; 

가 여기 내 .cpp 파일입니다 :

여기에 내 코드 .H 파일입니다. 감사합니다.

편집 :

<!-- 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> 

내가 그것을 ProfileManager1 및 디바이스 1을 추가,하지만 여전히 운 : 주위를 파고 후에 나는 여기에 내 꺼야의 DBUS의 bluetooth.conf 파일을 발견했다. 아무도 내가 여기에서 놓친 것을 아는가? 곧바로 bluez를 사용하여 프로필을 등록하고 사용할 수 있으므로 bluez/dbus 문제라는 것을 알고 있습니다.

답변

0

나는 그것을 이해했다고 생각합니다. 어쨌든 나는 그것을 가지고있다. 많은 예제를 다시 읽은 후에 다음을 수행했습니다.

1 : g_bus_own_name을 사용하여 버스 이름을 소유하고 있습니다.

2 : 사람의 경우

내가 게시 할 수있는 코드 RegisterProfile 방법을 호출 내 on_bus_acquired 콜백 나는 GDBusConnection

3합니다 (GDBusConnection 자신을 만들려고 반대) g_dbus_connection_register_object의 매개 변수로 것을 사용 관심이 있습니다.

모든 것이 이제 작동하는 것 같습니다. 또 다른 한가지는 RegisterProfile에 대한 매개 변수입니다. 연결에 SerialUUID를 사용하고 있지만, 처음에는 "서버"역할 매개 변수도 설정했습니다. 내 프로필로 인해 연결이 거부되었습니다. 나는 그 매개 변수가 다른 종류의 프로필만을위한 것이라고 생각하지만 확실하지 않습니다. 누구든지 확실하게 알고 있습니까?

+0

공유하는 데 신경 쓰지 않는다면 최종 결과를보고 싶습니다. 또한 위의'GVariantBuilder'를 사용하여'g_variant_builder_init (& builder, G_VARIANT_TYPE_DICTIONARY)'로 초기화하는 것에 관심이 있습니다. 실제로'g_variant_builder_init (빌더, G_VARIANT_TYPE_ARRAY)'가되어서는 안됩니까? –