title: C++: Traverse DBUS message to find BlueZ 5 adapter using iterator
body: <p>I am trying to find available BlueTooth adapters using the BlueZ 5 updated Dbus API.</p>
  
  <p>Unlike BlueZ 4, which has a method exactly for this (i.e. org.bluez.Manager.FindAdapter()), BlueZ 5 uses the FreeDesktop ObjectManager interface with the method GetManagedObjects().  This method returns a very large array of results:</p>
  
  <pre><code>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.
        . ]
  </code></pre>
  
  <p><a href="http://www.bluez.org/bluez-5-api-introduction-and-porting-guide/" rel="nofollow">The BlueZ 5 API Intro and Porting Guide</a> says, "<em>The concept of a default adapter was always a bit fuzzy and the value could’t be changed, so if applications need something like it they could e.g. just pick the first adapter they encounter in the GetManagedObjects reply.</em>"</p>
  
  <p>I've written C++ code using iterators to do this (I have no experience with Python), but it's really long for something that seems so simple:</p>
  
  <pre><code>if (dbus_message_iter_init(reply, &amp;rootIter) &amp;&amp; //point iterator to reply message
      DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&amp;rootIter)) //get the type of message that iter points to
  {
      debug_print("Type Array.\n");   
      DBusMessageIter arrayElementIter;
      dbus_message_iter_recurse(&amp;rootIter, &amp;arrayElementIter); //assign new iterator to first element of array
      debug_print("--&gt;Descending into Array (recursing).\n");
  
     while(!adapterFound){
      if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&amp;arrayElementIter))
      {
          debug_print("  Type Dict_Entry.\n");
  
          DBusMessageIter dictEntryIter;
          dbus_message_iter_recurse(&amp;arrayElementIter,&amp;dictEntryIter ); //assign new iterator to first element of
          debug_print("  --&gt;Descending into Dict_Entry (recursing).\n");
          if (DBUS_TYPE_OBJECT_PATH == dbus_message_iter_get_arg_type(&amp;dictEntryIter))
                  {
              debug_print("    Type DBUS_TYPE_OBJECT_PATH.\n");
              dbus_message_iter_get_basic(&amp;dictEntryIter, &amp;adapter_path);  
              if(device &amp;&amp; strstr(adapter_path,device)) 
              {   
                 adapterFound = TRUE;
                 debug_print("    Adapter %s FOUND!\n",device);
              }
          }
          dbus_message_iter_next(&amp;dictEntryIter);
          if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&amp;dictEntryIter))
                      {
                              debug_print("    Type DBUS_TYPE_ARRAY.\n");
              DBusMessageIter innerArrayIter;
              dbus_message_iter_recurse(&amp;dictEntryIter, &amp;innerArrayIter);
              dbus_message_iter_next(&amp;innerArrayIter);
              debug_print("    --&gt;Descending into Array (recursing).\n");
              if (DBUS_TYPE_DICT_ENTRY == dbus_message_iter_get_arg_type(&amp;innerArrayIter))
              {
                  debug_print("      Type Dict_Entry.\n");
                  DBusMessageIter innerDictEntryIter;
                  dbus_message_iter_recurse(&amp;innerArrayIter,&amp;innerDictEntryIter ); //assign new iterator to first element of
                  debug_print("      --&gt;Descending into Dict_Entry (recursing).\n");
                  if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&amp;innerDictEntryIter))
                  {
                      debug_print("        Type DBUS_TYPE_STRING.\n");
                      char *dbusObject;
                      dbus_message_iter_get_basic(&amp;innerDictEntryIter, &amp;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("      &lt;--Ascending from Dict_Entry.\n");
              }
              debug_print("    &lt;--Ascending from Array (top layer).\n");
                              //dbus_message_iter_get_basic(&amp;dictEntryIter, &amp;adapter_path);  
                      }
  
          debug_print("  &lt;--Ascending from Dict_Entry.\n");
      }
      debug_print("&lt;--Ascending from Array (top layer).\n");
      if(!dbus_message_iter_has_next(&amp;arrayElementIter)) break; //check to see if end of array
      else dbus_message_iter_next(&amp;arrayElementIter);
  
      }//while loop end --used to traverse array
  } //end if - outer arrray
  else return 0;
  </code></pre>
  
  <p>In other words, I have to define a new iterator for each branch of the tree, just to find a string that is in a fixed location every time. (array[x]->secondfield[2]->firstfieldstring)  My question (finally, I know) is can someone point out a more elegant/faster solution? </p>