6#include "usb/core/bos.hpp"
10using LibXR::USB::BOS_HEADER_SIZE;
13using LibXR::USB::DESCRIPTOR_TYPE_DEVICE_CAPABILITY;
14using LibXR::USB::DEV_CAPABILITY_TYPE_USB20EXT;
18static bool config_contains_iad(
const std::initializer_list<ConfigDescriptorItem*>& group)
20 for (
auto* item : group)
22 if (item !=
nullptr && item->HasIAD())
32static bool is_composite_config(
const std::initializer_list<ConfigDescriptorItem*>& group)
34 return (group.size() > 1) || config_contains_iad(group);
47 auto* item = items[0];
58 return (item->GetInterfaceCount() == 1);
63static size_t calc_bos_capability_num_max(
64 const std::initializer_list<
const std::initializer_list<ConfigDescriptorItem*>>&
68 for (
const auto& group : configs)
71 for (
auto* item : group)
77 num += item->GetBosCapabilityCount();
89static size_t calc_bos_descriptor_size_max(
90 const std::initializer_list<
const std::initializer_list<ConfigDescriptorItem*>>&
93 static constexpr size_t USB2_EXT_SIZE = 7;
95 size_t max_total = BOS_HEADER_SIZE;
96 for (
const auto& group : configs)
99 bool has_usb2_ext =
false;
101 for (
auto* item : group)
108 const size_t CAP_NUM = item->GetBosCapabilityCount();
109 for (
size_t i = 0; i < CAP_NUM; ++i)
118 ASSERT(blk.addr_ !=
nullptr);
119 ASSERT(blk.size_ >= 3);
121 cap_bytes += blk.size_;
123 const uint8_t* p =
reinterpret_cast<const uint8_t*
>(blk.addr_);
124 if (p[1] == DESCRIPTOR_TYPE_DEVICE_CAPABILITY &&
125 p[2] == DEV_CAPABILITY_TYPE_USB20EXT)
132 const size_t TOTAL = BOS_HEADER_SIZE + cap_bytes + (has_usb2_ext ? 0 : USB2_EXT_SIZE);
133 if (TOTAL > max_total)
139 ASSERT(max_total <= 0xFFFF);
145using namespace LibXR::USB;
156 const auto CFG =
items_[0];
157 return is_device_descriptor_override_eligible(CFG.items, CFG.item_num);
161 const std::initializer_list<
const std::initializer_list<ConfigDescriptorItem*>>&
166 for (
const auto& group : configs)
168 if (is_composite_config(group))
189 for (
size_t i = 0; i < CFG.item_num; ++i)
191 auto* item = CFG.items[i];
197 const size_t CAP_NUM = item->GetBosCapabilityCount();
198 for (
size_t j = 0; j < CAP_NUM; ++j)
200 auto* cap = item->GetBosCapability(j);
214 const std::initializer_list<
const std::initializer_list<ConfigDescriptorItem*>>&
216 uint8_t bmAttributes, uint8_t bMaxPower)
217 :
BosManager(calc_bos_descriptor_size_max(configs),
218 calc_bos_capability_num_max(configs)),
219 endpoint_pool_(endpoint_pool),
220 bm_attributes_(bmAttributes),
221 b_max_power_(bMaxPower),
222 COMPOSITE(IsCompositeConfig(configs)),
223 CFG_NUM(configs.size()),
224 items_(new
Config[CFG_NUM])
228 size_t max_config_size = 0;
229 size_t config_index = 0;
231 for (
const auto& cfg_group : configs)
233 size_t config_size =
sizeof(
Header);
238 size_t item_index = 0;
239 for (
auto* item : cfg_group)
244 config_size += item->GetMaxConfigSize();
249 if (config_size > max_config_size)
251 max_config_size = config_size;
264 if (index == 0 || index >
CFG_NUM)
266 return ErrorCode::NOT_FOUND;
272 return ErrorCode::OK;
285 size_t start_itf = 0;
286 for (
size_t i = 0; i < CFG.item_num; ++i)
288 auto* item = CFG.items[i];
295 start_itf += item->GetInterfaceCount();
309 for (
size_t i = 0; i < CFG.item_num; ++i)
311 auto* item = CFG.items[i];
322 uint8_t* buffer =
reinterpret_cast<uint8_t*
>(
buffer_.
addr_);
335 size_t offset =
sizeof(
Header);
336 uint8_t total_interfaces = 0;
340 for (
size_t i = 0; i < CFG.item_num; ++i)
342 auto* item = CFG.items[i];
348 auto data = item->GetData();
350 offset += data.size_;
352 total_interfaces =
static_cast<uint8_t
>(total_interfaces + item->GetInterfaceCount());
355 ASSERT(offset <= 0xFFFF);
360 return ErrorCode::OK;
369 return ErrorCode::NOT_SUPPORT;
372 const auto CFG =
items_[0];
373 if (CFG.item_num != 1 || CFG.items ==
nullptr || CFG.items[0] ==
nullptr)
375 return ErrorCode::NOT_SUPPORT;
398 int interface_index = -1;
399 for (
size_t i = 0; i < CFG.item_num; ++i)
401 auto* item = CFG.items[i];
407 interface_index +=
static_cast<int>(item->GetInterfaceCount());
408 if (interface_index >=
static_cast<int>(index))
420 for (
size_t i = 0; i < CFG.item_num; ++i)
422 auto* item = CFG.items[i];
428 if (item->OwnsEndpoint(addr))
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
BOS 能力接口 / BOS capability interface.
virtual ConstRawData GetCapabilityDescriptor() const =0
返回能力块(不含 BOS 头) Return capability block (without BOS header).
BOS 管理器:能力收集、BOS 描述符拼装、Vendor 请求链式分发 BOS manager: capability collection, descriptor building,...
bool AddCapability(BosCapability *cap)
添加能力 / Add capability
ConstRawData GetBosDescriptor()
构建 BOS 描述符(BOS 头 + 能力块) Build BOS descriptor (header + blocks).
void ClearCapabilities()
清空已注册能力 / Clear registered capabilities
bool IsComposite() const
是否为复合设备 / Whether composite device
RawData GetData() const
获取配置描述符数据 / Get configuration descriptor data
ConfigDescriptorItem * FindItemByInterfaceNumber(size_t index) const
按接口号查找配置项 / Find item by interface number
uint8_t i_configuration_
配置字符串索引 / Configuration string index
uint8_t bm_attributes_
配置属性 / bmAttributes
bool CanOverrideDeviceDescriptor() const
是否允许覆盖设备描述符 / Whether device descriptor override is allowed
uint16_t GetDeviceStatus() const
设备状态(GET_STATUS)/ Device status (GET_STATUS)
ErrorCode OverrideDeviceDescriptor(DeviceDescriptor &descriptor)
覆盖设备描述符 / Override device descriptor
uint8_t current_cfg_
当前配置索引 / Current configuration index
void BindEndpoints(bool in_isr)
绑定当前配置端点 / Bind endpoints for current configuration
size_t GetConfigNum() const
配置数量 / Number of configurations
bool ep_assigned_
端点是否已绑定 / Whether endpoints are assigned
ConfigDescriptorItem * FindItemByEndpointAddress(uint8_t addr) const
按端点地址查找配置项 / Find item by endpoint address
const bool COMPOSITE
是否为复合设备 / Whether composite device
size_t buffer_index_
缓冲区写入位置 / Buffer write index
ErrorCode BuildConfigDescriptor()
构建当前配置描述符 / Build current configuration descriptor
EndpointPool & endpoint_pool_
端点池引用 / Endpoint pool reference
static bool IsCompositeConfig(const std::initializer_list< const std::initializer_list< ConfigDescriptorItem * > > &configs)
uint8_t b_max_power_
最大电流(2mA 单位)/ Max power (2mA units)
const size_t CFG_NUM
配置数量 / Configuration count
ConfigDescriptor(EndpointPool &endpoint_pool, const std::initializer_list< const std::initializer_list< ConfigDescriptorItem * > > &configs, uint8_t bmAttributes=CFG_BUS_POWERED, uint8_t bMaxPower=50)
构造函数 / Constructor
void RebuildBosCache()
重建 BOS 缓存 / Rebuild BOS cache
Config * items_
配置项集合 / Configuration item set
RawData buffer_
配置描述符缓冲区 / Configuration descriptor buffer
size_t GetCurrentConfig() const
当前配置索引 / Current configuration index
ErrorCode SwitchConfig(size_t index, bool in_isr)
切换当前 configuration / Switch current configuration
void UnbindEndpoints(bool in_isr)
解绑当前配置端点 / Unbind endpoints for current configuration
USB 配置项基类(功能块)/ USB configuration item base (functional block)
RawData GetData()
获取内部数据缓存 / Get internal data cache
RawData data_
内部数据缓存 / Internal data cache
virtual ErrorCode WriteDeviceDescriptor(DeviceDescriptor &header)
可选:覆盖设备描述符字段 / Optional: override device descriptor fields
USB描述符基类 USB descriptor base class.
USB端点池类 / USB endpoint pool class.
单个 configuration 的配置项集合 / Item set for one configuration
size_t item_num
配置项数量 / Item count
ConfigDescriptorItem ** items
配置项指针表 / Item pointer table