2014-03-27 6 views
1

BlueZ 5 업데이트 된 Dbus API를 사용하여 사용 가능한 BlueTooth 어댑터를 찾으려고합니다.C++ : 반복자를 사용하여 BlueZ 5 어댑터를 찾으려면 DBUS 메시지를 트래버스하십시오.

BlueZ 4는 메소드 (예 : org.bluez.Manager.FindAdapter())와 완전히 다른 BlueZ 4와는 달리 GetManagedObjects() 메소드와 함께 FreeDesktop ObjectManager 인터페이스를 사용합니다. 이 방법은 결과의 매우 큰 배열 반환 : 기본 어댑터의 개념은 항상 약간 퍼지이었고, 어플리케이션이 같은 뭔가가 필요 그래서 만약 값이 변경 될 could't "

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. 
     . ] 

The BlueZ 5 API Intro and Porting Guide 말한다을 그들이 "

필자는 이것을하기 위해 반복자를 사용하여 작성했습니다 (파이썬에 대한 경험이 없습니다). 그러나 그렇게 간단한 것처럼 보이는 것은 길었습니다. :

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; 

다른 말로하면 매번 고정 된 위치에있는 문자열을 찾기 위해 트리의 각 분기마다 새로운 반복자를 정의해야합니다. (배열 [x] -> secondfield [2] -> firstfieldstring) 내 질문 (마침내, 나는 알고있다) 누군가가 더 우아하고 빠른 해결책을 지적 할 수 있는가?

답변

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); 

//... 

당신이 단지에서 볼 수있는이 방법을 어댑터 오브젝트 패스의 배열. 나머지는 모두 무시한다. 이 개체 경로를 사용하면 필요한 속성을 요청하거나 메서드 호출을 보내기 시작할 수 있습니다.

이것이 더 '우아한'것으로 간주 될 수 있는지 확실하지 않으며 추가 메서드 호출이 배열 탐색보다 느리기 때문에 아마도 더 빠를 것입니다. 코드의 양을 줄여서 더 읽기 쉽도록해야합니다. ...