1# The ObjectMapper
2
3The `xyz.openbmc_project.ObjectMapper` service, commonly referred to as just
4the mapper, is an OpenBMC application that attempts to ease the pain of using
5D-Bus by providing APIs that help in discovering and associating other D-Bus
6objects.
7
8The mapper has two major pieces of functionality:
9
10- [Methods](#methods) - Provides D-Bus discovery related functionality.
11- [Associations](#associations) - Associates two different objects with each other.
12
13## Methods
14
15The official YAML interface definition can be found [here][1].
16
17### GetObject
18
19Use this method to find the services, with their interfaces, that implement
20a certain object path.  The output is a map of service names to their
21implemented interfaces.  An optional list of interfaces may also be passed in
22to constrain the output to services that implement those specific interfaces.
23
24Inputs:
25- path: object path
26- param: interfaces - an optional list of interfaces to constrain the search to
27
28Output:
29- Map of service names to their interfaces
30
31```
32dbus-send --system --print-reply \
33--dest=xyz.openbmc_project.ObjectMapper \
34/xyz/openbmc_project/object_mapper \
35xyz.openbmc_project.ObjectMapper.GetObject \
36string:"/xyz/openbmc_project/sensors/voltage/ps1_input_voltage" array:string:
37
38   array [
39      dict entry(
40         string "xyz.openbmc_project.Hwmon-1025936882.Hwmon1"
41         array [
42            string "xyz.openbmc_project.Sensor.Threshold.Critical"
43            string "xyz.openbmc_project.Sensor.Threshold.Warning"
44            string "xyz.openbmc_project.Sensor.Value"
45         ]
46      )
47   ]
48```
49
50#### Example Use Case
51Find the service name that has the desired object path so it can be passed into
52a get property call.
53
54### GetSubTree
55
56Use this method to find the objects, services, and interfaces in the specified
57subtree that implement a certain interface.  If no interfaces are passed in,
58then all objects/services/interfaces in the subtree are returned.  If interfaces
59are passed in, then only those interfaces are returned in the output.
60
61Inputs:
62- param: subtree - the root of the tree.  Using "/" will search the whole tree
63- param: depth - the maximum depth of the tree past the root to search. Use 0 to search all
64- param: interfaces - an optional list of interfaces to constrain the search to
65
66Output:
67- Map of object paths to a map of service names to their interfaces
68
69```
70dbus-send --system --print-reply \
71--dest=xyz.openbmc_project.ObjectMapper \
72/xyz/openbmc_project/object_mapper \
73xyz.openbmc_project.ObjectMapper.GetSubTree \
74string:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
75
76   array [
77      dict entry(
78         string "/xyz/openbmc_project/sensors/current/ps0_output_current"
79         array [
80            dict entry(
81               string "xyz.openbmc_project.Hwmon-1040041051.Hwmon1"
82               array [
83                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
84                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
85                  string "xyz.openbmc_project.Sensor.Value"
86               ]
87            )
88         ]
89      )
90      dict entry(
91         string "/xyz/openbmc_project/sensors/current/ps1_output_current"
92         array [
93            dict entry(
94               string "xyz.openbmc_project.Hwmon-1025936882.Hwmon1"
95               array [
96                  string "xyz.openbmc_project.Sensor.Threshold.Critical"
97                  string "xyz.openbmc_project.Sensor.Threshold.Warning"
98                  string "xyz.openbmc_project.Sensor.Value"
99               ]
100            )
101         ]
102      )
103...
104
105```
106
107#### Example Use Case
108Find all object paths and services that implement a specific interface.
109
110### GetSubTreePaths
111This is the same as GetSubTree, but only returns object paths
112
113Inputs:
114- param: subtree - the root of the tree.  Using "/" will search the whole tree
115- param: depth - the maximum depth of the tree past the root to search. Use 0 to search all
116- param: interfaces - an optional list of interfaces to constrain the search to
117
118Output:
119- array of object paths in that subtree
120
121```
122dbus-send --system --print-reply \
123--dest=xyz.openbmc_project.ObjectMapper \
124/xyz/openbmc_project/object_mapper \
125xyz.openbmc_project.ObjectMapper.GetSubTreePaths \
126string:"/" int32:0 array:string:"xyz.openbmc_project.Sensor.Threshold.Warning"
127
128   array [
129      string "/xyz/openbmc_project/sensors/current/ps0_output_current"
130      string "/xyz/openbmc_project/sensors/current/ps1_output_current"
131      string "/xyz/openbmc_project/sensors/power/ps0_input_power"
132...
133   ]
134```
135
136#### Example Use Case
137Find all object paths that implement a specific interface.
138
139### GetAncestors
140Use this method to find all ancestors of an object that implement a specific
141interface.  If no interfaces are passed in, then all ancestor
142paths/services/interfaces are returned.
143
144Inputs:
145- param: path - the object path to find the ancestors of
146- param: interfaces - an optional list of interfaces to constrain the search to
147
148Output:
149- A map of object paths to a map of services names to their interfaces
150
151```
152
153dbus-send --system --print-reply \
154--dest=xyz.openbmc_project.ObjectMapper \
155/xyz/openbmc_project/object_mapper \
156xyz.openbmc_project.ObjectMapper.GetAncestors \
157string:"/xyz/openbmc_project/inventory/system" array:string:
158
159   array [
160      dict entry(
161         string "/xyz/openbmc_project"
162         array [
163            dict entry(
164               string "xyz.openbmc_project.ObjectMapper"
165               array [
166                  string "org.freedesktop.DBus.ObjectManager"
167               ]
168            )
169         ]
170      )
171      dict entry(
172         string "/xyz/openbmc_project/inventory"
173         array [
174            dict entry(
175               string "xyz.openbmc_project.Inventory.Manager"
176               array [
177                  string "xyz.openbmc_project.Inventory.Manager"
178                  string "org.freedesktop.DBus.ObjectManager"
179               ]
180            )
181         ]
182      )
183      dict entry(
184         string "/"
185         array [
186            dict entry(
187               string "xyz.openbmc_project.Settings"
188               array [
189                  string "org.freedesktop.DBus.ObjectManager"
190               ]
191            )
192         ]
193      )
194   ]
195```
196
197#### Example Use Case
198Find a parent object that implements a specific interface.
199
200## Associations
201
202Associations are special D-Bus objects created by the mapper to associate two
203objects with each other.  For this to occur, some application must implement
204the `xyz.openbmc_project.Association.Definitions` interface, and then when an
205association is desired, the `Associations` property on that interface needs to
206be written.
207
208This `Associations` property is an array of tuples of the form:
209```
210[forward, reverse, object path]
211```
212- forward: this is the name of the forward association object
213- reverse: this is the name of the reverse association object
214- object path: this is the other object to associate with
215
216When an object with, for example, an object path of `pathA` uses
217the following values:
218```
219["foo", "bar", "pathB"]
220```
221The mapper will create 2 new objects:
222
2231. `pathA/foo`
2242. `pathB/bar`
225
226On each of these objects, the interface `xyz.openbmc_project.Association` will
227be implemented, which has a single `endpoints` property.  This property is
228an array that holds the object paths to the other end of the association.
229
230So, `pathA/foo->endpoints` will contain `pathB`, and `pathB/bar->endpoints`
231will contain `pathA`.
232
233If another object, say `pathC`, also has an association to `pathB`, then a
234second entry, `pathC`, will be added into `pathB`\'s endpoints property.
235
236These new objects will match the lifetime of the associated objects.
237For example, if `pathA` is deleted, then `pathA/foo` will also be deleted,
238and `pathA` will be removed from the endpoints property of `pathB/bar`.  If
239that was the last entry in that property, then `pathB/bar` will also be deleted.
240In addition, if the endpoint path is removed from D-Bus, in this case `pathB`,
241then the mapper will remove the 2 association paths until `pathB` shows back
242up again.
243
244Note: The original name of the association definition interface was
245`org.openbmc.Associations`. While the mapper still supports this interface as
246well for the time being, new code should use the `xyz` version.
247
248#### Example Use Case
249
250Associate an error log with the inventory item that caused it.
251
252```
253# Error log
254"/xyz/openbmc_project/logging/entry/3": {
255...
256 "associations": [
257   [
258     "callout",
259     "fault",
260     "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
261   ]
262 ]
263}
264
265# Newly created forward association object
266"/xyz/openbmc_project/logging/entry/3/callout": {
267    "endpoints": [
268    "/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0"
269    ]
270}
271
272# Newly created reverse association object
273"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0/fault": {
274    "endpoints": [
275    "/xyz/openbmc_project/logging/entry/3"
276    ]
277}
278
279```
280[1]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/ObjectMapper.interface.yaml
281