blob: 0681e2346e3703f0482591b981f5d6e058545ffc [file] [log] [blame]
Rashmica Guptac1b66f42022-12-09 16:24:45 +11001#include "libpldm/transport.h"
2#include "base.h"
3#include "libpldm/requester/pldm.h"
4#include "transport.h"
5
6#ifdef PLDM_HAS_POLL
7#include <poll.h>
8#endif
9#include <stdlib.h>
10#include <unistd.h>
11
12#ifndef PLDM_HAS_POLL
13struct pollfd {
14 int fd; /* file descriptor */
15 short events; /* requested events */
16 short revents; /* returned events */
17};
18
19static inline int poll(struct pollfd *fds __attribute__((unused)),
20 int nfds __attribute__((unused)),
21 int timeout __attribute__((unused)))
22{
23 return 0;
24}
25#endif
26
27pldm_requester_rc_t pldm_transport_poll(struct pldm_transport *transport,
28 int timeout)
29{
30 struct pollfd pollfd;
31 int rc = 0;
32 if (!transport) {
33 return PLDM_REQUESTER_INVALID_SETUP;
34 }
35 if (!transport->init_pollfd) {
36 return PLDM_REQUESTER_SUCCESS;
37 }
38
39 transport->init_pollfd(transport, &pollfd);
40 rc = poll(&pollfd, 1, timeout);
41 if (rc < 0) {
42 return PLDM_REQUESTER_POLL_FAIL;
43 }
44
45 return PLDM_REQUESTER_SUCCESS;
46}
47
48pldm_requester_rc_t pldm_transport_send_msg(struct pldm_transport *transport,
49 pldm_tid_t tid,
50 const void *pldm_req_msg,
51 size_t req_msg_len)
52{
53 if (!transport || !pldm_req_msg) {
54 return PLDM_REQUESTER_INVALID_SETUP;
55 }
56
57 if (req_msg_len < sizeof(struct pldm_msg_hdr)) {
58 return PLDM_REQUESTER_NOT_REQ_MSG;
59 }
60
61 const struct pldm_msg_hdr *hdr = pldm_req_msg;
62 if (!hdr->request) {
63 return PLDM_REQUESTER_NOT_REQ_MSG;
64 }
65
66 return transport->send(transport, tid, pldm_req_msg, req_msg_len);
67}
68
69pldm_requester_rc_t pldm_transport_recv_msg(struct pldm_transport *transport,
70 pldm_tid_t tid,
71 void **pldm_resp_msg,
72 size_t *resp_msg_len)
73{
74 if (!transport || !resp_msg_len) {
75 return PLDM_REQUESTER_INVALID_SETUP;
76 }
77
78 pldm_requester_rc_t rc =
79 transport->recv(transport, tid, pldm_resp_msg, resp_msg_len);
80 if (rc != PLDM_REQUESTER_SUCCESS) {
81 return rc;
82 }
83
84 struct pldm_msg_hdr *hdr = *pldm_resp_msg;
85 if (hdr->request || hdr->datagram) {
86 free(*pldm_resp_msg);
87 *pldm_resp_msg = NULL;
88 return PLDM_REQUESTER_NOT_RESP_MSG;
89 }
90
91 uint8_t pldm_rc = 0;
92 if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_rc))) {
93 free(*pldm_resp_msg);
94 *pldm_resp_msg = NULL;
95 return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
96 }
97
98 return PLDM_REQUESTER_SUCCESS;
99}
100
101pldm_requester_rc_t
102pldm_transport_send_recv_msg(struct pldm_transport *transport, pldm_tid_t tid,
103 const void *pldm_req_msg, size_t req_msg_len,
104 void **pldm_resp_msg, size_t *resp_msg_len)
105
106{
107 if (!resp_msg_len) {
108 return PLDM_REQUESTER_INVALID_SETUP;
109 }
110
111 pldm_requester_rc_t rc =
112 pldm_transport_send_msg(transport, tid, pldm_req_msg, req_msg_len);
113 if (rc != PLDM_REQUESTER_SUCCESS) {
114 return rc;
115 }
116
117 while (1) {
118 rc = pldm_transport_poll(transport, -1);
119 if (rc != PLDM_REQUESTER_SUCCESS) {
120 break;
121 }
122 rc = pldm_transport_recv_msg(transport, tid, pldm_resp_msg,
123 resp_msg_len);
124 if (rc == PLDM_REQUESTER_SUCCESS) {
125 break;
126 }
127 }
128
129 return rc;
130}