Skip to content

Commit 3bebd0e

Browse files
committed
OFT branch merged with main
1 parent 570bb2c commit 3bebd0e

1 file changed

Lines changed: 81 additions & 31 deletions

File tree

src/lib.rs

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ use up_rust::{UListener, UMessage, UStatus, UTransport, UUri, UCode};
77
/// such as the service connection and active listeners.
88
pub struct Iceoryx2Transport {}
99

10+
enum MessageType {
11+
RpcRequest,
12+
RpcResponseOrNotification,
13+
Publish,
14+
}
15+
1016
// The #[async_trait] attribute enables async functions in our trait impl.
1117
#[async_trait]
1218
impl UTransport for Iceoryx2Transport {
@@ -49,48 +55,73 @@ impl Iceoryx2Transport {
4955
format!("{:X}", value)
5056
}
5157

52-
fn compute_service_name(source: &UUri,sink: Option<&UUri>) -> Result<String, UStatus> {
53-
let join_segments = |segments: Vec<String>| segments.join("/");
54-
55-
// [impl->dsn~up-transport-iceoryx2-service-name~1]
56-
// Handle RPC Request: source.resource_id == 0, valid sink (1<=sink.resource_id<=0x7FFF)
57-
if (source.resource_id==0 )&& !(sink.is_none()){
58-
if !((1<=sink.unwrap().resource_id && sink.unwrap().resource_id<=0x7FFF)){
59-
UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Invalid sink URI for RPC request");
58+
/// Assumption: valid source and sink URIs provided:
59+
/// send() makes use of UAttributesValidator
60+
/// register_listener() and unregister_listener() use verify_filter_criteria()
61+
/// Criteria for identification of message types can be found here: https://github.com/eclipse-uprotocol/up-spec/blob/main/basics/uattributes.adoc
62+
fn determine_message_type(source: &UUri, sink: Option<&UUri>) -> Result<MessageType, UStatus> {
63+
let src_id = source.resource_id;
64+
let sink_id = sink.map(|s| s.resource_id);
65+
66+
if src_id == 0 {
67+
if let Some(id) = sink_id {
68+
if id >= 1 && id <= 0x7FFF {
69+
return Ok(MessageType::RpcRequest);
70+
}
6071
}
61-
let segments = Self::encode_uuri_segments(sink.unwrap());
62-
Ok(format!("up/{}", join_segments(segments)))
72+
} else if sink_id == Some(0) && src_id >= 1 && src_id <= 0xFFFE {
73+
return Ok(MessageType::RpcResponseOrNotification);
74+
} else if src_id >= 1 && src_id <= 0x7FFF {
75+
return Ok(MessageType::Publish);
6376
}
77+
78+
Err(UStatus::fail_with_code(
79+
UCode::INVALID_ARGUMENT,
80+
"Unsupported UMessageType",
81+
))
82+
}
83+
fn compute_service_name(source: &UUri, sink: Option<&UUri>) -> Result<String, UStatus> {
84+
let join_segments = |segments: Vec<String>| segments.join("/");
6485
// [impl->dsn~up-transport-iceoryx2-service-name~1]
65-
// Handle Notification or RPC Response: sink.resource_id == 0, valid source(1<=source.resource_id<=0xFFFE)
66-
else if (!(sink.is_none()))&&(sink.unwrap().resource_id==0){
67-
if 1<=source.resource_id && source.resource_id <=0xFFFE{
86+
match Self::determine_message_type(source, sink)? {
87+
// [impl->dsn~up-transport-iceoryx2-service-name~1]
88+
MessageType::RpcRequest => {
89+
let Some(sink_uri) = sink else {
90+
return Err(UStatus::fail_with_code(
91+
UCode::INVALID_ARGUMENT,
92+
"sink required for RpcRequest",
93+
));
94+
};
95+
let segments = Self::encode_uuri_segments(sink_uri);
96+
Ok(format!("up/{}", join_segments(segments)))
97+
}
98+
// [impl->dsn~up-transport-iceoryx2-service-name~1]
99+
MessageType::RpcResponseOrNotification => {
100+
let Some(sink_uri) = sink else {
101+
return Err(UStatus::fail_with_code(
102+
UCode::INVALID_ARGUMENT,
103+
"sink required for ResponseOrNotification",
104+
));
105+
};
68106
let source_segments = Self::encode_uuri_segments(source);
69-
let sink_segments = Self::encode_uuri_segments(sink.unwrap());
107+
let sink_segments = Self::encode_uuri_segments(sink_uri);
70108
Ok(format!(
71-
"up/{}/{}",
72-
join_segments(source_segments),
73-
join_segments(sink_segments)
109+
"up/{}/{}",
110+
join_segments(source_segments),
111+
join_segments(sink_segments)
74112
))
75113
}
76-
else{
77-
Err(UStatus::fail_with_code(UCode::INVALID_ARGUMENT, "Invalid sink and source URIs"))}
78-
}
79-
// [impl->dsn~up-transport-iceoryx2-service-name~1]
80-
// Handle Publish: 1 <= source.resource_id <= 0x7FFF
81-
else if 1<=source.resource_id && source.resource_id<=0x7FFF {
82-
let segments = Self::encode_uuri_segments(source);
83-
Ok(format!("up/{}", join_segments(segments)))
84-
} else {
85-
Err(UStatus::fail_with_code(
86-
UCode::INVALID_ARGUMENT,
87-
"Unsupported UMessageType",
88-
))
114+
// [impl->dsn~up-transport-iceoryx2-service-name~1]
115+
MessageType::Publish => {
116+
let segments = Self::encode_uuri_segments(source);
117+
Ok(format!("up/{}", join_segments(segments)))
118+
}
89119
}
90-
91120
}
92121
}
93122

123+
124+
94125
#[cfg(test)]
95126
mod tests {
96127
use super::*;
@@ -148,4 +179,23 @@ mod tests {
148179
assert!(result.is_err());
149180
assert_eq!(result.unwrap_err().get_code(), UCode::INVALID_ARGUMENT);
150181
}
182+
183+
#[test]
184+
// [utest->dsn~up-transport-iceoryx2-service-name~1]
185+
fn test_fail_resource_id_error() {
186+
let source = test_uri("device1", 0x0000, 0x00CD, 0x04, 0x000);
187+
let sink = test_uri("device1", 0x0004, 0x3AB, 0x3, 0x0000);
188+
let result = Iceoryx2Transport::compute_service_name(&source, Some(&sink));
189+
assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT));
190+
}
191+
192+
#[test]
193+
// [utest->dsn~up-transport-iceoryx2-service-name~1]
194+
fn test_fail_missing_source_error() {
195+
let uuri = UUri::new();
196+
let sink = test_uri("device1", 0x0004, 0x3AB, 0x3, 0x000);
197+
let result = Iceoryx2Transport::compute_service_name(&uuri, Some(&sink));
198+
assert!(result.is_err_and(|err| err.get_code() == UCode::INVALID_ARGUMENT));
199+
}
151200
}
201+

0 commit comments

Comments
 (0)