1

BlueZ 5 で更新された Dbus API を使用して、利用可能な BlueTooth アダプターを見つけようとしています。

BlueZ 4 にはこのためのメソッド (つまり org.bluez.Manager.FindAdapter()) があり、BlueZ 5 はメソッド GetManagedObjects() で FreeDesktop ObjectManager インターフェースを使用します。このメソッドは、結果の非常に大きな配列を返します。

array [
      dict entry(
         object path "/org/bluez"
         array [
            dict entry(
               string "org.freedesktop.DBus.Introspectable"
               array [
               ]
            )
            dict entry(
               string "org.bluez.AgentManager1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.ProfileManager1"
               array [
               ]
            )
         ]
      )
      dict entry(
         object path "/org/bluez/hci0"
         array [
            dict entry(
               string "org.freedesktop.DBus.Introspectable"
               array [
               ]
            )
            dict entry(
               string "org.bluez.Adapter1"
               array [
                  dict entry(
                     string "Address"
                     variant                         string "XX:XX:XX:XX:XX:XX"
                  )
                  dict entry(
                     string "Name"
                     variant                         string "My_Adapter"
                  )
                  dict entry(
                     string "Alias"
                     variant                         string "kubuntu-0"
                  )
                  dict entry(
                     string "Class"
                     variant                         uint32 0
                  )
                  dict entry(
                     string "Powered"
                     variant                         boolean false
                  )
                  dict entry(
                     string "Discoverable"
                     variant                         boolean true
                  )
                  dict entry(
                     string "DiscoverableTimeout"
                     variant                         uint32 0
                  )
                  dict entry(
                     string "Pairable"
                     variant                         boolean true
                  )
                  dict entry(
                     string "PairableTimeout"
                     variant                         uint32 0
                  )
                  dict entry(
                     string "Discovering"
                     variant                         boolean false
                  )
                  dict entry(
                     string "UUIDs"
                     variant                         array [
                           string "00001200-0000-1000-8000-00805f9b34fb"
                           string "00001800-0000-1000-8000-00805f9b34fb"
                           string "00001801-0000-1000-8000-00805f9b34fb"
                           string "0000110e-0000-1000-8000-00805f9b34fb"
                           string "0000110c-0000-1000-8000-00805f9b34fb"
                        ]
                  )
                  dict entry(
                     string "Modalias"
                     variant                         string "usb:sdfasdfsadf"
                  )
               ]
            )
            dict entry(
               string "org.freedesktop.DBus.Properties"
               array [
               ]
            )
            dict entry(
               string "org.bluez.Media1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.NetworkServer1"
               array [
               ]
            )
         ]
      )
      .
      .etc.
      . ]

BlueZ 5 API イントロおよびポーティング ガイドは次のように述べています。 GetManagedObjects 応答。

これを行うためにイテレーターを使用して C++ コードを作成しました (私は Python の経験がありません)。

if (dbus_message_iter_init(reply, &rootIter) && //point iterator to reply message
    DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&rootIter)) //get the type of message that iter points to
{
    debug_print("Type Array.\n");   
    DBusMessageIter arrayElementIter;
    dbus_message_iter_recurse(&rootIter, &arrayElementIter); //assign new iterator to first element of array
    debug_print("-->Descending into Array (recursing).\n");

   while(!adapterFound){
    if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&arrayElementIter))
    {
        debug_print("  Type Dict_Entry.\n");

        DBusMessageIter dictEntryIter;
        dbus_message_iter_recurse(&arrayElementIter,&dictEntryIter ); //assign new iterator to first element of
        debug_print("  -->Descending into Dict_Entry (recursing).\n");
        if (DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&dictEntryIter))
                {
            debug_print("    Type DBUS_TYPE_OBJECT_PATH.\n");
            dbus_message_iter_get_basic(&dictEntryIter, &adapter_path);  
            if(device && strstr(adapter_path,device)) 
            {   
               adapterFound = TRUE;
               debug_print("    Adapter %s FOUND!\n",device);
            }
        }
        dbus_message_iter_next(&dictEntryIter);
        if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&dictEntryIter))
                    {
                            debug_print("    Type DBUS_TYPE_ARRAY.\n");
            DBusMessageIter innerArrayIter;
            dbus_message_iter_recurse(&dictEntryIter, &innerArrayIter);
            dbus_message_iter_next(&innerArrayIter);
            debug_print("    -->Descending into Array (recursing).\n");
            if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&innerArrayIter))
            {
                debug_print("      Type Dict_Entry.\n");
                DBusMessageIter innerDictEntryIter;
                dbus_message_iter_recurse(&innerArrayIter,&innerDictEntryIter ); //assign new iterator to first element of
                debug_print("      -->Descending into Dict_Entry (recursing).\n");
                if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&innerDictEntryIter))
                {
                    debug_print("        Type DBUS_TYPE_STRING.\n");
                    char *dbusObject;
                    dbus_message_iter_get_basic(&innerDictEntryIter, &dbusObject);
                    debug_print("        This is an object of type:%s.\n", dbusObject);
                    if(strncmp(dbusObject,adapterString,strCmpLimit))
                        debug_print("        Not an adapter.\n");
                    else{
                        if(!device)
                        {
                           debug_print("        No adapter given, so using first available: %s\n", adapter_path);
                           adapterFound = TRUE;
                        }
                        debug_print("        Adapter.\n");
                    }
                }
                debug_print("      <--Ascending from Dict_Entry.\n");
            }
            debug_print("    <--Ascending from Array (top layer).\n");
                            //dbus_message_iter_get_basic(&dictEntryIter, &adapter_path);  
                    }

        debug_print("  <--Ascending from Dict_Entry.\n");
    }
    debug_print("<--Ascending from Array (top layer).\n");
    if(!dbus_message_iter_has_next(&arrayElementIter)) break; //check to see if end of array
    else dbus_message_iter_next(&arrayElementIter);

    }//while loop end --used to traverse array
} //end if - outer arrray
else return 0;

つまり、毎回決まった場所にある文字列を見つけるためだけに、ツリーの枝ごとに新しい反復子を定義する必要があります。(array[x]->secondfield[2]->firstfieldstring) 私の質問 (最後に、私は知っています) は、誰かがよりエレガントで高速なソリューションを指摘できますか?

4

1 に答える 1

0

BLuez 5 Adapter オブジェクトによって実装される必要があるorg.freedesktop.DBus.Propertiesインターフェイスを使用して、アダプターのプロパティを取得できます。

私の知る限り、アダプター オブジェクト パスが見つかるまで配列をトラバースする必要がありますが、そこから始めて、次のようなことができます。

DBusMessage *msg = dbus_message_new_method_call(
        "org.bluez",
        adapter_object_path,
        "org.freedesktop.DBus.Properties", "Get");

const char *property = "Powered"; // (e.g.)
dbus_message_append_args(msg,
        DBUS_TYPE_STRING, &property,
        DBUS_TYPE_INVALID);

//...

このようにして、アダプター オブジェクト パスの配列を調べるだけで、残りはすべて無視できます。このオブジェクト パスを使用すると、必要なプロパティを要求したり、メソッド呼び出しの送信を開始したりできます。

これがより「エレガント」と見なされるかどうかはわかりません。また、追加のメソッド呼び出しは配列トラバーサルよりも遅くなると思うので、おそらく速くもありません。コードの量を減らして読みやすくする必要があります...

于 2014-06-06T08:37:37.063 に答える