message_basics/
message_basics.rs

1//! Message basics example.
2//!
3//! This example demonstrates how to create, serialize, and parse
4//! SOME/IP messages without network transport.
5//!
6//! Run with: cargo run --example message_basics
7
8use someip_rs::{
9    ClientId, MethodId, ReturnCode, ServiceId, SessionId, SomeIpHeader, SomeIpMessage,
10    HEADER_SIZE,
11};
12
13fn main() {
14    println!("=== SOME/IP Message Basics ===\n");
15
16    // Example 1: Create a request message using the builder
17    println!("--- Example 1: Building Messages ---");
18    let request = SomeIpMessage::request(ServiceId(0x1234), MethodId(0x0001))
19        .client_id(ClientId(0x0100))
20        .session_id(SessionId(0x0001))
21        .interface_version(2)
22        .payload(b"Hello, World!".as_slice())
23        .build();
24
25    println!("Request message:");
26    print_message(&request);
27
28    // Example 2: Create a response from the request
29    println!("\n--- Example 2: Creating Responses ---");
30    let response = request
31        .create_response()
32        .payload(b"Response data".as_slice())
33        .build();
34
35    println!("Response message:");
36    print_message(&response);
37
38    // Example 3: Create an error response
39    println!("\n--- Example 3: Error Response ---");
40    let error = request
41        .create_error_response(ReturnCode::UnknownMethod)
42        .build();
43
44    println!("Error response:");
45    print_message(&error);
46
47    // Example 4: Serialize and deserialize
48    println!("\n--- Example 4: Serialization ---");
49    let bytes = request.to_bytes();
50    println!("Serialized to {} bytes", bytes.len());
51    println!("Header bytes: {:02X?}", &bytes[..HEADER_SIZE]);
52    println!("Payload bytes: {:02X?}", &bytes[HEADER_SIZE..]);
53
54    let parsed = SomeIpMessage::from_bytes(&bytes).expect("Failed to parse");
55    println!("\nParsed message matches original: {}", parsed == request);
56
57    // Example 5: Working with headers directly
58    println!("\n--- Example 5: Header Details ---");
59    let header = SomeIpHeader::new(ServiceId(0xFFFF), MethodId(0x8001));
60    println!("Service ID: {}", header.service_id);
61    println!("Method ID: {} (is_event: {})", header.method_id, header.method_id.is_event());
62    println!("Message ID: 0x{:08X}", header.message_id());
63    println!("Request ID: 0x{:08X}", header.request_id());
64
65    // Example 6: Different message types
66    println!("\n--- Example 6: Message Types ---");
67
68    let notification = SomeIpMessage::notification(ServiceId(0x1234), MethodId::event(0x0001))
69        .payload(b"Event data".as_slice())
70        .build();
71    println!("Notification: type={:?}, method_id={} (is_event: {})",
72        notification.header.message_type,
73        notification.header.method_id,
74        notification.header.method_id.is_event()
75    );
76
77    let fire_and_forget = SomeIpMessage::request_no_return(ServiceId(0x1234), MethodId(0x0002))
78        .payload(b"Fire and forget".as_slice())
79        .build();
80    println!("Fire-and-forget: type={:?}, expects_response: {}",
81        fire_and_forget.header.message_type,
82        fire_and_forget.expects_response()
83    );
84
85    // Example 7: Return codes
86    println!("\n--- Example 7: Return Codes ---");
87    for code in [
88        ReturnCode::Ok,
89        ReturnCode::NotOk,
90        ReturnCode::UnknownService,
91        ReturnCode::UnknownMethod,
92        ReturnCode::Timeout,
93    ] {
94        println!("  {:?}: is_ok={}, value=0x{:02X}", code, code.is_ok(), code as u8);
95    }
96
97    println!("\n=== Done! ===");
98}
99
100fn print_message(msg: &SomeIpMessage) {
101    println!("  Service ID:        {}", msg.header.service_id);
102    println!("  Method ID:         {}", msg.header.method_id);
103    println!("  Client ID:         {}", msg.header.client_id);
104    println!("  Session ID:        {}", msg.header.session_id);
105    println!("  Protocol Version:  0x{:02X}", msg.header.protocol_version);
106    println!("  Interface Version: {}", msg.header.interface_version);
107    println!("  Message Type:      {:?}", msg.header.message_type);
108    println!("  Return Code:       {:?}", msg.header.return_code);
109    println!("  Length:            {} (payload: {} bytes)",
110        msg.header.length,
111        msg.payload.len()
112    );
113    if !msg.payload.is_empty() {
114        println!("  Payload:           {:?}", String::from_utf8_lossy(&msg.payload));
115    }
116}