View Javadoc
1   package org.metricshub.ipmi.core.coding.commands.sel;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * IPMI Java Client
6    * ჻჻჻჻჻჻
7    * Copyright 2023 Verax Systems, MetricsHub
8    * ჻჻჻჻჻჻
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23   */
24  
25  import org.metricshub.ipmi.core.coding.commands.CommandCodes;
26  import org.metricshub.ipmi.core.coding.commands.IpmiCommandCoder;
27  import org.metricshub.ipmi.core.coding.commands.IpmiVersion;
28  import org.metricshub.ipmi.core.coding.commands.ResponseData;
29  import org.metricshub.ipmi.core.coding.payload.CompletionCode;
30  import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
31  import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
32  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanRequest;
33  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanResponse;
34  import org.metricshub.ipmi.core.coding.payload.lan.NetworkFunction;
35  import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
36  import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
37  import org.metricshub.ipmi.core.coding.security.CipherSuite;
38  import org.metricshub.ipmi.core.common.TypeConverter;
39  
40  import java.security.InvalidKeyException;
41  import java.security.NoSuchAlgorithmException;
42  
43  /**
44   * Wrapper for Get Sel Entry request
45   */
46  public class GetSelEntry extends IpmiCommandCoder {
47  
48      private int reservationId;
49  
50      private int recordId;
51  
52      /**
53       * Initiates GetSelEntry for both encoding and decoding.
54       *
55       * @param version
56       *            - IPMI version of the command.
57       * @param cipherSuite
58       *            - {@link CipherSuite} containing authentication,
59       *            confidentiality and integrity algorithms for this session.
60       * @param authenticationType
61       *            - Type of authentication used. Must be RMCPPlus for IPMI v2.0.
62       * @param reservationId
63       *            - SEL reservation ID received via {@link ReserveSel} command
64       *            or 0 if requesting for whole record
65       * @param recordId
66       *            - ID of the record to get
67       */
68      public GetSelEntry(IpmiVersion version, CipherSuite cipherSuite,
69              AuthenticationType authenticationType, int reservationId,
70              int recordId) {
71          super(version, cipherSuite, authenticationType);
72          this.recordId = recordId;
73          this.reservationId = reservationId;
74      }
75  
76      @Override
77      public byte getCommandCode() {
78          return CommandCodes.GET_SEL_ENTRY;
79      }
80  
81      @Override
82      public NetworkFunction getNetworkFunction() {
83          return NetworkFunction.StorageRequest;
84      }
85  
86      @Override
87      protected IpmiPayload preparePayload(int sequenceNumber)
88              throws NoSuchAlgorithmException, InvalidKeyException {
89          byte[] payload = new byte[6];
90  
91          byte[] buffer = TypeConverter.intToByteArray(reservationId);
92  
93          payload[0] = buffer[3];
94          payload[1] = buffer[2]; // reservation ID
95  
96          buffer = TypeConverter.intToByteArray(recordId);
97  
98          payload[2] = buffer[3];
99          payload[3] = buffer[2]; // record ID
100 
101         payload[4] = 0;
102         payload[5] = TypeConverter.intToByte(0xff);
103 
104         return new IpmiLanRequest(getNetworkFunction(), getCommandCode(),
105                 payload, TypeConverter.intToByte(sequenceNumber));
106     }
107 
108     @Override
109     public ResponseData getResponseData(IpmiMessage message) throws IPMIException,
110             NoSuchAlgorithmException, InvalidKeyException {
111         if (!isCommandResponse(message)) {
112             throw new IllegalArgumentException(
113                     "This is not a response for Get SEL Entry command");
114         }
115         if (!(message.getPayload() instanceof IpmiLanResponse)) {
116             throw new IllegalArgumentException("Invalid response payload");
117         }
118         if (((IpmiLanResponse) message.getPayload()).getCompletionCode() != CompletionCode.Ok) {
119             throw new IPMIException(
120                     ((IpmiLanResponse) message.getPayload())
121                             .getCompletionCode());
122         }
123 
124         byte[] raw = message.getPayload().getIpmiCommandData();
125 
126         if (raw == null || raw.length < 3) {
127             throw new IllegalArgumentException(
128                     "Invalid response payload length");
129         }
130 
131         GetSelEntryResponseData responseData = new GetSelEntryResponseData();
132 
133         byte[] buffer = new byte[4];
134 
135         buffer[0] = raw[0];
136         buffer[1] = raw[1];
137         buffer[2] = 0;
138         buffer[3] = 0;
139 
140         responseData.setNextRecordId(TypeConverter
141                 .littleEndianByteArrayToInt(buffer));
142 
143         byte[] recordData = new byte[raw.length - 2];
144 
145         System.arraycopy(raw, 2, recordData, 0, recordData.length);
146 
147         responseData.setSelRecord(SelRecord.populateSelRecord(recordData));
148 
149         return responseData;
150     }
151 
152 }