Hi, Clearly, the MAC simulation in wmediumd is rather limited, basically the code just munges everything together: for (i = 0; i < frame->tx_rates_count && !is_acked; i++) { rate_idx = frame->tx_rates[i].idx; /* no more rates in MRR */ if (rate_idx < 0) break; error_prob = ctx->get_error_prob(ctx, snr, rate_idx, frame->freq, frame->data_len, station, deststa); for (j = 0; j < frame->tx_rates[i].count; j++) { send_time += difs + pkt_duration(frame->data_len, index_to_rate(rate_idx, frame->freq)); retries++; /* skip ack/backoff/retries for noack frames */ if (noack) { is_acked = true; break; } /* TODO TXOPs */ /* backoff */ if (j > 0) { send_time += (cw * slot_time) / 2; cw = (cw << 1) + 1; if (cw > queue->cw_max) cw = queue->cw_max; } send_time += ack_time_usec; if (choice > error_prob) { is_acked = true; break; } if (!use_fixed_random_value(ctx)) choice = drand48(); } } if (is_acked) { frame->tx_rates[i-1].count = j + 1; for (; i < frame->tx_rates_count; i++) { frame->tx_rates[i].idx = -1; frame->tx_rates[i].count = -1; } frame->flags |= HWSIM_TX_STAT_ACK; } (I copy/pasted that from my version, may be slightly different than current upstream due to a fix bugfixes. I also know the recent fixes will touch this area. Anyway, that's not the point.) Looking at this, one thing that immediately stands out is that the ACK isn't actually transmitted in any way, so you cannot have a duplicate transmission that's actually received and get the ACK back. And the second thing, because of this, it's highly unsuitable for actually integrating with some other MAC. The way I see it, wmediumd serves a dual purpose in this code, implementing both 1) the low-level MAC controller for hwsim, and 2) the actual medium simulation. I wonder if this should be split, implementing a "real" MAC for hwsim, and then sending also the ACKs "properly", perhaps implementing RTS/CTS behaviour in the MAC, etc.? Or perhaps then that's too much complexity and I should just teach ns3 the hwsim virtio interface? johannes