Branch data Line data Source code
1 : : /************************************************************************
2 : : * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes”
3 : : *
4 : : * Copyright (c) 2020 United States Government as represented by the
5 : : * Administrator of the National Aeronautics and Space Administration.
6 : : * All Rights Reserved.
7 : : *
8 : : * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 : : * not use this file except in compliance with the License. You may obtain
10 : : * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
11 : : *
12 : : * Unless required by applicable law or agreed to in writing, software
13 : : * distributed under the License is distributed on an "AS IS" BASIS,
14 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : : * See the License for the specific language governing permissions and
16 : : * limitations under the License.
17 : : ************************************************************************/
18 : :
19 : : /**
20 : : * @file
21 : : *
22 : : * Purpose:
23 : : * This header file contains all definitions for the cFE Software Bus
24 : : * Application Programmer's Interface.
25 : : *
26 : : * Author: R.McGraw/SSI
27 : : *
28 : : */
29 : :
30 : : #ifndef CFE_SB_H
31 : : #define CFE_SB_H
32 : :
33 : : /*
34 : : ** Includes
35 : : */
36 : : #include "common_types.h"
37 : : #include "cfe_error.h"
38 : : #include "cfe_sb_api_typedefs.h"
39 : : #include "cfe_es_api_typedefs.h"
40 : :
41 : : /*
42 : : ** Macro Definitions
43 : : */
44 : : #define CFE_BIT(x) (1 << (x)) /**< \brief Places a one at bit positions 0 - 31*/
45 : : #define CFE_SET(i, x) ((i) |= CFE_BIT(x)) /**< \brief Sets bit x of i */
46 : : #define CFE_CLR(i, x) ((i) &= ~CFE_BIT(x)) /**< \brief Clears bit x of i */
47 : : #define CFE_TST(i, x) (((i)&CFE_BIT(x)) != 0) /**< \brief true(non zero) if bit x of i is set */
48 : :
49 : : /****************** Function Prototypes **********************/
50 : :
51 : : /** @defgroup CFEAPISBPipe cFE Pipe Management APIs
52 : : * @{
53 : : */
54 : :
55 : : /*****************************************************************************/
56 : : /**
57 : : ** \brief Creates a new software bus pipe.
58 : : **
59 : : ** \par Description
60 : : ** This routine creates and initializes an input pipe that the calling
61 : : ** application can use to receive software bus messages. By default, no
62 : : ** messages are routed to the new pipe. So, the application must use
63 : : ** #CFE_SB_Subscribe to specify which messages it wants to receive on
64 : : ** this pipe.
65 : : **
66 : : ** \par Assumptions, External Events, and Notes:
67 : : ** None
68 : : **
69 : : ** \param[out] PipeIdPtr A pointer to a variable of type #CFE_SB_PipeId_t @nonnull,
70 : : ** which will be filled in with the pipe ID information
71 : : ** by the #CFE_SB_CreatePipe routine. *PipeIdPtr is the identifier for the created pipe.
72 : : **
73 : : ** \param[in] Depth The maximum number of messages that will be allowed on
74 : : ** this pipe at one time.
75 : : **
76 : : ** \param[in] PipeName A string @nonnull to be used to identify this pipe in error messages
77 : : ** and routing information telemetry. The string must be no
78 : : ** longer than #OS_MAX_API_NAME (including terminator).
79 : : ** Longer strings will be truncated.
80 : : **
81 : : ** \return Execution status, see \ref CFEReturnCodes
82 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
83 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
84 : : ** \retval #CFE_SB_MAX_PIPES_MET \copybrief CFE_SB_MAX_PIPES_MET
85 : : ** \retval #CFE_SB_PIPE_CR_ERR \copybrief CFE_SB_PIPE_CR_ERR
86 : : **
87 : : ** \sa #CFE_SB_DeletePipe #CFE_SB_GetPipeOpts #CFE_SB_SetPipeOpts #CFE_SB_GetPipeIdByName
88 : : **/
89 : : CFE_Status_t CFE_SB_CreatePipe(CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, const char *PipeName);
90 : :
91 : : /*****************************************************************************/
92 : : /**
93 : : ** \brief Delete a software bus pipe.
94 : : **
95 : : ** \par Description
96 : : ** This routine deletes an input pipe and cleans up all data structures
97 : : ** associated with the pipe. All subscriptions made for this pipe by
98 : : ** calls to #CFE_SB_Subscribe will be automatically removed from the
99 : : ** SB routing tables. Any messages in the pipe will be discarded.
100 : : **
101 : : ** Applications should not call this routine for all of their
102 : : ** SB pipes as part of their orderly shutdown process, as the
103 : : ** pipe will be deleted by the support framework at the
104 : : ** appropriate time.
105 : : **
106 : : ** \par Assumptions, External Events, and Notes:
107 : : ** None
108 : : **
109 : : ** \param[in] PipeId The pipe ID (obtained previously from #CFE_SB_CreatePipe)
110 : : ** of the pipe to be deleted.
111 : : **
112 : : ** \return Execution status, see \ref CFEReturnCodes
113 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
114 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
115 : : **
116 : : ** \sa #CFE_SB_CreatePipe #CFE_SB_GetPipeOpts #CFE_SB_SetPipeOpts #CFE_SB_GetPipeIdByName
117 : : **/
118 : : CFE_Status_t CFE_SB_DeletePipe(CFE_SB_PipeId_t PipeId);
119 : :
120 : : /**
121 : : * @brief Obtain an index value correlating to an SB Pipe ID
122 : : *
123 : : * This calculates a zero based integer value that may be used for indexing
124 : : * into a local resource table/array.
125 : : *
126 : : * Index values are only guaranteed to be unique for resources of the same
127 : : * type. For instance, the indices corresponding to two [valid] application
128 : : * IDs will never overlap, but the index of a pipe ID and an app ID
129 : : * may be the same. Furthermore, indices may be reused if a resource is
130 : : * deleted and re-created.
131 : : *
132 : : * @note There is no inverse of this function - indices cannot be converted
133 : : * back to the original PipeID value. The caller should retain the original ID
134 : : * for future use.
135 : : *
136 : : * @param[in] PipeID Pipe ID to convert
137 : : * @param[out] Idx Buffer where the calculated index will be stored @nonnull
138 : : *
139 : : * @return Execution status, see @ref CFEReturnCodes
140 : : * @retval #CFE_SUCCESS @copybrief CFE_SUCCESS
141 : : * @retval #CFE_ES_ERR_RESOURCEID_NOT_VALID @copybrief CFE_ES_ERR_RESOURCEID_NOT_VALID
142 : : */
143 : : CFE_Status_t CFE_SB_PipeId_ToIndex(CFE_SB_PipeId_t PipeID, uint32 *Idx);
144 : :
145 : : /*****************************************************************************/
146 : : /**
147 : : ** \brief Set options on a pipe.
148 : : **
149 : : ** \par Description
150 : : ** This routine sets (or clears) options to alter the pipe's behavior.
151 : : ** Options are (re)set every call to this routine.
152 : : **
153 : : ** \param[in] PipeId The pipe ID of the pipe to set options on.
154 : : **
155 : : ** \param[in] Opts A bit field of options: \ref CFESBPipeOptions
156 : : **
157 : : ** \return Execution status, see \ref CFEReturnCodes
158 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
159 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
160 : : **
161 : : ** \sa #CFE_SB_CreatePipe #CFE_SB_DeletePipe #CFE_SB_GetPipeOpts #CFE_SB_GetPipeIdByName #CFE_SB_PIPEOPTS_IGNOREMINE
162 : : **/
163 : : CFE_Status_t CFE_SB_SetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 Opts);
164 : :
165 : : /*****************************************************************************/
166 : : /**
167 : : ** \brief Get options on a pipe.
168 : : **
169 : : ** \par Description
170 : : ** This routine gets the current options on a pipe.
171 : : **
172 : : ** \param[in] PipeId The pipe ID of the pipe to get options from.
173 : : **
174 : : ** \param[out] OptsPtr A bit field of options: \ref CFESBPipeOptions @nonnull
175 : : **
176 : : ** \return Execution status, see \ref CFEReturnCodes
177 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
178 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
179 : : **
180 : : ** \sa #CFE_SB_CreatePipe #CFE_SB_DeletePipe #CFE_SB_SetPipeOpts #CFE_SB_GetPipeIdByName #CFE_SB_PIPEOPTS_IGNOREMINE
181 : : **/
182 : : CFE_Status_t CFE_SB_GetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 *OptsPtr);
183 : :
184 : : /*****************************************************************************/
185 : : /**
186 : : ** \brief Get the pipe name for a given id.
187 : : **
188 : : ** \par Description
189 : : ** This routine finds the pipe name for a pipe id.
190 : : **
191 : : ** \param[out] PipeNameBuf The buffer to receive the pipe name @nonnull.
192 : : **
193 : : ** \param[in] PipeNameSize The size (in chars) of the PipeName buffer @nonzero.
194 : : **
195 : : ** \param[in] PipeId The PipeId for that name.
196 : : **
197 : : ** \return Execution status, see \ref CFEReturnCodes
198 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
199 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
200 : : **
201 : : ** \sa #CFE_SB_CreatePipe #CFE_SB_DeletePipe #CFE_SB_SetPipeOpts #CFE_SB_GetPipeIdByName
202 : : **/
203 : : CFE_Status_t CFE_SB_GetPipeName(char *PipeNameBuf, size_t PipeNameSize, CFE_SB_PipeId_t PipeId);
204 : :
205 : : /*****************************************************************************/
206 : : /**
207 : : ** \brief Get pipe id by pipe name.
208 : : **
209 : : ** \par Description
210 : : ** This routine finds the pipe id for a pipe name.
211 : : **
212 : : ** \param[in] PipeName The name of the pipe @nonnull.
213 : : **
214 : : ** \param[out] PipeIdPtr The PipeId for that name @nonnull.
215 : : **
216 : : ** \return Execution status, see \ref CFEReturnCodes
217 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
218 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
219 : : **
220 : : ** \sa #CFE_SB_CreatePipe #CFE_SB_DeletePipe #CFE_SB_SetPipeOpts #CFE_SB_PIPEOPTS_IGNOREMINE
221 : : **/
222 : : CFE_Status_t CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName);
223 : : /**@}*/
224 : :
225 : : /** @defgroup CFEAPISBSubscription cFE Message Subscription Control APIs
226 : : * @{
227 : : */
228 : :
229 : : /*****************************************************************************/
230 : : /**
231 : : ** \brief Subscribe to a message on the software bus
232 : : **
233 : : ** \par Description
234 : : ** This routine adds the specified pipe to the destination list associated
235 : : ** with the specified message ID.
236 : : **
237 : : ** \par Assumptions, External Events, and Notes:
238 : : ** Note: As subscriptions are received, the destinations are added to
239 : : ** the head of a linked list. During the sending of a message, the list
240 : : ** is traversed beginning at the head of the list. Therefore the
241 : : ** message will first be sent to the last subscriber. If an application
242 : : ** has timing constraints and needs to receive a message in the
243 : : ** shortest possible time, the developer may consider holding off its
244 : : ** subscription until other applications have subscribed to the message.
245 : : **
246 : : ** \param[in] MsgId The message ID of the message to be subscribed to.
247 : : **
248 : : ** \param[in] PipeId The pipe ID of the pipe the subscribed message
249 : : ** should be sent to.
250 : : **
251 : : ** \param[in] Quality The requested Quality of Service (QoS) required of
252 : : ** the messages. Most callers will use #CFE_SB_DEFAULT_QOS
253 : : ** for this parameter.
254 : : **
255 : : ** \param[in] MsgLim The maximum number of messages with this Message ID to
256 : : ** allow in this pipe at the same time.
257 : : **
258 : : ** \return Execution status, see \ref CFEReturnCodes
259 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
260 : : ** \retval #CFE_SB_MAX_MSGS_MET \covtest \copybrief CFE_SB_MAX_MSGS_MET
261 : : ** \retval #CFE_SB_MAX_DESTS_MET \copybrief CFE_SB_MAX_DESTS_MET
262 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
263 : : ** \retval #CFE_SB_BUF_ALOC_ERR \covtest \copybrief CFE_SB_BUF_ALOC_ERR
264 : : **
265 : : ** \sa #CFE_SB_Subscribe, #CFE_SB_SubscribeLocal, #CFE_SB_Unsubscribe, #CFE_SB_UnsubscribeLocal
266 : : **/
267 : : CFE_Status_t CFE_SB_SubscribeEx(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, CFE_SB_Qos_t Quality, uint16 MsgLim);
268 : :
269 : : /*****************************************************************************/
270 : : /**
271 : : ** \brief Subscribe to a message on the software bus with default parameters
272 : : **
273 : : ** \par Description
274 : : ** This routine adds the specified pipe to the destination list for
275 : : ** the specified message ID. This is the same as #CFE_SB_SubscribeEx
276 : : ** with the Quality field set to #CFE_SB_DEFAULT_QOS and MsgLim set
277 : : ** to #CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT (4).
278 : : **
279 : : ** \par Assumptions, External Events, and Notes:
280 : : ** Note: As subscriptions are received, the destinations are added to
281 : : ** the head of a linked list. During the sending of a message, the list
282 : : ** is traversed beginning at the head of the list. Therefore the
283 : : ** message will first be sent to the last subscriber. If an application
284 : : ** has timing constraints and needs to receive a message in the
285 : : ** shortest possible time, the developer may consider holding off its
286 : : ** subscription until other applications have subscribed to the message.
287 : : **
288 : : ** \param[in] MsgId The message ID of the message to be subscribed to.
289 : : **
290 : : ** \param[in] PipeId The pipe ID of the pipe the subscribed message
291 : : ** should be sent to.
292 : : **
293 : : ** \return Execution status, see \ref CFEReturnCodes
294 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
295 : : ** \retval #CFE_SB_MAX_MSGS_MET \covtest \copybrief CFE_SB_MAX_MSGS_MET
296 : : ** \retval #CFE_SB_MAX_DESTS_MET \copybrief CFE_SB_MAX_DESTS_MET
297 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
298 : : ** \retval #CFE_SB_BUF_ALOC_ERR \covtest \copybrief CFE_SB_BUF_ALOC_ERR
299 : : **
300 : : ** \sa #CFE_SB_SubscribeEx, #CFE_SB_SubscribeLocal, #CFE_SB_Unsubscribe, #CFE_SB_UnsubscribeLocal
301 : : **/
302 : : CFE_Status_t CFE_SB_Subscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId);
303 : :
304 : : /*****************************************************************************/
305 : : /**
306 : : ** \brief Subscribe to a message while keeping the request local to a cpu
307 : : **
308 : : ** \par Description
309 : : ** This routine adds the specified pipe to the destination list for
310 : : ** the specified message ID. This is similar to #CFE_SB_SubscribeEx
311 : : ** with the Quality field set to #CFE_SB_DEFAULT_QOS and MsgLim set
312 : : ** to #CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT, but will not report the subscription.
313 : : **
314 : : ** Software Bus Network (SBN) application is an example use case,
315 : : ** where local subscriptions should not be reported to peers.
316 : : **
317 : : ** \par Assumptions, External Events, and Notes:
318 : : ** - This API is typically only used by Software Bus Network (SBN) Application
319 : : **
320 : : ** \param[in] MsgId The message ID of the message to be subscribed to.
321 : : **
322 : : ** \param[in] PipeId The pipe ID of the pipe the subscribed message
323 : : ** should be sent to.
324 : : **
325 : : ** \param[in] MsgLim The maximum number of messages with this Message ID to
326 : : ** allow in this pipe at the same time.
327 : : **
328 : : ** \return Execution status, see \ref CFEReturnCodes
329 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
330 : : ** \retval #CFE_SB_MAX_MSGS_MET \covtest \copybrief CFE_SB_MAX_MSGS_MET
331 : : ** \retval #CFE_SB_MAX_DESTS_MET \copybrief CFE_SB_MAX_DESTS_MET
332 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
333 : : ** \retval #CFE_SB_BUF_ALOC_ERR \covtest \copybrief CFE_SB_BUF_ALOC_ERR
334 : : **
335 : : ** \sa #CFE_SB_Subscribe, #CFE_SB_SubscribeEx, #CFE_SB_Unsubscribe, #CFE_SB_UnsubscribeLocal
336 : : **/
337 : : CFE_Status_t CFE_SB_SubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, uint16 MsgLim);
338 : :
339 : : /*****************************************************************************/
340 : : /**
341 : : ** \brief Remove a subscription to a message on the software bus
342 : : **
343 : : ** \par Description
344 : : ** This routine removes the specified pipe from the destination
345 : : ** list for the specified message ID.
346 : : **
347 : : ** \par Assumptions, External Events, and Notes:
348 : : ** If the Pipe is not subscribed to MsgId, the CFE_SB_UNSUB_NO_SUBS_EID
349 : : ** event will be generated and #CFE_SUCCESS will be returned
350 : : **
351 : : ** \param[in] MsgId The message ID of the message to be unsubscribed.
352 : : **
353 : : ** \param[in] PipeId The pipe ID of the pipe the subscribed message
354 : : ** should no longer be sent to.
355 : : **
356 : : ** \return Execution status, see \ref CFEReturnCodes
357 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
358 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
359 : : **
360 : : ** \sa #CFE_SB_Subscribe, #CFE_SB_SubscribeEx, #CFE_SB_SubscribeLocal, #CFE_SB_UnsubscribeLocal
361 : : **/
362 : : CFE_Status_t CFE_SB_Unsubscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId);
363 : :
364 : : /*****************************************************************************/
365 : : /**
366 : : ** \brief Remove a subscription to a message on the software bus on the current CPU
367 : : **
368 : : ** \par Description
369 : : ** This routine removes the specified pipe from the destination
370 : : ** list for the specified message ID on the current CPU.
371 : : **
372 : : ** \par Assumptions, External Events, and Notes:
373 : : ** This API is typically only used by Software Bus Network (SBN) Application.
374 : : ** If the Pipe is not subscribed to MsgId, the CFE_SB_UNSUB_NO_SUBS_EID
375 : : ** event will be generated and #CFE_SUCCESS will be returned
376 : : **
377 : : ** \param[in] MsgId The message ID of the message to be unsubscribed.
378 : : **
379 : : ** \param[in] PipeId The pipe ID of the pipe the subscribed message
380 : : ** should no longer be sent to.
381 : : **
382 : : ** \return Execution status, see \ref CFEReturnCodes
383 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
384 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
385 : : **
386 : : ** \sa #CFE_SB_Subscribe, #CFE_SB_SubscribeEx, #CFE_SB_SubscribeLocal, #CFE_SB_Unsubscribe
387 : : **/
388 : : CFE_Status_t CFE_SB_UnsubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId);
389 : : /**@}*/
390 : :
391 : : /** @defgroup CFEAPISBMessage cFE Send/Receive Message APIs
392 : : * @{
393 : : */
394 : :
395 : : /*****************************************************************************/
396 : : /**
397 : : ** \brief Transmit a message
398 : : **
399 : : ** \par Description
400 : : ** This routine copies the specified message into a software bus
401 : : ** buffer which is then transmitted to all subscribers. The
402 : : ** software bus will read the message ID from the message header to
403 : : ** determine which pipes should receive the message.
404 : : **
405 : : ** In general, the "UpdateHeader" parameter should be passed as "true"
406 : : ** if the message was newly constructed by the sender and is being sent
407 : : ** for the first time. When forwarding a message that originated from
408 : : ** an external entity (e.g. messages passing through CI or SBN), the
409 : : ** parameter should be passed as "false" to not overwrite existing data.
410 : : **
411 : : ** \par Assumptions, External Events, and Notes:
412 : : ** - This routine will not normally wait for the receiver tasks to
413 : : ** process the message before returning control to the caller's task.
414 : : ** - However, if a higher priority task is pending and subscribed to
415 : : ** this message, that task may get to run before returning
416 : : ** control to the caller.
417 : : ** - In previous versions of CFE, the boolean parameter referred to the
418 : : ** sequence number header of telemetry messages only. This has been
419 : : ** extended to apply more generically to any headers, as determined by
420 : : ** the CFE MSG implementation.
421 : : **
422 : : ** \param[in] MsgPtr A pointer to the message to be sent @nonnull. This must point
423 : : ** to the first byte of the message header.
424 : : ** \param[in] UpdateHeader Update the headers of the message
425 : : **
426 : : ** \return Execution status, see \ref CFEReturnCodes
427 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
428 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
429 : : ** \retval #CFE_SB_MSG_TOO_BIG \copybrief CFE_SB_MSG_TOO_BIG
430 : : ** \retval #CFE_SB_BUF_ALOC_ERR \covtest \copybrief CFE_SB_BUF_ALOC_ERR
431 : : **/
432 : : CFE_Status_t CFE_SB_TransmitMsg(const CFE_MSG_Message_t *MsgPtr, bool UpdateHeader);
433 : :
434 : : /*****************************************************************************/
435 : : /**
436 : : ** \brief Receive a message from a software bus pipe
437 : : **
438 : : ** \par Description
439 : : ** This routine retrieves the next message from the specified pipe.
440 : : ** If the pipe is empty, this routine will block until either a new
441 : : ** message comes in or the timeout value is reached.
442 : : **
443 : : ** \par Assumptions, External Events, and Notes:
444 : : ** Note - If an error occurs in this API, the *BufPtr value may be NULL or
445 : : ** random. Therefore, it is recommended that the return code be tested
446 : : ** for CFE_SUCCESS before processing the message.
447 : : **
448 : : ** \param[in, out] BufPtr A pointer to the software bus buffer to receive to @nonnull.
449 : : ** Typically a caller declares a ptr of type CFE_SB_Buffer_t
450 : : ** (i.e. CFE_SB_Buffer_t *Ptr) then gives the address of that
451 : : ** pointer (&Ptr) as this parameter. After a successful
452 : : ** receipt of a message, *BufPtr will point to the first
453 : : ** byte of the software bus buffer. This should be
454 : : ** used as a read-only pointer (in systems with an MMU,
455 : : ** writes to this pointer may cause a memory protection fault).
456 : : ** The *BufPtr is valid only until the next call to
457 : : ** CFE_SB_ReceiveBuffer for the same pipe.
458 : : **
459 : : ** \param[in] PipeId The pipe ID of the pipe containing the message to be obtained.
460 : : **
461 : : ** \param[in] TimeOut The number of milliseconds to wait for a new message if the
462 : : ** pipe is empty at the time of the call. This can also be set
463 : : ** to #CFE_SB_POLL for a non-blocking receive or
464 : : ** #CFE_SB_PEND_FOREVER to wait forever for a message to arrive.
465 : : **
466 : : ** \return Execution status, see \ref CFEReturnCodes
467 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
468 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
469 : : ** \retval #CFE_SB_TIME_OUT \copybrief CFE_SB_TIME_OUT
470 : : ** \retval #CFE_SB_PIPE_RD_ERR \covtest \copybrief CFE_SB_PIPE_RD_ERR
471 : : ** \retval #CFE_SB_NO_MESSAGE \copybrief CFE_SB_NO_MESSAGE
472 : : **/
473 : : CFE_Status_t CFE_SB_ReceiveBuffer(CFE_SB_Buffer_t **BufPtr, CFE_SB_PipeId_t PipeId, int32 TimeOut);
474 : : /** @} */
475 : :
476 : : /** @defgroup CFEAPISBZeroCopy cFE Zero Copy APIs
477 : : * @{
478 : : */
479 : :
480 : : /*****************************************************************************/
481 : : /**
482 : : ** \brief Get a buffer pointer to use for "zero copy" SB sends.
483 : : **
484 : : ** \par Description
485 : : ** This routine can be used to get a pointer to one of the software bus'
486 : : ** internal memory buffers that are used for sending messages. The caller
487 : : ** can use this memory buffer to build an SB message, then send it using
488 : : ** the CFE_SB_TransmitBuffer() function. This interface avoids an extra
489 : : ** copy of the message from the user's memory buffer to the software bus
490 : : ** internal buffer.
491 : : **
492 : : ** \par Assumptions, External Events, and Notes:
493 : : ** -# The pointer returned by CFE_SB_AllocateMessageBuffer() is only good for one
494 : : ** call to CFE_SB_TransmitBuffer().
495 : : ** -# Once a buffer has been successfully transmitted (as indicated by a successful
496 : : ** return from CFE_SB_TransmitBuffer()) the buffer becomes owned by the SB application.
497 : : ** It will automatically be freed by SB once all recipients have finished reading it.
498 : : ** -# Applications must not de-reference the message pointer (for reading
499 : : ** or writing) after the call to CFE_SB_TransmitBuffer().
500 : : ** -# If #CFE_SB_ReleaseMessageBuffer should be used only if a message is not transmitted
501 : : **
502 : : ** \param[in] MsgSize The size of the SB message buffer the caller wants
503 : : ** (including the SB message header).
504 : : **
505 : : ** \return A pointer to a memory buffer that message data can be written to
506 : : ** for use with CFE_SB_TransmitBuffer().
507 : : **/
508 : : CFE_SB_Buffer_t *CFE_SB_AllocateMessageBuffer(size_t MsgSize);
509 : :
510 : : /*****************************************************************************/
511 : : /**
512 : : ** \brief Release an unused "zero copy" buffer pointer.
513 : : **
514 : : ** \par Description
515 : : ** This routine can be used to release a pointer to one of the software
516 : : ** bus' internal memory buffers.
517 : : **
518 : : ** \par Assumptions, External Events, and Notes:
519 : : ** -# This function is not needed for normal "zero copy" transfers. It
520 : : ** is needed only for cleanup when an application gets a pointer using
521 : : ** CFE_SB_AllocateMessageBuffer(), but (due to some error condition) never
522 : : ** uses that pointer in a call to CFE_SB_TransmitBuffer().
523 : : **
524 : : ** \param[in] BufPtr A pointer to the SB internal buffer @nonnull. This must be a
525 : : ** pointer returned by a call to CFE_SB_AllocateMessageBuffer(),
526 : : ** but never used in a call to CFE_SB_TransmitBuffer().
527 : : **
528 : : ** \return Execution status, see \ref CFEReturnCodes
529 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
530 : : ** \retval #CFE_SB_BUFFER_INVALID \copybrief CFE_SB_BUFFER_INVALID
531 : : **/
532 : : CFE_Status_t CFE_SB_ReleaseMessageBuffer(CFE_SB_Buffer_t *BufPtr);
533 : :
534 : : /*****************************************************************************/
535 : : /**
536 : : ** \brief Transmit a buffer
537 : : **
538 : : ** \par Description
539 : : ** This routine sends a message that has been created directly in an
540 : : ** internal SB message buffer by an application (after a call to
541 : : ** #CFE_SB_AllocateMessageBuffer). This interface is more complicated than
542 : : ** the normal #CFE_SB_TransmitMsg interface, but it avoids an extra copy of
543 : : ** the message from the user's memory buffer to the software bus
544 : : ** internal buffer. The "zero copy" interface can be used to improve
545 : : ** performance in high-rate, high-volume software bus traffic.
546 : : **
547 : : ** In general, the "UpdateHeader" parameter should be passed as "true"
548 : : ** if the message was newly constructed by the sender and is being sent
549 : : ** for the first time. When forwarding a message that originated from
550 : : ** an external entity (e.g. messages passing through CI or SBN), the
551 : : ** parameter should be passed as "false" to not overwrite existing data.
552 : : **
553 : : ** \par Assumptions, External Events, and Notes:
554 : : ** -# A handle returned by #CFE_SB_AllocateMessageBuffer is "consumed" by
555 : : ** a _successful_ call to #CFE_SB_TransmitBuffer.
556 : : ** -# If this function returns CFE_SUCCESS, this indicates the zero copy handle is
557 : : ** now owned by software bus, and is no longer owned by the calling application,
558 : : ** and should not be re-used.
559 : : ** -# However if this function fails (returns any error status) it does not change
560 : : ** the state of the buffer at all, meaning the calling application still owns it.
561 : : ** (a failure means the buffer is left in the same state it was before the call).
562 : : ** -# Applications should be written as if #CFE_SB_AllocateMessageBuffer is
563 : : ** equivalent to a \c malloc() and a successful call to #CFE_SB_TransmitBuffer
564 : : ** is equivalent to a \c free().
565 : : ** -# Applications must not de-reference the message pointer (for reading
566 : : ** or writing) after a successful call to #CFE_SB_TransmitBuffer.
567 : : ** -# This function will increment and apply the internally tracked
568 : : ** sequence counter if set to do so.
569 : : **
570 : : ** \param[in] BufPtr A pointer to the buffer to be sent @nonnull.
571 : : ** \param[in] UpdateHeader Update the headers of the message
572 : : **
573 : : ** \return Execution status, see \ref CFEReturnCodes
574 : : ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS
575 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
576 : : ** \retval #CFE_SB_MSG_TOO_BIG \copybrief CFE_SB_MSG_TOO_BIG
577 : : **/
578 : : CFE_Status_t CFE_SB_TransmitBuffer(CFE_SB_Buffer_t *BufPtr, bool UpdateHeader);
579 : :
580 : : /** @} */
581 : :
582 : : /** @defgroup CFEAPISBMessageCharacteristics cFE Message Characteristics APIs
583 : : * @{
584 : : */
585 : :
586 : : /*****************************************************************************/
587 : : /**
588 : : ** \brief Sets the length of user data in a software bus message.
589 : : **
590 : : ** \par Description
591 : : ** This routine sets the field in the SB message header that determines
592 : : ** the size of the user data in a software bus message. SB message header
593 : : ** formats can be different for each deployment of the cFE. So, applications
594 : : ** should use this function rather than trying to poke a length value directly
595 : : ** into their SB message buffers.
596 : : **
597 : : ** \par Assumptions, External Events, and Notes:
598 : : ** - You must set a valid message ID in the SB message header before
599 : : ** calling this function.
600 : : **
601 : : ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message @nonnull.
602 : : ** This must point to the first byte of the message header.
603 : : **
604 : : ** \param[in] DataLength The length to set (size of the user data, in bytes).
605 : : **/
606 : : void CFE_SB_SetUserDataLength(CFE_MSG_Message_t *MsgPtr, size_t DataLength);
607 : :
608 : : /*****************************************************************************/
609 : : /**
610 : : ** \brief Sets the time field in a software bus message with the current spacecraft time.
611 : : **
612 : : ** \par Description
613 : : ** This routine sets the time of a software bus message with the current
614 : : ** spacecraft time. This will be the same time that is returned by the
615 : : ** function #CFE_TIME_GetTime.
616 : : **
617 : : ** \par Assumptions, External Events, and Notes:
618 : : ** - If the underlying implementation of software bus messages does not
619 : : ** include a time field, then this routine will do nothing.
620 : : **
621 : : ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message @nonnull.
622 : : ** This must point to the first byte of the message header.
623 : : **/
624 : : void CFE_SB_TimeStampMsg(CFE_MSG_Message_t *MsgPtr);
625 : :
626 : : /******************************************************************************/
627 : : /**
628 : : ** \brief Copies a string into a software bus message
629 : : **
630 : : ** \par Description
631 : : ** Strings within software bus messages have a defined/fixed maximum length, and
632 : : ** may not necessarily be null terminated within the message. This presents a possible
633 : : ** issue when using the C library functions to copy strings out of a message.
634 : : **
635 : : ** This performs a very similar function to "strncpy()" except that the sizes
636 : : ** of _both_ buffers are passed in. Neither buffer is required to be null-terminated,
637 : : ** but copying will stop after the first termination character is encountered.
638 : : **
639 : : ** If the destination buffer is not completely filled by the source data (such as if
640 : : ** the supplied string was shorter than the allotted length) the destination buffer
641 : : ** will be padded with NUL characters up to the size of the buffer, similar to what
642 : : ** strncpy() does. This ensures that the entire destination buffer is set.
643 : : **
644 : : ** \note
645 : : ** If the source string buffer is already guaranteed to be null terminated,
646 : : ** then there is no difference between the C library "strncpy()" function and this
647 : : ** implementation. It is only necessary to use this when termination of the source
648 : : ** buffer is not guaranteed.
649 : : **
650 : : ** \param[out] DestStringPtr Pointer to destination buffer (component of SB message definition) @nonnull
651 : : ** \param[in] SourceStringPtr Pointer to source buffer @nonnull
652 : : ** \param[in] DestMaxSize Size of destination buffer as defined by the message definition
653 : : ** \param[in] SourceMaxSize Size of source buffer
654 : : **
655 : : ** \return Number of characters copied or error code, see \ref CFEReturnCodes
656 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
657 : : **
658 : : */
659 : : int32 CFE_SB_MessageStringSet(char *DestStringPtr, const char *SourceStringPtr, size_t DestMaxSize,
660 : : size_t SourceMaxSize);
661 : :
662 : : /*****************************************************************************/
663 : : /**
664 : : ** \brief Get a pointer to the user data portion of a software bus message.
665 : : **
666 : : ** \par Description
667 : : ** This routine returns a pointer to the user data portion of a software
668 : : ** bus message. SB message header formats can be different for each
669 : : ** deployment of the cFE. So, applications should use this function and
670 : : ** avoid hard coding offsets into their SB message buffers.
671 : : **
672 : : ** \par Assumptions, External Events, and Notes:
673 : : ** None
674 : : **
675 : : ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message @nonnull.
676 : : **
677 : : ** \return A pointer to the first byte of user data within the software bus message.
678 : : **/
679 : : void *CFE_SB_GetUserData(CFE_MSG_Message_t *MsgPtr);
680 : :
681 : : /*****************************************************************************/
682 : : /**
683 : : ** \brief Gets the length of user data in a software bus message.
684 : : **
685 : : ** \par Description
686 : : ** This routine returns the size of the user data in a software bus message.
687 : : **
688 : : ** \par Assumptions, External Events, and Notes:
689 : : ** None
690 : : **
691 : : ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message @nonnull.
692 : : ** This must point to the first byte of the message header.
693 : : **
694 : : ** \return The size (in bytes) of the user data in the software bus message.
695 : : ** \retval 0 if an error occurs, such as if the MsgPtr argument is not valid.
696 : : **/
697 : : size_t CFE_SB_GetUserDataLength(const CFE_MSG_Message_t *MsgPtr);
698 : :
699 : : /******************************************************************************/
700 : : /**
701 : : ** \brief Copies a string out of a software bus message
702 : : **
703 : : ** \par Description
704 : : ** Strings within software bus messages have a defined/fixed maximum length, and
705 : : ** may not necessarily be null terminated within the message. This presents a possible
706 : : ** issue when using the C library functions to copy strings out of a message.
707 : : **
708 : : ** This function should replace use of C library functions such as strcpy/strncpy
709 : : ** when copying strings out of software bus messages to local storage buffers.
710 : : **
711 : : ** Up to [SourceMaxSize] or [DestMaxSize-1] (whichever is smaller) characters will be
712 : : ** copied from the source buffer to the destination buffer, and a NUL termination
713 : : ** character will be written to the destination buffer as the last character.
714 : : **
715 : : ** If the DefaultString pointer is non-NULL, it will be used in place of the source
716 : : ** string if the source is an empty string. This is typically a string constant that
717 : : ** comes from the platform configuration, allowing default values to be assumed for
718 : : ** fields that are unspecified.
719 : : **
720 : : ** IMPORTANT - the default string, if specified, must be null terminated. This will
721 : : ** be the case if a string literal is passed in (the typical/expected use case).
722 : : **
723 : : ** If the default is NULL, then only the source string will be copied, and the result
724 : : ** will be an empty string if the source was empty.
725 : : **
726 : : ** If the destination buffer is too small to store the entire string, it will be
727 : : ** truncated, but it will still be null terminated.
728 : : **
729 : : ** \param[out] DestStringPtr Pointer to destination buffer @nonnull
730 : : ** \param[in] SourceStringPtr Pointer to source buffer (component of SB message definition)
731 : : ** \param[in] DefaultString Default string to use if source is empty
732 : : ** \param[in] DestMaxSize Size of destination storage buffer @nonzero
733 : : ** \param[in] SourceMaxSize Size of source buffer as defined by the message definition
734 : : **
735 : : ** \return Number of characters copied or error code, see \ref CFEReturnCodes
736 : : ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT
737 : : **
738 : : */
739 : : int32 CFE_SB_MessageStringGet(char *DestStringPtr, const char *SourceStringPtr, const char *DefaultString,
740 : : size_t DestMaxSize, size_t SourceMaxSize);
741 : : /** @} */
742 : :
743 : : /** @defgroup CFEAPISBMessageID cFE Message ID APIs
744 : : * @{
745 : : */
746 : :
747 : : /*****************************************************************************/
748 : : /**
749 : : * \brief Identifies whether a given CFE_SB_MsgId_t is valid
750 : : *
751 : : * \par Description
752 : : * Implements a basic sanity check on the value provided
753 : : *
754 : : * \return Boolean message ID validity indicator
755 : : * \retval true Message ID is within the valid range
756 : : * \retval false Message ID is not within the valid range
757 : : */
758 : : bool CFE_SB_IsValidMsgId(CFE_SB_MsgId_t MsgId);
759 : :
760 : : /*****************************************************************************/
761 : : /**
762 : : * \brief Identifies whether two #CFE_SB_MsgId_t values are equal
763 : : *
764 : : * \par Description
765 : : * In cases where the #CFE_SB_MsgId_t type is not a simple integer
766 : : * type, it may not be possible to do a direct equality check.
767 : : * This inline function provides an abstraction for the equality
768 : : * check between two #CFE_SB_MsgId_t values.
769 : : *
770 : : * Applications should transition to using this function to compare
771 : : * MsgId values for equality to remain compatible with future versions
772 : : * of cFE.
773 : : *
774 : : * \return Boolean message ID equality indicator
775 : : * \retval true Message IDs are Equal
776 : : * \retval false Message IDs are not Equal
777 : : */
778 : 8734 : static inline bool CFE_SB_MsgId_Equal(CFE_SB_MsgId_t MsgId1, CFE_SB_MsgId_t MsgId2)
779 : : {
780 : 8734 : return CFE_SB_MSGID_UNWRAP_VALUE(MsgId1) == CFE_SB_MSGID_UNWRAP_VALUE(MsgId2);
781 : : }
782 : :
783 : : /*****************************************************************************/
784 : : /**
785 : : * \brief Converts a #CFE_SB_MsgId_t to a normal integer
786 : : *
787 : : * \par Description
788 : : * In cases where the #CFE_SB_MsgId_t type is not a simple integer
789 : : * type, it is not possible to directly display the value in a
790 : : * printf-style statement, use it in a switch() statement, or other
791 : : * similar use cases.
792 : : *
793 : : * This inline function provides the ability to map a #CFE_SB_MsgId_t
794 : : * type back into a simple integer value.
795 : : *
796 : : * Applications should transition to using this function wherever a
797 : : * #CFE_SB_MsgId_t type needs to be used as an integer.
798 : : *
799 : : * \par Assumptions and Notes:
800 : : * This negates the type safety that was gained by using a non-
801 : : * integer type for the #CFE_SB_MsgId_t value. This should only be used
802 : : * in specific cases such as UI display (printf, events, etc) where the
803 : : * value is being sent externally. Any internal API calls should be
804 : : * updated to use the #CFE_SB_MsgId_t type directly, rather than an
805 : : * integer type.
806 : : *
807 : : * \return Integer representation of the #CFE_SB_MsgId_t
808 : : */
809 : 26 : static inline CFE_SB_MsgId_Atom_t CFE_SB_MsgIdToValue(CFE_SB_MsgId_t MsgId)
810 : : {
811 : 26 : return CFE_SB_MSGID_UNWRAP_VALUE(MsgId);
812 : : }
813 : :
814 : : /*****************************************************************************/
815 : : /**
816 : : * \brief Converts a normal integer into a #CFE_SB_MsgId_t
817 : : *
818 : : * \par Description
819 : : * In cases where the #CFE_SB_MsgId_t type is not a simple integer
820 : : * type, it is not possible to directly use an integer value
821 : : * supplied via a define or similar method.
822 : : *
823 : : * This inline function provides the ability to map an integer value
824 : : * into a corresponding #CFE_SB_MsgId_t value.
825 : : *
826 : : * Applications should transition to using this function wherever an
827 : : * integer needs to be used for a #CFE_SB_MsgId_t.
828 : : *
829 : : * \par Assumptions and Notes:
830 : : * This negates the type safety that was gained by using a non-
831 : : * integer type for the #CFE_SB_MsgId_t value. This should only be
832 : : * used in specific cases where the value is coming from an external
833 : : * source. Any internal API calls should be updated to return the
834 : : * #CFE_SB_MsgId_t type directly, rather than an integer type.
835 : : *
836 : : * \return #CFE_SB_MsgId_t representation of the integer
837 : : */
838 : 48 : static inline CFE_SB_MsgId_t CFE_SB_ValueToMsgId(CFE_SB_MsgId_Atom_t MsgIdValue)
839 : : {
840 : 48 : CFE_SB_MsgId_t Result = CFE_SB_MSGID_C(MsgIdValue);
841 : 48 : return Result;
842 : : }
843 : : /** @} */
844 : :
845 : : #endif /* CFE_SB_H */
|