C++: Traverse DBUS message to find BlueZ 5 adapter using iterator

I am trying to find available BlueTooth adapters using the BlueZ 5 updated Dbus API.

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    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 (http://www.bluez.org/bluez-5-api-introduction-and-porting-guide/) says, "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."


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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    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;



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?
Topic archived. No new replies allowed.