Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
sapi_safestate.c
Go to the documentation of this file.
1
8
10
12
15static sapi_safestate_handler_t s_handlers[3] = { NULL, NULL, NULL };
16
18
27static bool sapi_safestate_level_to_index(sapi_safestate_level_t level, size_t *out_index);
28
29
33{
34 size_t index;
35 sapi_status_t lifecycle_status;
36
37 if ((handler == NULL) || (!sapi_safestate_level_to_index(level, &index)))
38 {
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 = sapi_lifecycle_check_setup_allowed();
44 if (lifecycle_status != SAPI_STATUS_OK)
45 {
46 return lifecycle_status;
47 }
48 s_handlers[index] = handler;
49 return SAPI_STATUS_OK;
50}
51
54 const char *file,
55 int32_t line,
56 const char *message)
57{
58 size_t index;
59 bool valid_level = sapi_safestate_level_to_index(level, &index);
60 sapi_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 == SAPI_SAFESTATE_LEVEL_SAFE) || (level == SAPI_SAFESTATE_LEVEL_REBOOT))
79 {
80 for (;;) /* GCOVR_EXCL_LINE - see tests/safestate/test_sapi_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
96static bool sapi_safestate_level_to_index(sapi_safestate_level_t level, size_t *out_index)
97{
98 bool found;
99
100 switch (level)
101 {
103 *out_index = 0U;
104 found = true;
105 break;
107 *out_index = 1U;
108 found = true;
109 break;
111 *out_index = 2U;
112 found = true;
113 break;
114 default:
115 found = false;
116 break;
117 }
118 return found;
119}
sapi_status_t sapi_lifecycle_check_setup_allowed(void)
Convenience check for a setup-only constructor: call this as one of the first checks in any function ...
sapi_status_t sapi_safestate_register_handler(sapi_safestate_level_t level, sapi_safestate_handler_t handler)
Registers the reaction handler for one safe-state level. This is how an integrator supplies their own...
uint16_t sapi_safestate_reason_t
Diagnostic reason code accompanying a safe-state transition.
sapi_safestate_level_t
Safe-state severity levels (ADR-004 section 2.1).
void sapi_safestate_enter(sapi_safestate_level_t level, sapi_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 SAPI_SAFESTATE_LEVEL_SA...
void(*) sapi_safestate_handler_t(sapi_safestate_level_t level, sapi_safestate_reason_t reason, const char *file, int32_t line, const char *message)
Application-supplied reaction for one safe-state level.
@ SAPI_SAFESTATE_LEVEL_REBOOT
@ SAPI_SAFESTATE_LEVEL_SAFE
@ SAPI_SAFESTATE_LEVEL_DEGRADED
sapi_status_t
Common result/status codes.
Definition sapi_status.h:27
@ SAPI_STATUS_INVALID_PARAM
Definition sapi_status.h:29
@ SAPI_STATUS_OK
Definition sapi_status.h:28
Process-wide application setup-phase lock (ADR-026).
static bool sapi_safestate_level_to_index(sapi_safestate_level_t level, size_t *out_index)
Maps a level enumerator to its handler-array index.
static sapi_safestate_handler_t s_handlers[3]
Safe-state transitions and checked assertions (ADR-004).