blob: e81ae22dc07cdeccac77c60211e63e2c8613fbbe [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <wlan/mlme/ap/tim.h>
namespace wlan {
TrafficIndicationMap::TrafficIndicationMap() {
aid_bitmap_.Reset(kMaxBssClients);
}
void TrafficIndicationMap::SetTrafficIndication(aid_t aid, bool has_bu) {
ZX_DEBUG_ASSERT(aid < kMaxBssClients);
if (aid >= kMaxBssClients) {
errorf("attempt setting traffic indication for invalid aid: %zu\n", aid);
return;
}
if (has_bu) {
aid_bitmap_.SetOne(aid);
} else {
aid_bitmap_.ClearOne(aid);
}
}
zx_status_t TrafficIndicationMap::WritePartialVirtualBitmap(uint8_t* buf, size_t buf_len,
size_t* bitmap_len,
uint8_t* bitmap_offset) const {
size_t n1 = N1();
size_t n2 = N2();
*bitmap_len = 1 + (n2 - n1);
if (buf_len < *bitmap_len) { return ZX_ERR_BUFFER_TOO_SMALL; }
auto data = static_cast<const uint8_t*>(aid_bitmap_.StorageUnsafe()->GetData());
memcpy(buf, data + n1, *bitmap_len);
*bitmap_offset = n1 / 2;
return ZX_OK;
}
size_t TrafficIndicationMap::BitmapLen() const {
return 1 + (N2() - N1());
}
uint8_t TrafficIndicationMap::BitmapOffset() const {
return static_cast<uint8_t>(N1() / 2);
}
const uint8_t* TrafficIndicationMap::BitmapData() const {
return static_cast<const uint8_t*>(aid_bitmap_.StorageUnsafe()->GetData());
}
bool TrafficIndicationMap::HasDozingClients() const {
bool empty = aid_bitmap_.Scan(1, aid_bitmap_.size(), false, nullptr);
return !empty;
}
bool TrafficIndicationMap::HasGroupTraffic() const {
return aid_bitmap_.GetOne(kGroupAdressedAid);
}
void TrafficIndicationMap::Clear() {
aid_bitmap_.Reset(kMaxBssClients);
}
size_t TrafficIndicationMap::N1() const {
size_t first_set_bit;
bool none_set = aid_bitmap_.Scan(1, aid_bitmap_.size(), false, &first_set_bit);
if (none_set) { return 0; }
size_t n1 = first_set_bit / 8;
return n1 % 2 == 0 ? n1 : (n1 - 1);
}
size_t TrafficIndicationMap::N2() const {
size_t last_set_bit;
bool none_set = aid_bitmap_.ReverseScan(1, aid_bitmap_.size(), false, &last_set_bit);
if (none_set) { return 0; }
return last_set_bit / 8;
}
} // namespace wlan