forked from k-sone/ipmigo
-
Notifications
You must be signed in to change notification settings - Fork 2
/
command_sel.go
146 lines (121 loc) · 4.12 KB
/
command_sel.go
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package ipmigo
import (
"encoding/binary"
)
// Get SEL Info (Section 31.2)
type GetSELInfoCommand struct {
// Response Data
SELVersion uint8
Entries uint16
FreeSpace uint16
LastAddTime uint32
LastDelTime uint32
SupportAllocInfo bool
SupportReserve bool
SupportPartialAdd bool
SupportDelete bool
Overflow bool
}
func (c *GetSELInfoCommand) Name() string { return "Get SEL Info" }
func (c *GetSELInfoCommand) Code() uint8 { return 0x40 }
func (c *GetSELInfoCommand) NetFnRsLUN() NetFnRsLUN {
return NewNetFnRsLUN(NetFnStorageReq, 0)
}
func (c *GetSELInfoCommand) String() string { return cmdToJSON(c) }
func (c *GetSELInfoCommand) Marshal() ([]byte, error) { return []byte{}, nil }
func (c *GetSELInfoCommand) Unmarshal(buf []byte) ([]byte, error) {
if err := cmdValidateLength(c, buf, 14); err != nil {
return nil, err
}
c.SELVersion = buf[0]
c.Entries = binary.LittleEndian.Uint16(buf[1:3])
c.FreeSpace = binary.LittleEndian.Uint16(buf[3:5])
c.LastAddTime = binary.LittleEndian.Uint32(buf[5:9])
c.LastDelTime = binary.LittleEndian.Uint32(buf[9:13])
c.SupportAllocInfo = buf[13]&0x01 != 0
c.SupportReserve = buf[13]&0x02 != 0
c.SupportPartialAdd = buf[13]&0x04 != 0
c.SupportDelete = buf[13]&0x08 != 0
c.Overflow = buf[13]&0x80 != 0
return buf[14:], nil
}
// Reserve SEL Command (Section 31.4)
type ReserveSELCommand struct {
// Response Data
ReservationID uint16
}
func (c *ReserveSELCommand) Name() string { return "Reserve SEL" }
func (c *ReserveSELCommand) Code() uint8 { return 0x42 }
func (c *ReserveSELCommand) NetFnRsLUN() NetFnRsLUN {
return NewNetFnRsLUN(NetFnStorageReq, 0)
}
func (c *ReserveSELCommand) String() string { return cmdToJSON(c) }
func (c *ReserveSELCommand) Marshal() ([]byte, error) { return []byte{}, nil }
func (c *ReserveSELCommand) Unmarshal(buf []byte) ([]byte, error) {
if err := cmdValidateLength(c, buf, 2); err != nil {
return nil, err
}
c.ReservationID = binary.LittleEndian.Uint16(buf)
return buf[2:], nil
}
// Get SEL Entry Command (Section 31.5)
type GetSELEntryCommand struct {
// Request Data
ReservationID uint16
RecordID uint16
RecordOffset uint8
ReadBytes uint8
// Response Data
NextRecordID uint16
RecordData []byte
}
func (c *GetSELEntryCommand) Name() string { return "Get SDR" }
func (c *GetSELEntryCommand) Code() uint8 { return 0x43 }
func (c *GetSELEntryCommand) NetFnRsLUN() NetFnRsLUN { return NewNetFnRsLUN(NetFnStorageReq, 0) }
func (c *GetSELEntryCommand) String() string { return cmdToJSON(c) }
func (c *GetSELEntryCommand) Marshal() ([]byte, error) {
return []byte{byte(c.ReservationID), byte(c.ReservationID >> 8), byte(c.RecordID), byte(c.RecordID >> 8),
byte(c.RecordOffset), byte(c.ReadBytes)}, nil
}
func (c *GetSELEntryCommand) Unmarshal(buf []byte) ([]byte, error) {
if err := cmdValidateLength(c, buf, 2); err != nil {
return nil, err
}
c.NextRecordID = binary.LittleEndian.Uint16(buf)
buf = buf[2:]
if l := len(buf); l <= int(c.ReadBytes) {
c.RecordData = make([]byte, l)
copy(c.RecordData, buf)
return nil, nil
} else {
c.RecordData = make([]byte, c.ReadBytes)
copy(c.RecordData, buf)
return buf[c.ReadBytes:], nil
}
}
// Clear SEL Command (Section 31.9)
type ClearSELEntry struct {
// Request Data
ReservationID uint16
Action uint8
// Response Data
ErasureStatus uint8
}
func (c *ClearSELEntry) Name() string { return "Clean SEL" }
func (c *ClearSELEntry) Code() uint8 { return 0x47 } // All cmd Codes are listed in "Appendix G - Command Assignments"
func (c *ClearSELEntry) NetFnRsLUN() NetFnRsLUN { return NewNetFnRsLUN(NetFnStorageReq, 0) }
func (c *ClearSELEntry) String() string { return cmdToJSON(c) }
func (c *ClearSELEntry) Marshal() ([]byte, error) {
cRecord := uint8(0x43)
lRecord := uint8(0x4c)
rRecord := uint8(0x52)
return []byte{byte(c.ReservationID), byte(c.ReservationID >> 8),
cRecord, lRecord, rRecord, c.Action}, nil
}
func (c *ClearSELEntry) Unmarshal(buf []byte) ([]byte, error) {
if err := cmdValidateLength(c, buf, 1); err != nil {
return nil, err
}
c.ErasureStatus = buf[0]
return buf, nil
}