static void seg_tx_send_unacked()

in nimble/host/mesh/src/transport.c [369:449]


static void seg_tx_send_unacked(struct seg_tx *tx)
{
	if (!tx->nack_count) {
		return;
	}

	struct bt_mesh_msg_ctx ctx = {
		.net_idx = tx->sub->net_idx,
		/* App idx only used by network to detect control messages: */
		.app_idx = (tx->ctl ? BT_MESH_KEY_UNUSED : 0),
		.addr = tx->dst,
		.send_rel = true,
		.send_ttl = tx->ttl,
	};
	struct bt_mesh_net_tx net_tx = {
		.sub = tx->sub,
		.ctx = &ctx,
		.src = tx->src,
		.xmit = tx->xmit,
		.friend_cred = tx->friend_cred,
		.aid = tx->hdr & AID_MASK,
	};

	if (!tx->attempts) {
		if (BT_MESH_ADDR_IS_UNICAST(tx->dst)) {
			BT_ERR("Ran out of retransmit attempts");
			seg_tx_complete(tx, -ETIMEDOUT);
		} else {
			/* Segmented sending to groups doesn't have acks, so
			 * running out of attempts is the expected behavior.
			 */
			seg_tx_complete(tx, 0);
		}

		return;
	}

	BT_DBG("SeqZero: 0x%04x Attempts: %u",
	       (uint16_t)(tx->seq_auth & TRANS_SEQ_ZERO_MASK), tx->attempts);

	tx->sending = 1U;

	for (; tx->seg_o <= tx->seg_n; tx->seg_o++) {
		struct os_mbuf *seg;
		int err;

		if (!tx->seg[tx->seg_o]) {
			continue;
		}

		seg = bt_mesh_adv_create(BT_MESH_ADV_DATA, tx->xmit,
					 BUF_TIMEOUT);
		if (!seg) {
			BT_DBG("Allocating segment failed");
			goto end;
		}

		net_buf_reserve(seg, BT_MESH_NET_HDR_LEN);
		seg_tx_buf_build(tx, tx->seg_o, seg);

		tx->seg_pending++;

		BT_DBG("Sending %u/%u", tx->seg_o, tx->seg_n);

		err = bt_mesh_net_send(&net_tx, seg, &seg_sent_cb, tx);
		if (err) {
			BT_DBG("Sending segment failed");
			tx->seg_pending--;
			goto end;
		}
	}
	tx->seg_o = 0U;
	tx->attempts--;
end:
	if (!tx->seg_pending) {
		k_work_reschedule(&tx->retransmit,
				  K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx)));
	}

	tx->sending = 0U;
}