1 #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 13 struct pollfd { 14 int fd; /* file descriptor */ 15 short events; /* requested events */ 16 short revents; /* returned events */ 17 }; 18 19 static 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 27 pldm_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 48 pldm_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 69 pldm_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 101 pldm_requester_rc_t 102 pldm_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 } 131