This directory contains comprehensive examples demonstrating the RteFramework's Inter-Process Communication (IPC) patterns.
Overview
Two fundamental communication patterns for safety-critical systems:
- Request-Reply (RPC) — Synchronous client-server communication
- Publish-Subscribe (Events) — Asynchronous one-to-many broadcasting
Pattern 1: Request-Reply (RPC)
What It Is
Synchronous, bidirectional communication where a client sends a request and blocks (with timeout) waiting for a reply from the server.
┌────────────────────────────────────────────────┐
│ Train Controller (Client) │
│ │
│ 1. Create RPC client │
│ send query │
│ block waiting for reply (timeout=5s) │
│ } │
│ 3. Receive reply │
└────────────────┬────────────────────────────┘
│
┌────────────┴────────────┐
│ IPC Channel │
│ (Bounded Queue) │
└────────────┬────────────┘
│
┌────────────────▼────────────────────────────┐
│ Signal Database (Server) │
│ │
│ 1. Create RPC server │
│ block waiting for query (timeout=5s) │
│ } │
│ 3. Process query (deterministic) │
│ (sends back to client) │
└─────────────────────────────────────────────┘
rte_status_t rte_ipc_rr_send_reply(rte_ipc_rr_server_t server, uint32_t request_id, const void *reply_data, size_t reply_size)
Send reply to a request.
rte_status_t rte_ipc_rr_receive_request(rte_ipc_rr_server_t server, rte_ipc_rr_request_t *request_out, rte_duration_ms_t timeout_ms)
Receive a request (blocking with timeout).
rte_status_t rte_ipc_rr_request(rte_ipc_rr_client_t client, const void *request_data, size_t request_size, void *reply_out, size_t reply_size, rte_duration_ms_t timeout_ms)
Send request and wait for reply (blocking with timeout).
Example: ipc-request-reply-example.c
Scenario:** Train controller queries signal database
# Terminal 1 (Server)
./ipc-request-reply-example server
# Terminal 2 (Client) - in another terminal
./ipc-request-reply-example client
Safety Properties:**
- ✓ Deadlock-free (timeout prevents indefinite block)
- ✓ No message loss (synchronous, guaranteed delivery)
- ✓ Type-safe (fixed message sizes)
✓ Error handling (explicit status codes)
When to Use Request-Reply:**
- ✓ Commands that need confirmation (e.g., "turn on brake")
- ✓ Queries that need immediate answers (e.g., "what's my speed limit?")
- ✓ Synchronous RPC patterns
✓ Critical operations requiring proof of delivery
When NOT to Use:**
- ✗ One-to-many communication (use Pub-Sub instead)
- ✗ Asynchronous events (use Pub-Sub instead)
- ✗ Broadcast messages (use Pub-Sub instead)
Pattern 2: Publish-Subscribe (Events)
What It Is
Asynchronous, one-to-many communication where a publisher sends messages to multiple independent subscribers who all receive the same message.
┌──────────────────────────────────┐
│ Track Database (Publisher) │
│ (doesn't wait for replies) │
└──────────────┬───────────────────┘
│
┌──────────┴──────────┐
│ Topic: track_status│
│ (broadcast bus) │
└──────┬──────┬──────┬┘
│ │ │
┌────▼──┐ │ ┌──▼────┐
│ Queue │ │ │ Queue │
└────┬──┘ │ └──┬─────┘
│ │ │
┌──────▼──┐ │ ┌──▼─────┐
│ Signal │ │ │ Speed │ ... Route Manager
│ Manager │ │ │ Manager │
│ recv() │ │ │ recv() │
└─────────┘ │ └─────────┘
Subscriber 1 Subscriber 2 Subscriber 3
rte_status_t rte_ipc_pubsub_publish(rte_ipc_pubsub_topic_t topic, const void *message, size_t message_size)
Publish a message to all subscribers on a topic.
Example: ipc-pubsub-example.c
Scenario:** Track database publishes status changes; multiple managers react
./ipc-pubsub-example
# Output shows:
# [Publisher] Publishing track 1 status: Clear
# [Signal Manager] Track 1: Setting signal to GREEN
# [Speed Manager] Track 1: Speed limit = 100 km/h
# [Route Manager] Track 1 available - planning route
Safety Properties:**
- ✓ Decoupled (publisher doesn't know about subscribers)
- ✓ Scalable (add more subscribers without modifying publisher)
- ✓ Event-driven (subscribers wake when message arrives)
- ✓ Asynchronous (publisher doesn't wait)
✓ Type-safe (fixed message sizes)
When to Use Publish-Subscribe:**
- ✓ Broadcasting events (status changes, alarms)
- ✓ One-to-many communication
- ✓ Decoupling components
- ✓ Asynchronous notification
✓ Event-driven architecture
When NOT to Use:**
- ✗ Synchronous operations needing immediate reply (use Request-Reply)
- ✗ Point-to-point communication (use base IPC send/receive)
- ✗ Priority or order-sensitive messages (consider priority queues)
Comparison
| Aspect | Request-Reply | Publish-Subscribe |
| Direction | Bidirectional | Unidirectional (broadcast) |
| Synchronization | Synchronous (blocks) | Asynchronous (non-blocking) |
| Participants | 1 client, 1 server | 1 publisher, N subscribers |
| Coupling | Tight (client knows server) | Loose (decoupled) |
| Timeout | Required (prevents deadlock) | Optional (just wait) |
| Reply | Required by protocol | No reply needed |
| Scalability | 1:1 only | 1:many naturally |
| Use Case | Commands, queries, RPC | Events, notifications, broadcasts |
Building Examples
Using Build Script
From the project root:
./examples/build-linux-native.sh
This builds the framework and all examples.
Manual Build
# Build framework
mkdir -p build/linux
cd build/linux
cmake -S . -B .
cmake --build .
cd ../..
# Build examples (manually)
gcc -I./include -L./build/linux/src/ipc \
examples/ipc-request-reply-example.c \
build/linux/src/ipc/rte_ipc_request_reply.c \
build/linux/src/log/rte_log.c \
... (other modules) \
-lpthread -o ipc-request-reply-example
gcc -I./include -L./build/linux/src/ipc \
examples/ipc-pubsub-example.c \
build/linux/src/ipc/rte_ipc_pubsub.c \
build/linux/src/log/rte_log.c \
... (other modules) \
-lpthread -o ipc-pubsub-example
Real-World Railway Scenario
Architecture
┌─────────────────────────────────────────────────────┐
│ RBC (ERTMS) │
├─────────────────────────────────────────────────────┤
│ │
│ Track Manager Train Controller │
│ (publishes status) (queries signals) │
│ │ │ │
│ ├→ publish() └→ request() │
│ │ (status change) (blocks) │
│ │ (waits) │
│ └───────────┬───────────────────┘ │
│ │ │
│ ┌────────┴─────────┐ │
│ │ │ │
│ Signal Manager Speed Manager │
│ (subscribe) (subscribe) │
│ recv() recv() │
│ (async) (async) │
│ │
└─────────────────────────────────────────────────────┘
Message Flow
Scenario:** Train approaches signal; status changes
1. Track Manager publishes status update
"Track 5 is now OCCUPIED, speed limit 40"
2. Signal Manager receives event
→ Updates signal to YELLOW/RED
3. Speed Manager receives same event
→ Updates speed enforcer to 40 km/h
4. Train Controller (at same time)
→ Sends RPC query: "What's my speed limit?"
→ Signal Database replies synchronously: "40 km/h"
→ Train applies brakes
Key Insight:** Pub-Sub for asynchronous notifications, Request-Reply for synchronous queries.
API Reference
Request-Reply (RPC)
rte_status_t rte_ipc_rr_client_destroy(rte_ipc_rr_client_t client)
Destroy request-reply client connection.
rte_status_t rte_ipc_rr_server_destroy(rte_ipc_rr_server_t server)
Destroy request-reply server.
rte_status_t rte_ipc_rr_server_create(rte_ipc_rr_server_t *handle_out, const rte_ipc_rr_server_config_t *config)
Create a request-reply server channel.
rte_status_t rte_ipc_rr_client_create(rte_ipc_rr_client_t *handle_out, const rte_ipc_rr_client_config_t *config)
Create a request-reply client connection.
Publish-Subscribe
rte_status_t rte_ipc_pubsub_topic_destroy(rte_ipc_pubsub_topic_t topic)
Destroy a publish-subscribe topic.
rte_status_t rte_ipc_pubsub_receive(rte_ipc_pubsub_subscriber_t subscriber, void *message_out, size_t message_size, rte_duration_ms_t timeout_ms)
Receive a message from subscribed topic (blocking with timeout).
rte_status_t rte_ipc_pubsub_unsubscribe(rte_ipc_pubsub_subscriber_t subscriber)
Unsubscribe from a topic.
rte_status_t rte_ipc_pubsub_subscribe(rte_ipc_pubsub_subscriber_t *subscriber_out, const rte_ipc_pubsub_subscriber_config_t *config)
Subscribe to a topic.
rte_status_t rte_ipc_pubsub_topic_create(rte_ipc_pubsub_topic_t *topic_out, const rte_ipc_pubsub_topic_config_t *config)
Create a publish-subscribe topic.
Testing Checklist
- Request-Reply: Client successfully sends request
- Request-Reply: Server receives and processes request
- Request-Reply: Server sends reply
- Request-Reply: Client receives reply with correct data
- Request-Reply: Timeout works when server doesn't reply
- Pub-Sub: Publisher creates topic
- Pub-Sub: Multiple subscribers register
- Pub-Sub: Publisher sends message
- Pub-Sub: All subscribers receive same message
- Pub-Sub: Message order preserved
- Pub-Sub: Subscriber timeout works
- Safety: No deadlocks (timeouts prevent hanging)
- Safety: No message loss (explicit errors on failure)
- Safety: Type safety (fixed message sizes validated)
- Performance: Low latency (<10ms in typical case)
- Performance: No unbounded memory growth
References