xref: /openbmc/fb-ipmi-oem/src/appcommands.cpp (revision a2d52f1269c72c47c4c85c22692ada5234fe5ac4)
1 /*
2  * Copyright (c)  2018 Intel Corporation.
3  * Copyright (c)  2018-present Facebook.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <ipmid/api.h>
19 
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <commandutils.hpp>
24 #include <iostream>
25 #include <phosphor-logging/log.hpp>
26 #include <sdbusplus/message/types.hpp>
27 #include <appcommands.hpp>
28 
29 namespace ipmi
30 {
31 
32 static void registerAPPFunctions() __attribute__((constructor));
33 static constexpr size_t GUID_SIZE = 16;
34 // TODO Make offset and location runtime configurable to ensure we
35 // can make each define their own locations.
36 static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
37 static constexpr off_t OFFSET_DEV_GUID = 0x1800;
38 static constexpr const char *FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
39 static uint8_t globEna = 0x09;
40 
41 void printGUID(uint8_t *guid, off_t offset)
42 {
43     std::cout << "Read GUID from offset : " << offset << " :\n";
44     for (int i = 0; i < GUID_SIZE; i++)
45     {
46         int data = guid[i];
47         std::cout << std::hex << data << " ";
48     }
49     std::cout << std::endl;
50 }
51 
52 int getGUID(off_t offset, uint8_t *guid)
53 {
54     int fd = -1;
55     ssize_t bytes_rd;
56     int ret = 0;
57 
58     errno = 0;
59 
60     // Check if file is present
61     if (access(FRU_EEPROM, F_OK) == -1)
62     {
63         std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
64         return errno;
65     }
66 
67     // Open the file
68     fd = open(FRU_EEPROM, O_RDONLY);
69     if (fd == -1)
70     {
71         std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
72         return errno;
73     }
74 
75     // seek to the offset
76     lseek(fd, offset, SEEK_SET);
77 
78     // Read bytes from location
79     bytes_rd = read(fd, guid, GUID_SIZE);
80     if (bytes_rd != GUID_SIZE)
81     {
82         phosphor::logging::log<phosphor::logging::level::ERR>(
83             "GUID read data from EEPROM failed");
84         ret = errno;
85     }
86     else
87     {
88         printGUID(guid, offset);
89     }
90     close(fd);
91     return ret;
92 }
93 
94 int getSystemGUID(uint8_t *guid)
95 {
96     return getGUID(OFFSET_SYS_GUID, guid);
97 }
98 
99 int getDeviceGUID(uint8_t *guid)
100 {
101     return getGUID(OFFSET_DEV_GUID, guid);
102 }
103 
104 //----------------------------------------------------------------------
105 // Get Device GUID (CMD_APP_GET_DEV_GUID)
106 //----------------------------------------------------------------------
107 ipmi_ret_t ipmiAppGetDevGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
108                              ipmi_request_t request, ipmi_response_t response,
109                              ipmi_data_len_t data_len, ipmi_context_t context)
110 {
111     uint8_t *res = reinterpret_cast<uint8_t *>(response);
112 
113     if (getDeviceGUID(res))
114     {
115         return IPMI_CC_UNSPECIFIED_ERROR;
116     }
117     *data_len = GUID_SIZE;
118 
119     return IPMI_CC_OK;
120 }
121 
122 //----------------------------------------------------------------------
123 // Set Global Enables (CMD_APP_SET_GLOBAL_ENABLES)
124 //----------------------------------------------------------------------
125 ipmi_ret_t ipmiAppSetGlobalEnables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
126                                    ipmi_request_t request,
127                                    ipmi_response_t response,
128                                    ipmi_data_len_t data_len,
129                                    ipmi_context_t context)
130 {
131     uint8_t *req = reinterpret_cast<uint8_t *>(request);
132 
133     globEna = *req;
134     *data_len = 0;
135 
136     return IPMI_CC_OK;
137 }
138 
139 //----------------------------------------------------------------------
140 // Get Global Enables (CMD_APP_GET_GLOBAL_ENABLES)
141 //----------------------------------------------------------------------
142 ipmi_ret_t ipmiAppGetGlobalEnables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
143                                    ipmi_request_t request,
144                                    ipmi_response_t response,
145                                    ipmi_data_len_t data_len,
146                                    ipmi_context_t context)
147 {
148     uint8_t *res = reinterpret_cast<uint8_t *>(response);
149 
150     *data_len = 1;
151     *res++ = globEna;
152 
153     return IPMI_CC_OK;
154 }
155 
156 //----------------------------------------------------------------------
157 // Get System GUID (CMD_APP_GET_SYS_GUID)
158 //----------------------------------------------------------------------
159 ipmi_ret_t ipmiAppGetSysGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
160                              ipmi_request_t request, ipmi_response_t response,
161                              ipmi_data_len_t data_len, ipmi_context_t context)
162 {
163     uint8_t *res = reinterpret_cast<uint8_t *>(response);
164     if (getSystemGUID(res))
165     {
166         return IPMI_CC_UNSPECIFIED_ERROR;
167     }
168     *data_len = GUID_SIZE;
169     return IPMI_CC_OK;
170 }
171 
172 void registerAPPFunctions()
173 {
174     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_DEV_GUID, NULL,
175                          ipmiAppGetDevGUID,
176                          PRIVILEGE_USER); // Get Device GUID
177     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_GLOBAL_ENABLES, NULL,
178                          ipmiAppSetGlobalEnables,
179                          PRIVILEGE_USER); // Get Global Enables
180     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_GLOBAL_ENABLES, NULL,
181                          ipmiAppGetGlobalEnables,
182                          PRIVILEGE_USER); // Get Global Enables
183     ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_GUID, NULL,
184                          ipmiAppGetSysGUID,
185                          PRIVILEGE_USER); // Get System GUID
186 
187     return;
188 }
189 
190 } // namespace ipmi
191