Safe API Framework
0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Toggle main menu visibility
Loading...
Searching...
No Matches
rte_safestate.c
Go to the documentation of this file.
1
6
#include "
rte/utils/safestate/rte_safestate.h
"
7
#include "
rte/utils/lifecycle/rte_lifecycle.h
"
8
10
12
15
static
rte_safestate_handler_t
s_handlers
[3] = { NULL, NULL, NULL };
16
18
27
static
bool
rte_safestate_level_to_index
(
rte_safestate_level_t
level,
size_t
*out_index);
28
29
31
rte_status_t
rte_safestate_register_handler
(
rte_safestate_level_t
level,
32
rte_safestate_handler_t
handler)
33
{
34
size_t
index;
35
rte_status_t
lifecycle_status;
36
37
if
((handler == NULL) || (!
rte_safestate_level_to_index
(level, &index)))
38
{
39
return
RTE_STATUS_INVALID_PARAM
;
40
}
41
/* REQ-LIFECYCLE-001 (ADR-026): a safe-state handler is a setup-only
42
* resource - refuse once the application's setup phase has been locked. */
43
lifecycle_status =
rte_lifecycle_check_setup_allowed
();
44
if
(lifecycle_status !=
RTE_STATUS_OK
)
45
{
46
return
lifecycle_status;
47
}
48
s_handlers
[index] = handler;
49
return
RTE_STATUS_OK
;
50
}
51
52
void
rte_safestate_enter
(
rte_safestate_level_t
level,
53
rte_safestate_reason_t
reason,
54
const
char
*file,
55
int32_t line,
56
const
char
*message)
57
{
58
size_t
index;
59
bool
valid_level =
rte_safestate_level_to_index
(level, &index);
60
rte_safestate_handler_t
handler = NULL;
61
62
if
(valid_level)
63
{
64
handler =
s_handlers
[index];
65
}
66
67
if
(handler != NULL)
68
{
69
handler(level, reason, file, line, message);
70
}
71
72
/* REQ-COMMON-SAFESTATE-002: SAFE and REBOOT never return control to the
73
* caller - not even if the handler above misbehaved and returned, and
74
* not even if no handler was registered at all. An unrecognized level
75
* value is itself treated as a fault and handled the same defensive
76
* way, since a corrupted `level` argument cannot be trusted to mean
77
* DEGRADED. */
78
if
((!valid_level) || (level ==
RTE_SAFESTATE_LEVEL_SAFE
) || (level ==
RTE_SAFESTATE_LEVEL_REBOOT
))
79
{
80
for
(;;)
/* GCOVR_EXCL_LINE - see tests/safestate/test_rte_safestate.c's
81
* test_unrecognized_level_halts_forever() for why: this line
82
* IS proven to execute at runtime (via a SIGALRM escape),
83
* but gcov's flow-graph line-count reconstruction always
84
* reports 0 for a `for(;;){}` with no outgoing edge,
85
* regardless of how many times it actually ran - a tool
86
* limitation, not a real gap. */
87
{
88
/* Defensive halt: intentionally never returns. */
89
}
90
}
91
}
92
93
94
/****Local functions ****/
95
96
static
bool
rte_safestate_level_to_index
(
rte_safestate_level_t
level,
size_t
*out_index)
97
{
98
bool
found;
99
100
switch
(level)
101
{
102
case
RTE_SAFESTATE_LEVEL_DEGRADED
:
103
*out_index = 0U;
104
found =
true
;
105
break
;
106
case
RTE_SAFESTATE_LEVEL_SAFE
:
107
*out_index = 1U;
108
found =
true
;
109
break
;
110
case
RTE_SAFESTATE_LEVEL_REBOOT
:
111
*out_index = 2U;
112
found =
true
;
113
break
;
114
default
:
115
found =
false
;
116
break
;
117
}
118
return
found;
119
}
rte_lifecycle_check_setup_allowed
rte_status_t rte_lifecycle_check_setup_allowed(void)
Convenience check for a setup-only constructor: call this as one of the first checks in any function ...
Definition
rte_lifecycle.c:41
rte_safestate_level_t
rte_safestate_level_t
Safe-state severity levels (ADR-004 section 2.1).
Definition
rte_safestate.h:42
rte_safestate_register_handler
rte_status_t rte_safestate_register_handler(rte_safestate_level_t level, rte_safestate_handler_t handler)
Registers the reaction handler for one safe-state level. This is how an integrator supplies their own...
Definition
rte_safestate.c:31
rte_safestate_reason_t
uint16_t rte_safestate_reason_t
Diagnostic reason code accompanying a safe-state transition.
Definition
rte_safestate.h:63
rte_safestate_enter
void rte_safestate_enter(rte_safestate_level_t level, rte_safestate_reason_t reason, const char *file, int32_t line, const char *message)
Enters a safe-state level: invokes the registered handler (if any), then, for RTE_SAFESTATE_LEVEL_SAF...
Definition
rte_safestate.c:52
rte_safestate_handler_t
void(*) rte_safestate_handler_t(rte_safestate_level_t level, rte_safestate_reason_t reason, const char *file, int32_t line, const char *message)
Application-supplied reaction for one safe-state level.
Definition
rte_safestate.h:102
RTE_SAFESTATE_LEVEL_REBOOT
@ RTE_SAFESTATE_LEVEL_REBOOT
Definition
rte_safestate.h:53
RTE_SAFESTATE_LEVEL_DEGRADED
@ RTE_SAFESTATE_LEVEL_DEGRADED
Definition
rte_safestate.h:45
RTE_SAFESTATE_LEVEL_SAFE
@ RTE_SAFESTATE_LEVEL_SAFE
Definition
rte_safestate.h:49
rte_status_t
rte_status_t
Common result/status codes.
Definition
rte_status.h:27
RTE_STATUS_OK
@ RTE_STATUS_OK
Definition
rte_status.h:28
RTE_STATUS_INVALID_PARAM
@ RTE_STATUS_INVALID_PARAM
Definition
rte_status.h:29
rte_lifecycle.h
Process-wide application setup-phase lock (ADR-026).
rte_safestate_level_to_index
static bool rte_safestate_level_to_index(rte_safestate_level_t level, size_t *out_index)
Maps a level enumerator to its handler-array index.
Definition
rte_safestate.c:96
s_handlers
static rte_safestate_handler_t s_handlers[3]
Definition
rte_safestate.c:15
rte_safestate.h
Safe-state transitions and checked assertions (ADR-004).
src
utils
safestate
rte_safestate.c
Generated by
1.18.0