1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ResponseUnavailableReason {
    Unknown,
    SDRInUpdate,
    DeviceInFwUpdate,
    BMCInitializing,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CompletionCode {
    Success,
    NodeBusy,
    InvalidCommand,
    InvalidCommandForLun,
    ProcessingTimeout,
    OutOfSpace,
    ReservationCancelledOrInvalidId,
    RequestDataTruncated,
    RequestDataLenInvalid,
    RequestDataLengthLimitExceeded,
    ParameterOutOfRange,
    CannotReturnNumOfRequestedBytes,
    RequestedDatapointNotPresent,
    InvalidDataFieldInRequest,
    CommandIllegalForSensorOrRecord,
    ResponseUnavailable { reason: ResponseUnavailableReason },
    CannotExecuteDuplicateRequest,
    DestinationUnavailable,
    InsufficientPrivilege,
    CannotExecuteCommandInCurrentState,
    SubFunctionDisabled,
    Unspecified,
    Oem(u8),
    CommandSpecific(u8),
    Reserved(u8),
}

impl From<u8> for CompletionCode {
    fn from(value: u8) -> Self {
        match value {
            0x00 => Self::Success,
            0xC0 => Self::NodeBusy,
            0xC1 => Self::InvalidCommand,
            0xC2 => Self::InvalidCommandForLun,
            0xC3 => Self::ProcessingTimeout,
            0xC4 => Self::OutOfSpace,
            0xC5 => Self::ReservationCancelledOrInvalidId,
            0xC6 => Self::RequestDataTruncated,
            0xC7 => Self::RequestDataLenInvalid,
            0xC8 => Self::RequestDataLengthLimitExceeded,
            0xC9 => Self::ParameterOutOfRange,
            0xCA => Self::CannotReturnNumOfRequestedBytes,
            0xCB => Self::RequestedDatapointNotPresent,
            0xCC => Self::InvalidDataFieldInRequest,
            0xCD => Self::CommandIllegalForSensorOrRecord,
            0xCE => Self::ResponseUnavailable {
                reason: ResponseUnavailableReason::Unknown,
            },
            0xCF => Self::CannotExecuteDuplicateRequest,
            0xD0 => Self::ResponseUnavailable {
                reason: ResponseUnavailableReason::SDRInUpdate,
            },
            0xD1 => Self::ResponseUnavailable {
                reason: ResponseUnavailableReason::DeviceInFwUpdate,
            },
            0xD2 => Self::ResponseUnavailable {
                reason: ResponseUnavailableReason::BMCInitializing,
            },
            0xD3 => Self::DestinationUnavailable,
            0xD4 => Self::InsufficientPrivilege,
            0xD5 => Self::CannotExecuteCommandInCurrentState,
            0xD6 => Self::SubFunctionDisabled,
            0xFF => Self::Unspecified,
            0x01..=0x7E => Self::Oem(value),
            0x80..=0xBE => Self::CommandSpecific(value),
            v => Self::Reserved(v),
        }
    }
}

impl CompletionCode {
    pub fn is_success(&self) -> bool {
        matches!(self, Self::Success)
    }

    pub fn is_reserved(&self) -> bool {
        matches!(self, Self::Reserved(_))
    }
}