libfdt: Add FdtNode::subnodes()

Bug: 277993056
Test: atest liblibfdt.integration_test
Change-Id: I8557b04c0fa4f4de28f6fdf79712dd5ee8f2b963
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index b573697..758df2a 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -21,7 +21,7 @@
 
 pub use iterators::{
     AddressRange, CellIterator, CompatibleIterator, MemRegIterator, RangesIterator, Reg,
-    RegIterator,
+    RegIterator, SubnodeIterator,
 };
 
 use core::cmp::max;
@@ -384,6 +384,25 @@
             .try_into()
             .map_err(|_| FdtError::Internal)
     }
+
+    /// Returns an iterator of subnodes
+    pub fn subnodes(&'a self) -> Result<SubnodeIterator<'a>> {
+        SubnodeIterator::new(self)
+    }
+
+    fn first_subnode(&self) -> Result<Option<Self>> {
+        // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+        let ret = unsafe { libfdt_bindgen::fdt_first_subnode(self.fdt.as_ptr(), self.offset) };
+
+        Ok(fdt_err_or_option(ret)?.map(|offset| FdtNode { fdt: self.fdt, offset }))
+    }
+
+    fn next_subnode(&self) -> Result<Option<Self>> {
+        // SAFETY: Accesses (read-only) are constrained to the DT totalsize.
+        let ret = unsafe { libfdt_bindgen::fdt_next_subnode(self.fdt.as_ptr(), self.offset) };
+
+        Ok(fdt_err_or_option(ret)?.map(|offset| FdtNode { fdt: self.fdt, offset }))
+    }
 }
 
 /// Mutable FDT node.