int RFM69::send(uint8_t dest, uint8_t port, const iovec_t* vec) { // Sanity check the payload size if (UNLIKELY(vec == NULL)) return (EINVAL); size_t len = iovec_size(vec); if (UNLIKELY(len > PAYLOAD_MAX)) return (EMSGSIZE); // Check if a packet available. Should receive before send if (UNLIKELY(m_avail)) return (ENXIO); // Write frame header(length, dest, src, port) and payload spi.acquire(this); spi.begin(); spi.transfer(REG_WRITE | FIFO); spi.transfer(len + HEADER_MAX); spi.transfer(dest); spi.transfer(m_addr.device); spi.transfer(port); spi.write(vec); spi.end(); spi.release(); // Trigger the transmit and await completion. Set standby mode m_done = false; set(TRANSMITTER_MODE); while (!m_done) yield(); set(STANDBY_MODE); // Return total length of payload return (len); }
int CC1101::send(uint8_t dest, uint8_t port, const iovec_t* vec) { // Sanity check the payload size if (vec == NULL) return (-1); size_t len = iovec_size(vec); if (len > PAYLOAD_MAX) return (-1); // Wait for the device to become idle before writing the frame await(IDLE_MODE); // Write frame header(length, dest, src, port) spi.begin(this); loop_until_bit_is_clear(PIN, Board::MISO); write(TXFIFO, len + 3); write(TXFIFO, dest); write(TXFIFO, m_addr.device); write(TXFIFO, port); spi.end(); // Write frame payload for (const iovec_t* vp = vec; vp->buf != NULL; vp++) { spi.begin(this); loop_until_bit_is_clear(PIN, Board::MISO); write(TXFIFO, vp->buf, vp->size); spi.end(); } // Trigger the transmit strobe(STX); return (len); }
int NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec) { // Sanity check the payload size if (vec == NULL) return (-1); size_t len = iovec_size(vec); if (len > PAYLOAD_MAX) return (-1); // Setting transmit destination set_transmit_mode(dest); // Write source address and payload to the transmit fifo // Fix: Allow larger payload(30*3) with fragmentation spi.acquire(this); spi.begin(); uint8_t command = ((dest != BROADCAST) ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK); m_status = spi.transfer(command); spi.transfer(m_addr.device); spi.transfer(port); spi.write(vec); spi.end(); spi.release(); m_trans += 1; // Check for auto-acknowledge pipe(0), and address setup and enable if (dest != BROADCAST) { addr_t tx_addr(m_addr.network, dest); write(RX_ADDR_P0, &tx_addr, sizeof(tx_addr)); write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1) | _BV(ERX_P0))); } // Wait for transmission do { yield(); read_status(); } while (!m_status.tx_ds && !m_status.max_rt); bool data_sent = m_status.tx_ds; // Check for auto-acknowledge pipe(0) disable if (dest != BROADCAST) { write(EN_RXADDR, (_BV(ERX_P2) | _BV(ERX_P1))); } // Reset status bits and read retransmission counter and update write(STATUS, _BV(MAX_RT) | _BV(TX_DS)); observe_tx_t observe = read_observe_tx(); m_retrans += observe.arc_cnt; // Check that the message was delivered if (data_sent) return (len); // Failed to delivery write(FLUSH_TX); m_drops += 1; return (-2); }
int trusty_ipc_dev_send(struct trusty_ipc_dev *dev, handle_t chan, const struct trusty_ipc_iovec *iovs, size_t iovs_cnt) { int rc; size_t msg_size; volatile struct trusty_ipc_cmd_hdr *cmd; trusty_assert(dev); /* calc message length */ msg_size = iovec_size(iovs, iovs_cnt); if (msg_size > dev->buf_size - sizeof(*cmd)) { /* msg is too big to fit provided buffer */ trusty_error("%a: chan %d: msg is too long (%zu)\n", __func__, chan, msg_size); return TRUSTY_ERR_MSG_TOO_BIG; } /* prepare command */ cmd = dev->buf_vaddr; memset((void *)cmd, 0, sizeof(*cmd)); cmd->opcode = QL_TIPC_DEV_SEND; cmd->handle = chan; /* copy in message data */ cmd->payload_len = (uint32_t)msg_size; msg_size = iovec_to_buf(dev->buf_vaddr + sizeof(*cmd), dev->buf_size - sizeof(*cmd), iovs, iovs_cnt); trusty_assert(msg_size == (size_t)cmd->payload_len); /* call into secure os */ rc = trusty_dev_exec_ipc(dev->tdev, &dev->buf_ns, sizeof(*cmd) + cmd->payload_len); if (rc < 0) { trusty_error("%a: secure OS returned (%d)\n", __func__, rc); return TRUSTY_ERR_SECOS_ERR; } rc = check_response(dev, cmd, QL_TIPC_DEV_SEND); if (rc) { trusty_error("%a: send msg failed (%d)\n", __func__, rc); } return rc; }
int NRF24L01P::send(uint8_t dest, uint8_t port, const iovec_t* vec) { // Sanity check the payload size if (vec == NULL) return (-1); size_t len = iovec_size(vec); if (len > PAYLOAD_MAX) return (-1); // Setting transmit destination set_transmit_mode(dest); // Write source address and payload to the transmit fifo // Fix: Allow larger payload(30*3) with fragmentation spi.begin(this); m_status = spi.transfer(dest ? W_TX_PAYLOAD : W_TX_PAYLOAD_NO_ACK); spi.transfer(m_addr.device); spi.transfer(port); spi.write(vec); spi.end(); m_trans += 1; // Wait for transmission do { Power::sleep(m_mode); read_status(); } while (!m_status.tx_ds && !m_status.max_rt); bool data_sent = m_status.tx_ds; // Reset status bits and read retransmission counter and update write(STATUS, _BV(MAX_RT) | _BV(TX_DS)); observe_tx_t observe = read_observe_tx(); m_retrans += observe.arc_cnt; // Check that the message was delivered if (data_sent) return (len); // Failed to delivery write(FLUSH_TX); m_drops += 1; return (-2); }