blob: 7354fb190441de30142ba7f388966cb8eacbf96e [file] [log] [blame]
Deepak Kodihalli1b24f972019-02-01 04:09:13 -06001#include <endian.h>
2#include <string.h>
3
4#include "base.h"
5
Tom Joseph41251042019-02-07 16:17:07 +05306int pack_pldm_header(const struct pldm_header_info *hdr,
7 struct pldm_msg_hdr *msg)
8{
9 if (msg == NULL || hdr == NULL) {
10 return PLDM_ERROR_INVALID_DATA;
11 }
12
13 if (hdr->msg_type != PLDM_RESPONSE && hdr->msg_type != PLDM_REQUEST &&
14 hdr->msg_type != PLDM_ASYNC_REQUEST_NOTIFY) {
15 return PLDM_ERROR_INVALID_DATA;
16 }
17
18 if (hdr->instance > PLDM_INSTANCE_MAX) {
19 return PLDM_ERROR_INVALID_DATA;
20 }
21
22 if (hdr->pldm_type > (PLDM_MAX_TYPES - 1)) {
23 return PLDM_ERROR_INVALID_PLDM_TYPE;
24 }
25
26 uint8_t datagram = (hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) ? 1 : 0;
27
28 if (hdr->msg_type == PLDM_RESPONSE) {
29 msg->request = PLDM_RESPONSE;
30 } else if (hdr->msg_type == PLDM_REQUEST ||
31 hdr->msg_type == PLDM_ASYNC_REQUEST_NOTIFY) {
32 msg->request = PLDM_REQUEST;
33 }
34 msg->datagram = datagram;
35 msg->reserved = 0;
36 msg->instance_id = hdr->instance;
37 msg->header_ver = 0;
38 msg->type = hdr->pldm_type;
39 msg->command = hdr->command;
40
41 return PLDM_SUCCESS;
42}
43
44int unpack_pldm_header(const struct pldm_msg_hdr *msg,
45 struct pldm_header_info *hdr)
46{
47 if (msg == NULL) {
48 return PLDM_ERROR_INVALID_DATA;
49 }
50
51 if (msg->request == PLDM_RESPONSE) {
52 hdr->msg_type = PLDM_RESPONSE;
53 } else {
54 hdr->msg_type =
55 msg->datagram ? PLDM_ASYNC_REQUEST_NOTIFY : PLDM_REQUEST;
56 }
57
58 hdr->instance = msg->instance_id;
59 hdr->pldm_type = msg->type;
60 hdr->command = msg->command;
61
62 return PLDM_SUCCESS;
63}
64
Deepak Kodihalli1b24f972019-02-01 04:09:13 -060065int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg)
66{
67 if (msg == NULL) {
68 return PLDM_ERROR_INVALID_DATA;
69 }
70
71 return PLDM_SUCCESS;
72}
73
74int encode_get_commands_req(uint8_t instance_id, uint8_t type,
75 struct pldm_version version, struct pldm_msg *msg)
76{
77 if (msg == NULL) {
78 return PLDM_ERROR_INVALID_DATA;
79 }
80
81 uint8_t *dst = msg->body.payload;
82 memcpy(dst, &type, sizeof(type));
83 dst += sizeof(type);
84 memcpy(dst, &version, sizeof(version));
85
86 return PLDM_SUCCESS;
87}
88
89int encode_get_types_resp(uint8_t instance_id, uint8_t completion_code,
90 const uint8_t *types, struct pldm_msg *msg)
91{
92 if (msg == NULL) {
93 return PLDM_ERROR_INVALID_DATA;
94 }
95
96 msg->body.payload[0] = completion_code;
97 if (msg->body.payload[0] == PLDM_SUCCESS) {
98 if (types == NULL) {
99 return PLDM_ERROR_INVALID_DATA;
100 }
101 uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
102 memcpy(dst, types, PLDM_MAX_TYPES / 8);
103 }
104
105 return PLDM_SUCCESS;
106}
107
108int decode_get_commands_req(const struct pldm_msg_payload *msg, uint8_t *type,
109 struct pldm_version *version)
110{
111 if (msg == NULL || type == NULL || version == NULL) {
112 return PLDM_ERROR_INVALID_DATA;
113 }
114
115 const uint8_t *start = msg->payload;
116 *type = *start;
117 memcpy(version, (struct pldm_version *)(start + sizeof(*type)),
118 sizeof(*version));
119
120 return PLDM_SUCCESS;
121}
122
123int encode_get_commands_resp(uint8_t instance_id, uint8_t completion_code,
124 const uint8_t *commands, struct pldm_msg *msg)
125{
126 if (msg == NULL) {
127 return PLDM_ERROR_INVALID_DATA;
128 }
129
130 msg->body.payload[0] = completion_code;
131 if (msg->body.payload[0] == PLDM_SUCCESS) {
132 if (commands == NULL) {
133 return PLDM_ERROR_INVALID_DATA;
134 }
135 uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
136 memcpy(dst, commands, PLDM_MAX_CMDS_PER_TYPE / 8);
137 }
138
139 return PLDM_SUCCESS;
140}
141
142int decode_get_types_resp(const struct pldm_msg_payload *msg, uint8_t *types)
143{
144 if (msg == NULL || types == NULL) {
145 return PLDM_ERROR_INVALID_DATA;
146 }
147 const uint8_t *src = msg->payload + sizeof(uint8_t);
148 memcpy(types, src, PLDM_MAX_TYPES / 8);
149
150 return PLDM_SUCCESS;
151}
152
153int decode_get_commands_resp(const struct pldm_msg_payload *msg,
154 uint8_t *commands)
155{
156 if (msg == NULL || commands == NULL) {
157 return PLDM_ERROR_INVALID_DATA;
158 }
159 const uint8_t *src = msg->payload + sizeof(uint8_t);
160 memcpy(commands, src, PLDM_MAX_CMDS_PER_TYPE / 8);
161
162 return PLDM_SUCCESS;
163}
Sampa Misra432e1872019-02-13 03:49:43 -0600164
165int encode_get_version_req(uint8_t instance_id, uint32_t transfer_handle,
166 uint8_t transfer_opflag, uint8_t type,
167 struct pldm_msg *msg)
168{
169 struct pldm_header_info header = {0};
170 int rc = PLDM_SUCCESS;
171
172 if (NULL == msg) {
173 return PLDM_ERROR_INVALID_DATA;
174 }
175
176 header.msg_type = PLDM_REQUEST;
177 header.instance = instance_id;
178 header.pldm_type = PLDM_BASE;
179 header.command = PLDM_GET_PLDM_VERSION;
180
181 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
182 return rc;
183 }
184
185 uint8_t *dst = msg->body.payload;
186 transfer_handle = htole32(transfer_handle);
187 memcpy(dst, &transfer_handle, sizeof(transfer_handle));
188 dst += sizeof(transfer_handle);
189
190 memcpy(dst, &transfer_opflag, sizeof(transfer_opflag));
191 dst += sizeof(transfer_opflag);
192
193 memcpy(dst, &type, sizeof(type));
194
195 return PLDM_SUCCESS;
196}
197
198int encode_get_version_resp(uint8_t instance_id, uint8_t completion_code,
199 uint32_t next_transfer_handle,
200 uint8_t transfer_flag,
201 const struct pldm_version *version_data,
202 size_t version_size, struct pldm_msg *msg)
203{
204 struct pldm_header_info header = {0};
205 int rc = PLDM_SUCCESS;
206
207 msg->body.payload[0] = completion_code;
208 if (msg->body.payload[0] == PLDM_SUCCESS) {
209
210 header.msg_type = PLDM_RESPONSE;
211 header.instance = instance_id;
212 header.pldm_type = PLDM_BASE;
213 header.command = PLDM_GET_PLDM_VERSION;
214
215 if ((rc = pack_pldm_header(&header, &(msg->hdr))) >
216 PLDM_SUCCESS) {
217 return rc;
218 }
219 uint8_t *dst = msg->body.payload + sizeof(msg->body.payload[0]);
220
221 next_transfer_handle = htole32(next_transfer_handle);
222
223 memcpy(dst, &next_transfer_handle,
224 sizeof(next_transfer_handle));
225 dst += sizeof(next_transfer_handle);
226 memcpy(dst, &transfer_flag, sizeof(transfer_flag));
227
228 dst += sizeof(transfer_flag);
229 memcpy(dst, version_data, version_size);
230 }
231 return PLDM_SUCCESS;
232}
233
234int decode_get_version_req(const struct pldm_msg_payload *msg,
235 uint32_t *transfer_handle, uint8_t *transfer_opflag,
236 uint8_t *type)
237{
238 const uint8_t *start = msg->payload;
239 *transfer_handle = le32toh(*((uint32_t *)start));
240 *transfer_opflag = *(start + sizeof(*transfer_handle));
241 *type = *(start + sizeof(*transfer_handle) + sizeof(*transfer_opflag));
242
243 return PLDM_SUCCESS;
244}
245
246int decode_get_version_resp(const struct pldm_msg_payload *msg,
247 uint32_t *next_transfer_handle,
248 uint8_t *transfer_flag,
249 struct pldm_version *version)
250{
251 const uint8_t *start = msg->payload + sizeof(uint8_t);
252 *next_transfer_handle = le32toh(*((uint32_t *)start));
253 *transfer_flag = *(start + sizeof(*next_transfer_handle));
254
255 *version =
256 *((struct pldm_version *)(start + sizeof(*next_transfer_handle) +
257 sizeof(*transfer_flag)));
258
259 return PLDM_SUCCESS;
260}