aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2023-07-16 17:13:47 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2023-07-16 17:13:47 +0900
commitcde82311a1b300ce634234ef5acd0c3ed3a8b2bc (patch)
tree5f5314ac6cae48cde75b48147644838d1cda3990
parentd76688665d25007ee56a18958f574a6bc1891fee (diff)
downloadhinawa-rs-cde82311a1b300ce634234ef5acd0c3ed3a8b2bc.tar.gz
hinawa: regenerate crate
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r--hinawa/examples/read-quadlet.rs19
-rw-r--r--hinawa/src/auto/cycle_time.rs105
-rw-r--r--hinawa/src/auto/mod.rs3
-rw-r--r--hinawa/src/auto/versions.txt2
-rw-r--r--hinawa/src/cycle_time.rs72
-rw-r--r--hinawa/src/fw_fcp.rs211
-rw-r--r--hinawa/src/fw_node.rs40
-rw-r--r--hinawa/src/fw_req.rs214
-rw-r--r--hinawa/src/fw_resp.rs78
-rw-r--r--hinawa/src/lib.rs1
-rw-r--r--hinawa/src/subclass/fw_fcp.rs37
-rw-r--r--hinawa/src/subclass/fw_req.rs65
-rw-r--r--hinawa/src/subclass/fw_resp.rs91
13 files changed, 906 insertions, 32 deletions
diff --git a/hinawa/examples/read-quadlet.rs b/hinawa/examples/read-quadlet.rs
index 7510739..f42415e 100644
--- a/hinawa/examples/read-quadlet.rs
+++ b/hinawa/examples/read-quadlet.rs
@@ -23,15 +23,16 @@ fn main() {
let req = hinawa::FwReq::new();
let mut frames = [0; 4];
- req.transaction_sync(
- &node,
- FwTcode::ReadQuadletRequest,
- OFFSET,
- 4,
- &mut frames,
- 100,
- )
- .unwrap();
+ let _ = req
+ .transaction_with_tstamp(
+ &node,
+ FwTcode::ReadQuadletRequest,
+ OFFSET,
+ 4,
+ &mut frames,
+ 100,
+ )
+ .unwrap();
assert_eq!(0x31333934, u32::from_be_bytes(frames));
diff --git a/hinawa/src/auto/cycle_time.rs b/hinawa/src/auto/cycle_time.rs
new file mode 100644
index 0000000..a03e4ef
--- /dev/null
+++ b/hinawa/src/auto/cycle_time.rs
@@ -0,0 +1,105 @@
+// This file was generated by gir (https://github.com/gtk-rs/gir)
+// from
+// from gir-files (https://github.com/gtk-rs/gir-files)
+// DO NOT EDIT
+
+use glib::translate::*;
+use std::mem;
+
+glib::wrapper! {
+ /// A boxed object to express data of cycle time.
+ /// A [`CycleTime`][crate::CycleTime] expresses the value of cycle time of 1394 OHCI as well as Linux system
+ /// time referring to clock_id.
+ #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+ pub struct CycleTime(Boxed<ffi::HinawaCycleTime>);
+
+ match fn {
+ copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::hinawa_cycle_time_get_type(), ptr as *mut _) as *mut ffi::HinawaCycleTime,
+ free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::hinawa_cycle_time_get_type(), ptr as *mut _),
+ type_ => || ffi::hinawa_cycle_time_get_type(),
+ }
+}
+
+impl CycleTime {
+ /// Allocate and return an instance of [`CycleTime`][crate::CycleTime].
+ ///
+ /// # Returns
+ ///
+ /// An instance of [`CycleTime`][crate::CycleTime].
+ #[doc(alias = "hinawa_cycle_time_new")]
+ pub fn new() -> CycleTime {
+ unsafe { from_glib_full(ffi::hinawa_cycle_time_new()) }
+ }
+
+ /// Get the ID of clock for timestamp.
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `clock_id`
+ /// The numeric ID of clock source for the reference timestamp.
+ /// One of CLOCK_REALTIME(0), CLOCK_MONOTONIC(1), and CLOCK_MONOTONIC_RAW(4) is available
+ /// UAPI of Linux kernel.
+ #[doc(alias = "hinawa_cycle_time_get_clock_id")]
+ #[doc(alias = "get_clock_id")]
+ pub fn clock_id(&self) -> i32 {
+ unsafe {
+ let mut clock_id = mem::MaybeUninit::uninit();
+ ffi::hinawa_cycle_time_get_clock_id(self.to_glib_none().0, clock_id.as_mut_ptr());
+ let clock_id = clock_id.assume_init();
+ clock_id
+ }
+ }
+
+ /// Get the value of cycle time in 1394 OHCI controller.
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `raw`
+ /// The raw value for CYCLE_TIME register.
+ #[doc(alias = "hinawa_cycle_time_get_raw")]
+ #[doc(alias = "get_raw")]
+ pub fn raw(&self) -> u32 {
+ unsafe {
+ let mut raw = mem::MaybeUninit::uninit();
+ ffi::hinawa_cycle_time_get_raw(self.to_glib_none().0, raw.as_mut_ptr());
+ let raw = raw.assume_init();
+ raw
+ }
+ }
+
+ /// Get system time with enough size of strorage. The timestamp refers to clock_id available by
+ /// [`clock_id()`][Self::clock_id()].
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `tv_sec`
+ /// The second part of timestamp.
+ ///
+ /// ## `tv_nsec`
+ /// The nanosecond part of timestamp.
+ #[doc(alias = "hinawa_cycle_time_get_system_time")]
+ #[doc(alias = "get_system_time")]
+ pub fn system_time(&self) -> (i64, i32) {
+ unsafe {
+ let mut tv_sec = mem::MaybeUninit::uninit();
+ let mut tv_nsec = mem::MaybeUninit::uninit();
+ ffi::hinawa_cycle_time_get_system_time(
+ self.to_glib_none().0,
+ tv_sec.as_mut_ptr(),
+ tv_nsec.as_mut_ptr(),
+ );
+ let tv_sec = tv_sec.assume_init();
+ let tv_nsec = tv_nsec.assume_init();
+ (tv_sec, tv_nsec)
+ }
+ }
+}
+
+impl Default for CycleTime {
+ fn default() -> Self {
+ Self::new()
+ }
+}
diff --git a/hinawa/src/auto/mod.rs b/hinawa/src/auto/mod.rs
index e0b9a32..d67f108 100644
--- a/hinawa/src/auto/mod.rs
+++ b/hinawa/src/auto/mod.rs
@@ -15,6 +15,9 @@ pub use self::fw_req::FwReq;
mod fw_resp;
pub use self::fw_resp::FwResp;
+mod cycle_time;
+pub use self::cycle_time::CycleTime;
+
mod enums;
pub use self::enums::FwFcpError;
pub use self::enums::FwNodeError;
diff --git a/hinawa/src/auto/versions.txt b/hinawa/src/auto/versions.txt
index 1313169..4bb7a0b 100644
--- a/hinawa/src/auto/versions.txt
+++ b/hinawa/src/auto/versions.txt
@@ -1,3 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ c8a7a13d2c4d)
from
-from gir-files (https://github.com/gtk-rs/gir-files @ 7ebd4478b4a5)
+from gir-files (https://github.com/gtk-rs/gir-files @ faebfb303ca6)
diff --git a/hinawa/src/cycle_time.rs b/hinawa/src/cycle_time.rs
new file mode 100644
index 0000000..2806eea
--- /dev/null
+++ b/hinawa/src/cycle_time.rs
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: MIT
+use crate::*;
+
+impl CycleTime {
+ /// Get the value of cycle time in 1394 OHCI controller. The first element of array expresses the
+ /// value of sec field, up to 127. The second element of array expresses the value of cycle field,
+ /// up to 7999. The third element of array expresses the value of offset field, up to 3071.
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `fields`
+ /// The value of cycle time register of 1394
+ /// OHCI, including three elements; second, cycle, and offset in its order.
+ #[doc(alias = "hinawa_cycle_time_get_fields")]
+ pub fn fields(&mut self) -> [u16; 3] {
+ let mut fields = [0; 3];
+ unsafe {
+ ffi::hinawa_cycle_time_get_fields(self.to_glib_none_mut().0, &mut fields);
+ }
+ fields
+ }
+
+ /// Compute second count and cycle count from unsigned 16 bit integer value retrieved by Asynchronous
+ /// Transmit (AT), Asynchronous Receive(AR), Isochronous Transmit (IT), and Isochronous Receive (IR)
+ /// contexts of 1394 OHCI. The second count is completed with the internal value read from the
+ /// CYCLE_TIME register. For the precise computation, the method should be called in the condition
+ /// that the timing between receipt of time stamp and access to CYCLE_TIME register is within 8
+ /// seconds.
+ /// ## `tstamp`
+ /// The value of time stamp retrieved from each context of 1394 OHCI.
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `isoc_cycle`
+ /// The result to parse the time stamp. The
+ /// first element is for 7 bits of second field in the format of IEEE 1394 CYCLE_TIME
+ /// register, up to 127. The second element is for 13 bits of cycle field in the format,
+ /// up to 7,999.
+ #[doc(alias = "hinawa_cycle_time_compute_tstamp")]
+ pub fn compute_tstamp(&self, tstamp: u32) -> [u32; 2] {
+ let mut isoc_cycle = [0; 2];
+ unsafe {
+ ffi::hinawa_cycle_time_compute_tstamp(self.to_glib_none().0, tstamp, &mut isoc_cycle);
+ }
+ isoc_cycle
+ }
+
+ /// Parse second count and cycle count from unsigned 16 bit integer value retrieved by Asynchronous
+ /// Transmit (AT), Asynchronous Receive(AR), Isochronous Transmit (IT), and Isochronous Receive (IR)
+ /// contexts of 1394 OHCI.
+ /// ## `tstamp`
+ /// The value of time stamp retrieved from each context of 1394 OHCI.
+ ///
+ /// # Returns
+ ///
+ ///
+ /// ## `isoc_cycle`
+ /// The result to parse the time stamp. The
+ /// first element is for three order bits of second field in the format of IEEE 1394
+ /// CYCLE_TIME register, up to 7. The second element is for 13 bits of cycle field in
+ /// the format, up to 7,999.
+ #[doc(alias = "hinawa_cycle_time_parse_tstamp")]
+ pub fn parse_tstamp(tstamp: u32) -> [u32; 2] {
+ let mut isoc_cycle = [0; 2];
+ unsafe {
+ ffi::hinawa_cycle_time_parse_tstamp(tstamp, &mut isoc_cycle);
+ }
+ isoc_cycle
+ }
+}
diff --git a/hinawa/src/fw_fcp.rs b/hinawa/src/fw_fcp.rs
index ef52200..f345acf 100644
--- a/hinawa/src/fw_fcp.rs
+++ b/hinawa/src/fw_fcp.rs
@@ -7,43 +7,165 @@ use crate::*;
///
/// [`FwFcp`][struct@crate::FwFcp]
pub trait FwFcpExtManual {
+ /// Transfer command frame for FCP. When receiving response frame for FCP, `signal::FwFcp::responded`
+ /// signal is emitted.
+ ///
+ /// Each value of @tstamp is unsigned 16 bit integer including higher 3 bits for three low order bits
+ /// of second field and the rest 13 bits for cycle field in the format of IEEE 1394 CYCLE_TIMER register.
+ ///
+ /// If the version of kernel ABI for Linux FireWire subsystem is less than 6, each element of @tstamp
+ /// has invalid value (=G_MAXUINT16).
+ /// ## `cmd_frame`
+ /// An array with elements for request byte data. The value of this
+ /// argument should point to the array and immutable.
+ /// ## `timeout_ms`
+ /// The timeout to wait for response subaction of transaction for command frame.
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ ///
+ /// ## `tstamp`
+ /// The array with two elements for time stamps.
+ /// The first element is for the isochronous cycle at which the request arrived. The second
+ /// element is for the isochronous cycle at which the response was sent.
+ #[doc(alias = "hinawa_fw_fcp_command_with_tstamp")]
+ fn command_with_tstamp(
+ &self,
+ cmd_frame: &[u8],
+ timeout_ms: u32,
+ ) -> Result<[u32; 2], glib::Error>;
+
/// Finish the pair of asynchronous transaction for AV/C command and response transactions. The
- /// timeout_ms parameter is used to wait for response transaction since the command transaction is
- /// initiated, ignoring `property::FwFcp::timeout` property of instance. The timeout is not expanded in
- /// the case that AV/C INTERIM status is arrived, thus the caller should expand the timeout in
- /// advance for the case.
- /// ## `cmd`
+ /// timeout_ms parameter is used to wait for response transaction since the command transaction
+ /// is initiated, ignoring [property@FwFcp:timeout] property of instance. The timeout is not
+ /// expanded in the case that AV/C INTERIM status is arrived, thus the caller should expand the
+ /// timeout in advance for the case.
+ ///
+ /// ## `cmd_frame`
/// An array with elements for request byte data. The value of
/// this argument should point to the array and immutable.
- /// ## `resp`
+ /// ## `resp_frame`
/// An array with elements for response byte data. Callers
/// should give it for buffer with enough space against the request since this library
/// performs no reallocation. Due to the reason, the value of this argument should point to
/// the pointer to the array and immutable. The content of array is mutable.
/// ## `timeout_ms`
/// The timeout to wait for response transaction since command transactions finishes.
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ ///
+ /// ## `resp_size`
+ /// The size of response buffer consumed for response frame.
+ ///
#[doc(alias = "hinawa_fw_fcp_avc_transaction")]
fn avc_transaction(
&self,
- req_frame: &[u8],
+ cmd_frame: &[u8],
resp_frame: &mut [u8],
timeout_ms: u32,
) -> Result<usize, glib::Error>;
+
+ /// Finish the pair of asynchronous transaction for AV/C command and response transactions. The
+ /// timeout_ms parameter is used to wait for response transaction since the command transaction is
+ /// initiated, ignoring `property::FwFcp::timeout` property of instance. The timeout is not expanded in
+ /// the case that AV/C INTERIM status is arrived, thus the caller should expand the timeout in
+ /// advance for the case.
+ /// ## `cmd_frame`
+ /// An array with elements for request byte data. The value of
+ /// this argument should point to the array and immutable.
+ /// ## `resp_frame`
+ /// An array with elements for response byte data. Callers
+ /// should give it for buffer with enough space against the request since this library
+ /// performs no reallocation. Due to the reason, the value of this argument should point to
+ /// the pointer to the array and immutable. The content of array is mutable.
+ /// ## `timeout_ms`
+ /// The timeout to wait for response transaction since command transactions finishes.
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ ///
+ /// ## `tstamp`
+ /// The array with three elements for time
+ /// stamps. The first element is for the isochronous cycle at which the request was sent
+ /// for the command of FCP transaction. The second element is for the isochronous cycle at
+ /// which the response arrived for the command of FCP transaction. The third element is for
+ /// the isochronous cycle at which the request was sent for the response of FCP transaction.
+ #[doc(alias = "hinawa_fw_fcp_avc_transaction_with_tstamp")]
+ fn avc_transaction_with_tstamp(
+ &self,
+ cmd_frame: &[u8],
+ resp_frame: &mut Vec<u8>,
+ timeout_ms: u32,
+ ) -> Result<[u32; 3], glib::Error>;
+
/// Emitted when the node transfers asynchronous packet as response for FCP and the process
- /// successfully read the content of packet.
+ /// successfully read the content of packet, except for the case that `signal@FwFcp::responded2`
+ /// signal handler is already assigned.
+ ///
/// ## `frame`
/// The array with elements for byte
- /// data of response for FCP.
+ /// data of response for FCP.
#[doc(alias = "responded")]
fn connect_responded<F>(&self, f: F) -> SignalHandlerId
where
F: Fn(&Self, &[u8]) + 'static;
+
+ /// Emitted when the node transfers asynchronous packet as response for FCP and the process
+ /// successfully read the content of packet.
+ ///
+ /// The values of @tstamp is unsigned 16 bit integer including higher 3 bits for three low
+ /// order bits of second field and the rest 13 bits for cycle field in the format of IEEE
+ /// 1394 CYCLE_TIMER register.
+ ///
+ /// If the version of kernel ABI for Linux FireWire subsystem is less than 6, the value of
+ /// @tstamp argument has invalid value (=G_MAXUINT).
+ ///
+ /// ## `tstamp`
+ /// The time stamp at which the request arrived for the response of FCP
+ /// transaction.
+ /// ## `frame`
+ /// The array with elements for byte
+ /// data of response for FCP.
+ #[doc(alias = "responded2")]
+ fn connect_responded2<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, u32, &[u8]) + 'static;
}
impl<O: IsA<FwFcp>> FwFcpExtManual for O {
+ fn command_with_tstamp(
+ &self,
+ cmd_frame: &[u8],
+ timeout_ms: u32,
+ ) -> Result<[u32; 2], glib::Error> {
+ unsafe {
+ let mut tstamp = [0; 2];
+ let mut error = std::ptr::null_mut();
+
+ let _ = ffi::hinawa_fw_fcp_command_with_tstamp(
+ self.as_ref().to_glib_none().0,
+ cmd_frame.as_ptr(),
+ cmd_frame.len(),
+ &mut tstamp,
+ timeout_ms,
+ &mut error,
+ );
+
+ if error.is_null() {
+ Ok(tstamp)
+ } else {
+ Err(from_glib_full(error))
+ }
+ }
+ }
+
fn avc_transaction(
&self,
- req_frame: &[u8],
+ cmd_frame: &[u8],
resp_frame: &mut [u8],
timeout_ms: u32,
) -> Result<usize, glib::Error> {
@@ -53,8 +175,8 @@ impl<O: IsA<FwFcp>> FwFcpExtManual for O {
ffi::hinawa_fw_fcp_avc_transaction(
self.as_ref().to_glib_none().0,
- req_frame.as_ptr(),
- req_frame.len(),
+ cmd_frame.as_ptr(),
+ cmd_frame.len(),
&mut resp_frame.as_mut_ptr(),
&mut resp_frame_size,
timeout_ms,
@@ -69,6 +191,37 @@ impl<O: IsA<FwFcp>> FwFcpExtManual for O {
}
}
+ fn avc_transaction_with_tstamp(
+ &self,
+ cmd_frame: &[u8],
+ resp_frame: &mut Vec<u8>,
+ timeout_ms: u32,
+ ) -> Result<[u32; 3], glib::Error> {
+ unsafe {
+ let mut resp_frame_size = resp_frame.len();
+ let mut tstamp = [0; 3];
+ let mut error = std::ptr::null_mut();
+
+ let _ = ffi::hinawa_fw_fcp_avc_transaction_with_tstamp(
+ self.as_ref().to_glib_none().0,
+ cmd_frame.as_ptr(),
+ cmd_frame.len(),
+ &mut resp_frame.as_mut_ptr(),
+ &mut resp_frame_size,
+ &mut tstamp,
+ timeout_ms,
+ &mut error,
+ );
+
+ if error.is_null() {
+ resp_frame.truncate(resp_frame_size);
+ Ok(tstamp)
+ } else {
+ Err(from_glib_full(error))
+ }
+ }
+ }
+
fn connect_responded<F>(&self, f: F) -> SignalHandlerId
where
F: Fn(&Self, &[u8]) + 'static,
@@ -100,4 +253,38 @@ impl<O: IsA<FwFcp>> FwFcpExtManual for O {
)
}
}
+
+ fn connect_responded2<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, u32, &[u8]) + 'static,
+ {
+ unsafe extern "C" fn responded2_trampoline<P, F>(
+ this: *mut ffi::HinawaFwFcp,
+ tstamp: libc::c_uint,
+ frame: *const u8,
+ length: libc::c_uint,
+ f: glib::ffi::gpointer,
+ ) where
+ P: IsA<FwFcp>,
+ F: Fn(&P, u32, &[u8]) + 'static,
+ {
+ let f: &F = &*(f as *const F);
+ f(
+ &FwFcp::from_glib_borrow(this).unsafe_cast_ref(),
+ tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+ }
+ unsafe {
+ let f: std::boxed::Box<F> = std::boxed::Box::new(f);
+ connect_raw(
+ self.as_ptr() as *mut _,
+ b"responded2\0".as_ptr() as *const _,
+ Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
+ responded2_trampoline::<Self, F> as *const (),
+ )),
+ std::boxed::Box::into_raw(f),
+ )
+ }
+ }
}
diff --git a/hinawa/src/fw_node.rs b/hinawa/src/fw_node.rs
index 8e5927d..6a48d2d 100644
--- a/hinawa/src/fw_node.rs
+++ b/hinawa/src/fw_node.rs
@@ -10,10 +10,27 @@ pub trait FwNodeExtManual {
/// Get cached content of configuration ROM aligned to big-endian.
///
/// # Returns
+ ///
+ ///
+ /// ## `image`
/// The content of configuration ROM.
#[doc(alias = "hinawa_fw_node_get_config_rom")]
#[doc(alias = "get_config_rom")]
fn config_rom(&self) -> Result<&[u8], glib::Error>;
+
+ /// Read current value of CYCLE_TIME register in 1394 OHCI controller.
+ /// ## `clock_id`
+ /// The numeric ID of clock source for the reference timestamp. One of CLOCK_REALTIME(0),
+ /// CLOCK_MONOTONIC(1), and CLOCK_MONOTONIC_RAW(4) is available in UAPI of Linux kernel.
+ /// ## `cycle_time`
+ /// A [`CycleTime`][crate::CycleTime].
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ #[doc(alias = "hinawa_fw_node_read_cycle_time")]
+ fn read_cycle_time(&self, clock_id: i32, cycle_time: &mut CycleTime)
+ -> Result<(), glib::Error>;
}
impl<O: IsA<FwNode>> FwNodeExtManual for O {
@@ -37,4 +54,27 @@ impl<O: IsA<FwNode>> FwNodeExtManual for O {
}
}
}
+
+ fn read_cycle_time(
+ &self,
+ clock_id: i32,
+ cycle_time: &mut CycleTime,
+ ) -> Result<(), glib::Error> {
+ unsafe {
+ let mut error = std::ptr::null_mut();
+
+ let _ = ffi::hinawa_fw_node_read_cycle_time(
+ self.as_ref().to_glib_none().0,
+ clock_id,
+ &cycle_time.to_glib_none_mut().0,
+ &mut error,
+ );
+
+ if error.is_null() {
+ Ok(())
+ } else {
+ Err(from_glib_full(error))
+ }
+ }
+ }
}
diff --git a/hinawa/src/fw_req.rs b/hinawa/src/fw_req.rs
index 4700197..fe7d34e 100644
--- a/hinawa/src/fw_req.rs
+++ b/hinawa/src/fw_req.rs
@@ -33,6 +33,7 @@ pub trait FwReqExtManual {
length: usize,
frame: &mut [u8],
) -> Result<(), glib::Error>;
+
/// Execute request subaction of transaction to the given node according to given code, then wait
/// for response subaction within the given timeout. The `property::FwReq::timeout` property of
/// instance is ignored.
@@ -63,18 +64,121 @@ pub trait FwReqExtManual {
frame: &mut [u8],
timeout_ms: u32,
) -> Result<(), glib::Error>;
+
+ /// Execute request subaction of transactions to the given node according to given code. When the
+ /// response subaction arrives and running event dispatcher reads the contents,
+ /// `signal::FwReq::responded` signal handler is called.
+ /// ## `node`
+ /// A [`FwNode`][crate::FwNode].
+ /// ## `tcode`
+ /// A transaction code of [`FwTcode`][crate::FwTcode].
+ /// ## `addr`
+ /// A destination address of target device
+ /// ## `length`
+ /// The range of address in byte unit.
+ /// ## `frame`
+ /// An array with elements for byte data. Callers should
+ /// give it for buffer with enough space against the request since this library performs no
+ /// reallocation. Due to the reason, the value of this argument should point to the pointer
+ /// to the array and immutable. The content of array is mutable for read and lock
+ /// transaction.
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ #[doc(alias = "hinawa_fw_req_request")]
+ fn request<P: IsA<FwNode>>(
+ &self,
+ node: &P,
+ tcode: FwTcode,
+ addr: u64,
+ length: usize,
+ frame: &mut [u8],
+ ) -> Result<(), glib::Error>;
+
+ /// Execute request subaction of transaction to the given node according to given code, then wait
+ /// for response subaction within the given timeout. The `property::FwReq::timeout` property of
+ /// instance is ignored.
+ ///
+ /// Each value of @tstamp is unsigned 16 bit integer including higher 3 bits for three low order bits
+ /// of second field and the rest 13 bits for cycle field in the format of IEEE 1394 CYCLE_TIMER register.
+ ///
+ /// If the version of kernel ABI for Linux FireWire subsystem is less than 6, each element of @tstamp
+ /// has invalid value (=G_MAXUINT).
+ /// ## `node`
+ /// A [`FwNode`][crate::FwNode].
+ /// ## `tcode`
+ /// A transaction code of [`FwTcode`][crate::FwTcode].
+ /// ## `addr`
+ /// A destination address of target device
+ /// ## `length`
+ /// The range of address in byte unit.
+ /// ## `frame`
+ /// An array with elements for byte data. Callers should
+ /// give it for buffer with enough space against the request since this library performs no
+ /// reallocation. Due to the reason, the value of this argument should point to the pointer
+ /// to the array and immutable. The content of array is mutable for read and lock
+ /// transaction.
+ /// ## `timeout_ms`
+ /// The timeout to wait for response subaction of the transaction since request
+ /// subaction is initiated, in milliseconds.
+ ///
+ /// # Returns
+ ///
+ /// TRUE if the overall operation finishes successfully, otherwise FALSE.
+ ///
+ /// ## `tstamp`
+ /// The array with two elements for time stamps.
+ /// The first element is for the isochronous cycle at which the request was sent. The second
+ /// element is for the isochronous cycle at which the response arrived.
+ #[doc(alias = "hinawa_fw_req_transaction_with_tstamp")]
+ fn transaction_with_tstamp<P: IsA<FwNode>>(
+ &self,
+ node: &P,
+ tcode: FwTcode,
+ addr: u64,
+ length: usize,
+ frame: &mut [u8],
+ timeout_ms: u32,
+ ) -> Result<[u32; 2], glib::Error>;
+
/// Emitted when the unit transfers asynchronous packet as response subaction for the
/// transaction and the process successfully reads the content of packet from Linux firewire
- /// subsystem.
+ /// subsystem, except for the case that `signal@FwReq::responded2` signal handler is already
+ /// assigned.
+ ///
/// ## `rcode`
/// One of [`FwRcode`][crate::FwRcode].
/// ## `frame`
- /// The array with elements for
- /// byte data of response subaction for transaction.
+ /// The array with elements for byte data of response subaction for transaction.
#[doc(alias = "responded")]
fn connect_responded<F>(&self, f: F) -> SignalHandlerId
where
F: Fn(&Self, FwRcode, &[u8]) + 'static;
+
+ /// Emitted when the unit transfers asynchronous packet as response subaction for the
+ /// transaction and the process successfully reads the content of packet from Linux firewire
+ /// subsystem.
+ ///
+ /// The values of @request_tstamp and @response_tstamp are unsigned 16 bit integer including
+ /// higher 3 bits for three low order bits of second field and the rest 13 bits for cycle
+ /// field in the format of IEEE 1394 CYCLE_TIMER register.
+ ///
+ /// If the version of kernel ABI for Linux FireWire subsystem is less than 6, the
+ /// @request_tstamp and @response_tstamp argument has invalid value (=G_MAXUINT).
+ ///
+ /// ## `rcode`
+ /// One of [`FwRcode`][crate::FwRcode].
+ /// ## `request_tstamp`
+ /// The isochronous cycle at which the request was sent.
+ /// ## `response_tstamp`
+ /// The isochronous cycle at which the response arrived.
+ /// ## `frame`
+ /// The array with elements for byte data of response subaction for transaction.
+ #[doc(alias = "responded2")]
+ fn connect_responded2<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, FwRcode, u32, u32, &[u8]) + 'static;
}
impl<O: IsA<FwReq>> FwReqExtManual for O {
@@ -142,6 +246,72 @@ impl<O: IsA<FwReq>> FwReqExtManual for O {
}
}
+ fn request<P: IsA<FwNode>>(
+ &self,
+ node: &P,
+ tcode: FwTcode,
+ addr: u64,
+ length: usize,
+ frame: &mut [u8],
+ ) -> Result<(), glib::Error> {
+ unsafe {
+ let mut frame_size = frame.len();
+ let mut error = std::ptr::null_mut();
+
+ let _ = ffi::hinawa_fw_req_request(
+ self.as_ref().to_glib_none().0,
+ node.as_ref().to_glib_none().0,
+ tcode.into_glib(),
+ addr,
+ length,
+ &mut frame.as_mut_ptr(),
+ &mut frame_size,
+ &mut error,
+ );
+
+ if error.is_null() {
+ Ok(())
+ } else {
+ Err(from_glib_full(error))
+ }
+ }
+ }
+
+ fn transaction_with_tstamp<P: IsA<FwNode>>(
+ &self,
+ node: &P,
+ tcode: FwTcode,
+ addr: u64,
+ length: usize,
+ frame: &mut [u8],
+ timeout_ms: u32,
+ ) -> Result<[u32; 2], glib::Error> {
+ unsafe {
+ let mut frame_size = frame.len();
+ let mut tstamp = [0; 2];
+ let mut error = std::ptr::null_mut();
+
+ let _ = ffi::hinawa_fw_req_transaction_with_tstamp(
+ self.as_ref().to_glib_none().0,
+ node.as_ref().to_glib_none().0,
+ tcode.into_glib(),
+ addr,
+ length,
+ &mut frame.as_mut_ptr(),
+ &mut frame_size,
+ &mut tstamp,
+ timeout_ms,
+ &mut error,
+ );
+
+ if error.is_null() {
+ Ok(tstamp)
+ } else {
+ Err(from_glib_full(error))
+ }
+ }
+ }
+
fn connect_responded<F>(&self, f: F) -> SignalHandlerId
where
F: Fn(&Self, FwRcode, &[u8]) + 'static,
@@ -175,4 +345,42 @@ impl<O: IsA<FwReq>> FwReqExtManual for O {
)
}
}
+
+ fn connect_responded2<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, FwRcode, u32, u32, &[u8]) + 'static,
+ {
+ unsafe extern "C" fn responded2_trampoline<P, F>(
+ this: *mut ffi::HinawaFwReq,
+ rcode: ffi::HinawaFwRcode,
+ request_tstamp: libc::c_uint,
+ response_tstamp: libc::c_uint,
+ frame: *const u8,
+ length: libc::c_uint,
+ f: glib::ffi::gpointer,
+ ) where
+ P: IsA<FwReq>,
+ F: Fn(&P, FwRcode, u32, u32, &[u8]) + 'static,
+ {
+ let f: &F = &*(f as *const F);
+ f(
+ &FwReq::from_glib_borrow(this).unsafe_cast_ref(),
+ from_glib(rcode),
+ request_tstamp,
+ response_tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+ }
+ unsafe {
+ let f: std::boxed::Box<F> = std::boxed::Box::new(f);
+ connect_raw(
+ self.as_ptr() as *mut _,
+ b"responded2\0".as_ptr() as *const _,
+ Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
+ responded2_trampoline::<Self, F> as *const (),
+ )),
+ std::boxed::Box::into_raw(f),
+ )
+ }
+ }
}
diff --git a/hinawa/src/fw_resp.rs b/hinawa/src/fw_resp.rs
index 6e924d0..afdf9ac 100644
--- a/hinawa/src/fw_resp.rs
+++ b/hinawa/src/fw_resp.rs
@@ -7,10 +7,24 @@ use crate::*;
///
/// [`FwResp`][struct@crate::FwResp]
pub trait FwRespExtManual {
- /// Emitted when any node transfers request subaction to the range of address to which this
- /// object listening, the `signal::FwResp::requested` signal handler is called with arrived
- /// frame for the subaction. The handler is expected to call [`FwRespExt::set_resp_frame()`][crate::prelude::FwRespExt::set_resp_frame()]
- /// with frame and return [`FwRcode`][crate::FwRcode] for response subaction.
+ #[doc(alias = "requested2")]
+ fn connect_requested2<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, FwTcode, u64, u32, u32, u32, u32, &[u8]) -> FwRcode + 'static;
+
+ /// Emitted when any node transfers request subaction to the range of address in 1394 OHCI
+ /// controller to which this object listening.
+ ///
+ /// The handler is expected to call [`FwRespExt::set_resp_frame()`][crate::prelude::FwRespExt::set_resp_frame()] with frame and return
+ /// [`FwRcode`][crate::FwRcode] for response subaction.
+ ///
+ /// The value of @tstamp is unsigned 16 bit integer including higher 3 bits for three low
+ /// order bits of second field and the rest 13 bits for cycle field in the format of IEEE
+ /// 1394 CYCLE_TIMER register.
+ ///
+ /// If the version of kernel ABI for Linux FireWire subsystem is less than 6, the value of
+ /// tstamp argument has invalid value (=G_MAXUINT). Furthermore, if the version is less than
+ /// 4, the src, dst, card, generation arguments have invalid value (=G_MAXUINT).
/// ## `tcode`
/// One of [`FwTcode`][crate::FwTcode] enumerations
/// ## `offset`
@@ -23,6 +37,8 @@ pub trait FwRespExtManual {
/// The index of card corresponding to 1394 OHCI controller.
/// ## `generation`
/// The generation of bus when the transaction is transferred.
+ /// ## `tstamp`
+ /// The isochronous cycle at which the request arrived.
/// ## `frame`
/// The array with elements for byte
/// data.
@@ -31,10 +47,10 @@ pub trait FwRespExtManual {
///
/// One of [`FwRcode`][crate::FwRcode] enumerations corresponding to rcodes defined in IEEE 1394
/// specification.
- #[doc(alias = "requested")]
- fn connect_requested2<F>(&self, f: F) -> SignalHandlerId
+ #[doc(alias = "requested3")]
+ fn connect_requested3<F>(&self, f: F) -> SignalHandlerId
where
- F: Fn(&Self, FwTcode, u64, u32, u32, u32, u32, &[u8]) -> FwRcode + 'static;
+ F: Fn(&Self, FwTcode, u64, u32, u32, u32, u32, u32, &[u8]) -> FwRcode + 'static;
}
impl<O: IsA<FwResp>> FwRespExtManual for O {
@@ -83,4 +99,52 @@ impl<O: IsA<FwResp>> FwRespExtManual for O {
)
}
}
+
+ fn connect_requested3<F>(&self, f: F) -> SignalHandlerId
+ where
+ F: Fn(&Self, FwTcode, u64, u32, u32, u32, u32, u32, &[u8]) -> FwRcode + 'static,
+ {
+ unsafe extern "C" fn requested3_trampoline<P, F>(
+ this: *mut ffi::HinawaFwResp,
+ tcode: ffi::HinawaFwTcode,
+ offset: u64,
+ src: libc::c_uint,
+ dst: libc::c_uint,
+ card: libc::c_uint,
+ generation: libc::c_uint,
+ tstamp: libc::c_uint,
+ frame: *const u8,
+ length: libc::c_uint,
+ f: glib::ffi::gpointer,
+ ) -> ffi::HinawaFwRcode
+ where
+ P: IsA<FwResp>,
+ F: Fn(&P, FwTcode, u64, u32, u32, u32, u32, u32, &[u8]) -> FwRcode + 'static,
+ {
+ let f: &F = &*(f as *const F);
+ f(
+ &FwResp::from_glib_borrow(this).unsafe_cast_ref(),
+ from_glib(tcode),
+ offset,
+ src,
+ dst,
+ card,
+ generation,
+ tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+ .into_glib()
+ }
+ unsafe {
+ let f: std::boxed::Box<F> = std::boxed::Box::new(f);
+ connect_raw(
+ self.as_ptr() as *mut _,
+ b"requested3\0".as_ptr() as *const _,
+ Some(std::mem::transmute::<_, unsafe extern "C" fn()>(
+ requested3_trampoline::<Self, F> as *const (),
+ )),
+ std::boxed::Box::into_raw(f),
+ )
+ }
+ }
}
diff --git a/hinawa/src/lib.rs b/hinawa/src/lib.rs
index ecf2f56..90d6e59 100644
--- a/hinawa/src/lib.rs
+++ b/hinawa/src/lib.rs
@@ -3,6 +3,7 @@
#![doc = include_str!("../README.md")]
mod auto;
+mod cycle_time;
mod fw_fcp;
mod fw_node;
mod fw_req;
diff --git a/hinawa/src/subclass/fw_fcp.rs b/hinawa/src/subclass/fw_fcp.rs
index 18842b4..af76cca 100644
--- a/hinawa/src/subclass/fw_fcp.rs
+++ b/hinawa/src/subclass/fw_fcp.rs
@@ -7,11 +7,15 @@ pub trait FwFcpImpl: ObjectImpl + FwRespImpl {
fn responded(&self, fcp: &Self::Type, frame: &[u8]) {
self.parent_responded(fcp, frame)
}
+ fn responded2(&self, fcp: &Self::Type, tstamp: u32, frame: &[u8]) {
+ self.parent_responded2(fcp, tstamp, frame)
+ }
}
/// Trait which is automatically implemented to implementator of [`FwFcpImpl`][self::FwFcpImpl].
pub trait FwFcpImplExt: ObjectSubclass {
fn parent_responded(&self, fcp: &Self::Type, frame: &[u8]);
+ fn parent_responded2(&self, fcp: &Self::Type, tstamp: u32, frame: &[u8]);
}
impl<T: FwFcpImpl> FwFcpImplExt for T {
@@ -29,6 +33,21 @@ impl<T: FwFcpImpl> FwFcpImplExt for T {
)
}
}
+ fn parent_responded2(&self, fcp: &Self::Type, tstamp: u32, frame: &[u8]) {
+ unsafe {
+ let data = T::type_data();
+ let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwFcpClass;
+ let f = (*parent_class)
+ .responded2
+ .expect("No parent class implementation for \"responded2\"");
+ f(
+ fcp.unsafe_cast_ref::<FwFcp>().to_glib_none().0,
+ tstamp,
+ frame.as_ptr(),
+ frame.len() as u32,
+ )
+ }
+ }
}
unsafe impl<T: FwFcpImpl> IsSubclassable<T> for FwFcp {
@@ -37,6 +56,7 @@ unsafe impl<T: FwFcpImpl> IsSubclassable<T> for FwFcp {
let klass = class.as_mut();
klass.responded = Some(fw_fcp_responded::<T>);
+ klass.responded2 = Some(fw_fcp_responded2::<T>);
}
}
@@ -54,3 +74,20 @@ unsafe extern "C" fn fw_fcp_responded<T: FwFcpImpl>(
std::slice::from_raw_parts(frame, length as usize),
)
}
+
+unsafe extern "C" fn fw_fcp_responded2<T: FwFcpImpl>(
+ ptr: *mut ffi::HinawaFwFcp,
+ tstamp: c_uint,
+ frame: *const u8,
+ length: c_uint,
+) {
+ let instance = &*(ptr as *mut T::Instance);
+ let imp = instance.imp();
+ let wrap: Borrowed<FwFcp> = from_glib_borrow(ptr);
+
+ imp.responded2(
+ wrap.unsafe_cast_ref(),
+ tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+}
diff --git a/hinawa/src/subclass/fw_req.rs b/hinawa/src/subclass/fw_req.rs
index 6acf1f6..21c3a8f 100644
--- a/hinawa/src/subclass/fw_req.rs
+++ b/hinawa/src/subclass/fw_req.rs
@@ -7,11 +7,29 @@ pub trait FwReqImpl: ObjectImpl {
fn responded(&self, req: &Self::Type, rcode: FwRcode, frame: &[u8]) {
self.parent_responded(req, rcode, frame)
}
+ fn responded2(
+ &self,
+ req: &Self::Type,
+ rcode: FwRcode,
+ request_tstamp: u32,
+ response_tstamp: u32,
+ frame: &[u8],
+ ) {
+ self.parent_responded2(req, rcode, request_tstamp, response_tstamp, frame)
+ }
}
/// Trait which is automatically implemented to implementator of [`FwReqImpl`][self::FwReqImpl].
pub trait FwReqImplExt: ObjectSubclass {
fn parent_responded(&self, req: &Self::Type, rcode: FwRcode, frame: &[u8]);
+ fn parent_responded2(
+ &self,
+ req: &Self::Type,
+ rcode: FwRcode,
+ request_tstamp: u32,
+ response_tstamp: u32,
+ frame: &[u8],
+ );
}
impl<T: FwReqImpl> FwReqImplExt for T {
@@ -30,6 +48,31 @@ impl<T: FwReqImpl> FwReqImplExt for T {
)
}
}
+
+ fn parent_responded2(
+ &self,
+ req: &Self::Type,
+ rcode: FwRcode,
+ request_tstamp: u32,
+ response_tstamp: u32,
+ frame: &[u8],
+ ) {
+ unsafe {
+ let data = T::type_data();
+ let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwReqClass;
+ let f = (*parent_class)
+ .responded2
+ .expect("No parent class implementation for \"responded2\"");
+ f(
+ req.unsafe_cast_ref::<FwReq>().to_glib_none().0,
+ rcode.into_glib(),
+ request_tstamp,
+ response_tstamp,
+ frame.as_ptr(),
+ frame.len() as u32,
+ )
+ }
+ }
}
unsafe impl<T: FwReqImpl> IsSubclassable<T> for FwReq {
@@ -38,6 +81,7 @@ unsafe impl<T: FwReqImpl> IsSubclassable<T> for FwReq {
let klass = class.as_mut();
klass.responded = Some(fw_req_responded::<T>);
+ klass.responded2 = Some(fw_req_responded2::<T>);
}
}
@@ -57,3 +101,24 @@ unsafe extern "C" fn fw_req_responded<T: FwReqImpl>(
std::slice::from_raw_parts(frame, length as usize),
)
}
+
+unsafe extern "C" fn fw_req_responded2<T: FwReqImpl>(
+ ptr: *mut ffi::HinawaFwReq,
+ rcode: ffi::HinawaFwRcode,
+ request_tstamp: c_uint,
+ response_tstamp: c_uint,
+ frame: *const u8,
+ length: c_uint,
+) {
+ let instance = &*(ptr as *mut T::Instance);
+ let imp = instance.imp();
+ let wrap: Borrowed<FwReq> = from_glib_borrow(ptr);
+
+ imp.responded2(
+ wrap.unsafe_cast_ref(),
+ from_glib(rcode),
+ request_tstamp,
+ response_tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+}
diff --git a/hinawa/src/subclass/fw_resp.rs b/hinawa/src/subclass/fw_resp.rs
index 76f7e82..997db3a 100644
--- a/hinawa/src/subclass/fw_resp.rs
+++ b/hinawa/src/subclass/fw_resp.rs
@@ -17,6 +17,22 @@ pub trait FwRespImpl: ObjectImpl {
) -> FwRcode {
self.parent_requested2(resp, tcode, offset, src, dst, card, generation, frame)
}
+ fn requested3(
+ &self,
+ resp: &Self::Type,
+ tcode: FwTcode,
+ offset: u64,
+ src: u32,
+ dst: u32,
+ card: u32,
+ generation: u32,
+ tstamp: u32,
+ frame: &[u8],
+ ) -> FwRcode {
+ self.parent_requested3(
+ resp, tcode, offset, src, dst, card, generation, tstamp, frame,
+ )
+ }
}
/// Trait which is automatically implemented to implementator of [`FwRespImpl`][self::FwRespImpl].
@@ -32,6 +48,18 @@ pub trait FwRespImplExt: ObjectSubclass {
generation: u32,
frame: &[u8],
) -> FwRcode;
+ fn parent_requested3(
+ &self,
+ resp: &Self::Type,
+ tcode: FwTcode,
+ offset: u64,
+ src: u32,
+ dst: u32,
+ card: u32,
+ generation: u32,
+ tstamp: u32,
+ frame: &[u8],
+ ) -> FwRcode;
}
impl<T: FwRespImpl> FwRespImplExt for T {
@@ -65,6 +93,38 @@ impl<T: FwRespImpl> FwRespImplExt for T {
))
}
}
+ fn parent_requested3(
+ &self,
+ resp: &Self::Type,
+ tcode: FwTcode,
+ offset: u64,
+ src: u32,
+ dst: u32,
+ card: u32,
+ generation: u32,
+ tstamp: u32,
+ frame: &[u8],
+ ) -> FwRcode {
+ unsafe {
+ let data = T::type_data();
+ let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwRespClass;
+ let f = (*parent_class)
+ .requested3
+ .expect("No parent class implementation for \"requested3\"");
+ from_glib(f(
+ resp.unsafe_cast_ref::<FwResp>().to_glib_none().0,
+ tcode.into_glib(),
+ offset,
+ src,
+ dst,
+ card,
+ generation,
+ tstamp,
+ frame.as_ptr(),
+ frame.len() as u32,
+ ))
+ }
+ }
}
unsafe impl<T: FwRespImpl> IsSubclassable<T> for FwResp {
@@ -73,6 +133,7 @@ unsafe impl<T: FwRespImpl> IsSubclassable<T> for FwResp {
let klass = class.as_mut();
klass.requested2 = Some(fw_resp_requested2::<T>);
+ klass.requested3 = Some(fw_resp_requested3::<T>);
}
}
@@ -103,3 +164,33 @@ unsafe extern "C" fn fw_resp_requested2<T: FwRespImpl>(
)
.into_glib()
}
+
+unsafe extern "C" fn fw_resp_requested3<T: FwRespImpl>(
+ ptr: *mut ffi::HinawaFwResp,
+ tcode: ffi::HinawaFwTcode,
+ offset: u64,
+ src: u32,
+ dst: u32,
+ card: u32,
+ generation: u32,
+ tstamp: u32,
+ frame: *const u8,
+ length: c_uint,
+) -> ffi::HinawaFwRcode {
+ let instance = &*(ptr as *mut T::Instance);
+ let imp = instance.imp();
+ let wrap: Borrowed<FwResp> = from_glib_borrow(ptr);
+
+ imp.requested3(
+ wrap.unsafe_cast_ref(),
+ from_glib(tcode),
+ offset,
+ src,
+ dst,
+ card,
+ generation,
+ tstamp,
+ std::slice::from_raw_parts(frame, length as usize),
+ )
+ .into_glib()
+}