UART Command Interpreter
Title: Interpret Single-Character UART Commands via switch (with Mode & Lock Guards)
Level: Medium (focus on switch)
Concepts: switch statement, enumerations, default handling, guard checks inside cases, deterministic branching, no fall-through
Scenario
Your embedded device receives single-character commands over UART to control its behavior. The device can be in normal mode or maintenance mode, and it can be locked for safety. Depending on the incoming command and these mode/lock flags, the device must select an action or reject the request. You will implement the decision logic using a switch on the command.
Problem Statement
Implement a function that interprets a single ASCII command and returns an action enum using a switch. The function should validate the command, apply guards for maintenance_mode and locked, ensure no fall-through between cases, and handle unknown commands in the default case. The output action must only be written on success.
Requirements
- Allowed C types:
int,long,double,char,bool, andenum(and pointers/arrays of these). - Commands (
char cmd):'S'→ START'T'→ STOP'R'→ RESET'D'→ DIAGNOSTICS'U'→ UPDATE'Q'→ SHUTDOWN
- Guards / Policies:
- If
locked == true, only STOP ('T') and RESET ('R') are allowed; all others must be rejected. - If
maintenance_mode == false, DIAGNOSTICS ('D') and UPDATE ('U') are not permitted. - SHUTDOWN (
'Q') is allowed only whenlocked == false.
- If
- Outputs & return codes:
- On success: write
*out_actionand return0. - On error/violation: return a negative code and do not modify
*out_action.-1→ invalid output pointer-2→ invalid/unknown command (default case)-3→ disallowed by guards (mode/lock)
- On success: write
- No fall-through: each
casemust end inreturnorbreak(recommendreturnon each path). - Input is a single character; no need to process strings.
Function Details
- Name:
interpret_uart_command - Arguments:
char cmd— incoming ASCII command ('S','T','R','D','U','Q', or other)bool maintenance_mode— true when device is in maintenancebool locked— true when safety lock is engagedenum Action *out_action— output action
- Return Value:
int—0on success;-1invalid pointer;-2invalid command;-3disallowed by guards.
- Description:
Useswitch (cmd)with cases'S','T','R','D','U','Q'. In each case, apply guard checks usingifstatements inside the case, return-3when a guard blocks the action, otherwise set*out_actionto the mapped enum and return0. For any other character, return-2. Never modify*out_actionon any error return path.
Suggested enum (for your implementation):
enum Action {
ACT_NONE = 0,
ACT_START = 1,
ACT_STOP = 2,
ACT_RESET = 3,
ACT_DIAG = 4,
ACT_UPDATE = 5,
ACT_SHUTDOWN = 6
};
Solution Approach
- Validate
out_action != NULLfirst; return-1if invalid. switch (cmd):- For
'S': iflocked→-3; else setACT_START. - For
'T': allowed even whenlocked; setACT_STOP. - For
'R': allowed even whenlocked; setACT_RESET. - For
'D': if!maintenance_mode→-3; iflocked→-3; else setACT_DIAG. - For
'U': if!maintenance_mode→-3; iflocked→-3; else setACT_UPDATE. - For
'Q': iflocked→-3; else setACT_SHUTDOWN. default: return-2.
- For
- Ensure each case returns immediately to avoid fall-through.
- Do not write to
*out_actionon any error path.
Tasks to Perform
- Validate pointer: If
out_action == NULL, return-1. - Switch on
cmd:- Case 'S' (START): If
lockedreturn-3; else*out_action = ACT_START; return 0; - Case 'T' (STOP):
*out_action = ACT_STOP; return 0; - Case 'R' (RESET):
*out_action = ACT_RESET; return 0; - Case 'D' (DIAGNOSTICS): If
!maintenance_modereturn-3; iflockedreturn-3; else*out_action = ACT_DIAG; return 0; - Case 'U' (UPDATE): If
!maintenance_modereturn-3; iflockedreturn-3; else*out_action = ACT_UPDATE; return 0; - Case 'Q' (SHUTDOWN): If
lockedreturn-3; else*out_action = ACT_SHUTDOWN; return 0; - Default: return
-2(invalid/unknown command).
- Case 'S' (START): If
- No writes on error: On any negative return, ensure
*out_actionremains untouched.
Test Cases
| # | Inputs / Precondition | Expected Output | Notes |
|---|---|---|---|
| 1 | cmd='S', maintenance_mode=false, locked=false |
ret=0, *out_action=ACT_START |
Normal start |
| 2 | cmd='S', maintenance_mode=false, locked=true |
ret=-3 |
Start blocked by lock |
| 3 | cmd='T', maintenance_mode=false, locked=true |
ret=0, *out_action=ACT_STOP |
Stop allowed under lock |
| 4 | cmd='R', maintenance_mode=false, locked=true |
ret=0, *out_action=ACT_RESET |
Reset allowed under lock |
| 5 | cmd='D', maintenance_mode=false, locked=false |
ret=-3 |
Diagnostics blocked outside maintenance |
| 6 | cmd='D', maintenance_mode=true, locked=false |
ret=0, *out_action=ACT_DIAG |
Diagnostics allowed in maintenance |
| 7 | cmd='U', maintenance_mode=true, locked=true |
ret=-3 |
Update blocked by lock |
| 8 | cmd='Q', maintenance_mode=false, locked=false |
ret=0, *out_action=ACT_SHUTDOWN |
Shutdown allowed when unlocked |
| 9 | cmd='Q', maintenance_mode=false, locked=true |
ret=-3 |
Shutdown blocked by lock |
| 10 | cmd='X', maintenance_mode=false, locked=false |
ret=-2 |
Unknown command |
| 11 | out_action=NULL |
ret=-1 |
Invalid pointer |