NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
control_message.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2025 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
27 
30 
31 namespace storage::control {
32 
33 uint32_t wire_size(storage::control::message_header const &hdr) noexcept
34 {
35  static_cast<void>(hdr);
36  return sizeof(message_header::wire_size);
37 }
38 
40 {
41  uint32_t size = sizeof(message::message_type) + sizeof(message::message_id) + sizeof(message::correlation_id);
42  switch (msg.message_type) {
44  size += sizeof(error_response_payload::error_code);
45  auto const *details = dynamic_cast<error_response_payload const *>(msg.payload.get());
46  if (details == nullptr) {
49  "[bug] Unable to calculate wire size for invalid error_response, no payload"};
50  }
51 
52  size += sizeof(uint32_t);
53  size += details->message.size();
54  } break;
58  } break;
60  size += sizeof(init_storage_payload::task_count);
61  size += sizeof(init_storage_payload::batch_size);
62  size += sizeof(init_storage_payload::core_count);
63 
64  auto const *details = dynamic_cast<init_storage_payload const *>(msg.payload.get());
65  if (details == nullptr) {
68  "[bug] Unable to calculate wire size for invalid init_storage_request, no payload"};
69  }
70 
71  size += sizeof(uint32_t);
72  size += details->mmap_export_blob.size();
73  } break;
78 
79  auto const *details = dynamic_cast<rdma_connection_details_payload const *>(msg.payload.get());
80  if (details == nullptr) {
83  "[bug] Unable to calculate wire size for invalid create_rdma_connection_xxx message, no payload"};
84  }
85 
86  size += sizeof(uint32_t);
87  size += details->connection_details.size();
88  } break;
97  break;
98  default:
100  "Unable to calculate wire size for unhandled message type: " +
101  to_string(msg.message_type)};
102  }
103 
104  return size;
105 }
106 
107 char *encode(char *buffer, storage::control::message_header const &hdr) noexcept
108 {
109  return storage::to_buffer(buffer, hdr.wire_size);
110 }
111 
112 char *encode(char *buffer, storage::control::message const &msg)
113 {
114  buffer = storage::to_buffer(buffer, static_cast<uint32_t>(msg.message_type));
115  buffer = storage::to_buffer(buffer, msg.message_id.value);
116  buffer = storage::to_buffer(buffer, msg.correlation_id.value);
117 
118  switch (msg.message_type) {
120  auto const *details = dynamic_cast<error_response_payload const *>(msg.payload.get());
121  if (details == nullptr) {
123  "[bug] Unable to encode invalid error_response, no payload"};
124  }
125 
126  buffer = storage::to_buffer(buffer, static_cast<uint32_t>(details->error_code));
127  buffer = storage::to_buffer(buffer, details->message);
128  } break;
130  auto const *details = dynamic_cast<storage_details_payload const *>(msg.payload.get());
131  if (details == nullptr) {
134  "[bug] Unable to encode invalid query_storage_response, no payload"};
135  }
136  buffer = storage::to_buffer(buffer, details->total_size);
137  buffer = storage::to_buffer(buffer, details->block_size);
138  } break;
140  auto const *details = dynamic_cast<init_storage_payload const *>(msg.payload.get());
141  if (details == nullptr) {
143  "[bug] Unable to encode invalid init_storage_request, no payload"};
144  }
145  buffer = storage::to_buffer(buffer, details->task_count);
146  buffer = storage::to_buffer(buffer, details->batch_size);
147  buffer = storage::to_buffer(buffer, details->core_count);
148  buffer = storage::to_buffer(buffer, details->mmap_export_blob);
149  } break;
152  auto const *details = dynamic_cast<rdma_connection_details_payload const *>(msg.payload.get());
153  if (details == nullptr) {
156  "[bug] Unable to encode invalid rdma_connection_details_payload, no payload"};
157  }
158  buffer = storage::to_buffer(buffer, details->context_idx);
159  buffer = storage::to_buffer(buffer, static_cast<uint32_t>(details->role));
160  buffer = storage::to_buffer(buffer, details->connection_details);
161  } break;
170  break;
171  default: {
173  "Unable to encode unhandled message type: " + to_string(msg.message_type)};
174  }
175  }
176 
177  return buffer;
178 }
179 
180 char const *decode(char const *buffer, storage::control::message_header &hdr) noexcept
181 {
182  return storage::from_buffer(buffer, hdr.wire_size);
183 }
184 
185 char const *decode(char const *buffer, storage::control::message &msg)
186 {
187  buffer = storage::from_buffer(buffer, reinterpret_cast<uint32_t &>(msg.message_type));
188  buffer = storage::from_buffer(buffer, msg.message_id.value);
189  buffer = storage::from_buffer(buffer, msg.correlation_id.value);
190 
191  switch (msg.message_type) {
193  auto details = std::make_unique<error_response_payload>();
194  buffer = storage::from_buffer(buffer, reinterpret_cast<uint32_t &>(details->error_code));
195  buffer = storage::from_buffer(buffer, details->message);
196  msg.payload = std::move(details);
197  } break;
199  auto details = std::make_unique<storage_details_payload>();
200  buffer = storage::from_buffer(buffer, details->total_size);
201  buffer = storage::from_buffer(buffer, details->block_size);
202  msg.payload = std::move(details);
203  } break;
205  auto details = std::make_unique<init_storage_payload>();
206  buffer = storage::from_buffer(buffer, details->task_count);
207  buffer = storage::from_buffer(buffer, details->batch_size);
208  buffer = storage::from_buffer(buffer, details->core_count);
209  buffer = storage::from_buffer(buffer, details->mmap_export_blob);
210  msg.payload = std::move(details);
211  } break;
214  auto details = std::make_unique<rdma_connection_details_payload>();
215 
216  buffer = storage::from_buffer(buffer, details->context_idx);
217  buffer = storage::from_buffer(buffer, reinterpret_cast<uint32_t &>(details->role));
218  buffer = storage::from_buffer(buffer, details->connection_details);
219  msg.payload = std::move(details);
220  } break;
229  break;
230  default: {
232  "Unable to decode unhandled message type: " + to_string(msg.message_type)};
233  }
234  }
235 
236  return buffer;
237 }
238 
240 {
241  switch (type) {
243  return "error_response";
245  return "query_storage_request";
247  return "query_storage_response";
249  return "init_storage_request";
251  return "init_storage_response";
253  return "create_rdma_connection_request";
255  return "create_rdma_connection_response";
257  return "start_storage_request";
259  return "start_storage_response";
261  return "stop_storage_request";
263  return "stop_storage_response";
265  return "shutdown_request";
267  return "shutdown_response";
268  }
269 
270  return "UNKNOWN(" + std::to_string(static_cast<uint32_t>(type)) + ")";
271 }
272 
274 {
275  switch (role) {
277  return "io_control";
279  return "io_data";
280  }
281 
282  return "UNKNOWN(" + std::to_string(static_cast<uint32_t>(role)) + ")";
283 }
284 
285 std::string to_string(storage::control::message const &msg)
286 {
287  std::string s;
288  s.reserve(512);
289  s += "control_message: {";
290  s += " cid: ";
292  s += ", mid: ";
293  s += std::to_string(msg.message_id.value);
294  s += ", ";
295  s += to_string(msg.message_type);
296  s += ": {";
297  switch (msg.message_type) {
299  auto const *details = dynamic_cast<error_response_payload const *>(msg.payload.get());
300  if (details == nullptr) {
302  "[bug] Unable to encode invalid error_response, no payload"};
303  }
304  s += "error_code: ";
305  s += doca_error_get_name(details->error_code);
306  s += ", message: \"";
307  s += details->message;
308  s += "\"";
309  } break;
311  auto const *details = dynamic_cast<storage_details_payload const *>(msg.payload.get());
312  if (details == nullptr) {
315  "[bug] Unable to encode invalid query_storage_response, no payload"};
316  }
317  s += "total_size: ";
318  s += std::to_string(details->total_size);
319  s += ", block_size: ";
320  s += std::to_string(details->block_size);
321  } break;
323  auto const *details = dynamic_cast<init_storage_payload const *>(msg.payload.get());
324  if (details == nullptr) {
326  "[bug] Unable to encode invalid init_storage_request, no payload"};
327  }
328  s += "task_count: ";
329  s += std::to_string(details->task_count);
330  s += ", batch_size: ";
331  s += std::to_string(details->batch_size);
332  s += ", core_count: ";
333  s += std::to_string(details->core_count);
334  s += ", mmap_export_blob: [";
335  storage::bytes_to_hex_str(reinterpret_cast<char const *>(details->mmap_export_blob.data()),
336  details->mmap_export_blob.size(),
337  s);
338  s += "]";
339  } break;
341  auto const *details = dynamic_cast<rdma_connection_details_payload const *>(msg.payload.get());
342  if (details == nullptr) {
345  "[bug] Unable to encode invalid create_rdma_connection_request, no payload"};
346  }
347  s += "context_idx: ";
348  s += std::to_string(details->context_idx);
349  s += ", role: ";
350  s += to_string(details->role);
351  s += ", connection_details: [";
352  storage::bytes_to_hex_str(reinterpret_cast<char const *>(details->connection_details.data()),
353  details->connection_details.size(),
354  s);
355  s += "]";
356  } break;
358  auto const *details = dynamic_cast<rdma_connection_details_payload const *>(msg.payload.get());
359  if (details == nullptr) {
362  "[bug] Unable to encode invalid create_rdma_connection_response, no payload"};
363  }
364  s += "context_idx: ";
365  s += std::to_string(details->context_idx);
366  s += ", role: ";
367  s += to_string(details->role);
368  s += ", connection_details: [";
369  storage::bytes_to_hex_str(reinterpret_cast<char const *>(details->connection_details.data()),
370  details->connection_details.size(),
371  s);
372  s += "]";
373  } break;
382  break;
383  default:
384  s += "UNKNOWN(" + std::to_string(static_cast<uint32_t>(msg.message_type)) + "): {}";
385  }
386 
387  s += "}}";
388  return s;
389 }
390 
391 } // namespace storage::control
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
@ DOCA_ERROR_INVALID_VALUE
Definition: doca_error.h:44
uint32_t wire_size(storage::control::message_header const &hdr) noexcept
std::string to_string(storage::control::message const &msg)
char * encode(char *buffer, storage::control::message_header const &hdr) noexcept
char const * decode(char const *buffer, storage::control::message_header &hdr) noexcept
std::string to_string(storage::control::message_type type)
std::string bytes_to_hex_str(char const *bytes, size_t byte_count)
char const * from_buffer(char const *buffer, T &value)
char * to_buffer(char *buffer, uint8_t value)
uint8_t type
Definition: packets.h:0
storage::control::correlation_id correlation_id
storage::control::message_id message_id
std::unique_ptr< storage::control::message::payload > payload
storage::control::message_type message_type
storage::control::rdma_connection_role role