1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 3 #define _GNU_SOURCE 4 5 #if HAVE_CONFIG_H 6 #include "config.h" 7 #endif 8 9 #include "libmctp-log.h" 10 #include "libmctp-serial.h" 11 12 #ifdef NDEBUG 13 #undef NDEBUG 14 #endif 15 16 #include <assert.h> 17 #include <fcntl.h> 18 #include <stdbool.h> 19 #include <stdio.h> 20 #include <string.h> 21 #include <unistd.h> 22 23 struct mctp_binding_serial_pipe { 24 int ingress; 25 int egress; 26 27 struct mctp_binding_serial *serial; 28 }; 29 30 static int mctp_binding_serial_pipe_tx(void *data, void *buf, size_t len) 31 { 32 struct mctp_binding_serial_pipe *ctx = data; 33 ssize_t rc; 34 35 rc = write(ctx->egress, buf, len); 36 assert(rc == len); 37 } 38 39 uint8_t mctp_msg_src[2 * MCTP_BTU]; 40 41 static bool seen; 42 43 static void rx_message(uint8_t eid, void *data, void *msg, size_t len) 44 { 45 uint8_t type; 46 47 type = *(uint8_t *)msg; 48 49 mctp_prdebug("MCTP message received: len %zd, type %d", len, type); 50 51 assert(sizeof(mctp_msg_src) == len); 52 assert(!memcmp(mctp_msg_src, msg, len)); 53 54 seen = true; 55 } 56 57 struct serial_test { 58 struct mctp_binding_serial_pipe binding; 59 struct mctp *mctp; 60 }; 61 62 int main(void) 63 { 64 struct serial_test scenario[2]; 65 66 struct mctp_binding_serial_pipe *a = &scenario[0].binding; 67 struct mctp_binding_serial_pipe *b = &scenario[1].binding; 68 int p[2][2]; 69 int rc; 70 71 mctp_set_log_stdio(MCTP_LOG_DEBUG); 72 73 memset(&mctp_msg_src[0], 0x5a, MCTP_BTU); 74 memset(&mctp_msg_src[MCTP_BTU], 0xa5, MCTP_BTU); 75 76 rc = pipe(p[0]); 77 assert(!rc); 78 79 rc = pipe(p[1]); 80 assert(!rc); 81 82 /* Instantiate the A side of the serial pipe */ 83 scenario[0].mctp = mctp_init(); 84 assert(scenario[0].mctp); 85 a->serial = mctp_serial_init(); 86 assert(a->serial); 87 a->ingress = p[0][0]; 88 a->egress = p[1][1]; 89 mctp_serial_open_fd(a->serial, a->ingress); 90 mctp_serial_set_tx_fn(a->serial, mctp_binding_serial_pipe_tx, a); 91 mctp_register_bus(scenario[0].mctp, mctp_binding_serial_core(a->serial), 8); 92 93 /* Instantiate the B side of the serial pipe */ 94 scenario[1].mctp = mctp_init(); 95 assert(scenario[1].mctp); 96 mctp_set_rx_all(scenario[1].mctp, rx_message, NULL); 97 b->serial = mctp_serial_init(); 98 assert(b->serial); 99 b->ingress = p[1][0]; 100 b->egress = p[0][1]; 101 mctp_serial_open_fd(b->serial, b->ingress); 102 mctp_serial_set_tx_fn(b->serial, mctp_binding_serial_pipe_tx, a); 103 mctp_register_bus(scenario[1].mctp, mctp_binding_serial_core(b->serial), 9); 104 105 /* Transmit a message from A to B */ 106 rc = mctp_message_tx(scenario[0].mctp, 9, mctp_msg_src, sizeof(mctp_msg_src)); 107 assert(rc == 0); 108 109 /* Read the message at B from A */ 110 seen = false; 111 mctp_serial_read(b->serial); 112 assert(seen); 113 114 return 0; 115 } 116