libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
desc_cfg.cpp
1#include "desc_cfg.hpp"
2
3using namespace LibXR::USB;
4
6
7bool ConfigDescriptor::IsCompositeConfig(
8 const std::initializer_list<const std::initializer_list<ConfigDescriptorItem*>>&
9 configs)
10{
11 // 复合设备:有多个功能项(接口块),或某功能项含多个接口
12 // 判断标准:configs.size() > 1 或者 (有一项 GetInterfaceNum() > 1)
13 if (configs.size() > 1)
14 {
15 return true;
16 }
17 for (const auto& group : configs)
18 {
19 if (group.size() > 1)
20 {
21 return true;
22 }
23 for (const auto& item : group)
24 {
25 if (item->HasIAD())
26 {
27 return true;
28 }
29 }
30 }
31 return false;
32}
33
35 EndpointPool& endpoint_pool,
36 const std::initializer_list<const std::initializer_list<ConfigDescriptorItem*>>&
37 configs,
38 uint8_t bmAttributes, uint8_t bMaxPower)
39 : endpoint_pool_(endpoint_pool),
40 bm_attributes_(bmAttributes),
41 b_max_power_(bMaxPower),
42 COMPOSITE(IsCompositeConfig(configs)),
43 CFG_NUM(configs.size()),
44 items_(new Config[CFG_NUM])
45{
46 ASSERT(CFG_NUM > 0);
47
48 size_t max_config_size = 0;
49 size_t config_index = 0;
50 for (auto config : configs)
51 {
52 size_t config_size = sizeof(Header);
53 size_t item_index = 0;
54 items_[config_index].item_num = config.size();
55 items_[config_index].items = new ConfigDescriptorItem*[config.size()];
56 for (auto item : config)
57 {
58 config_size += item->GetMaxConfigSize();
59 items_[config_index].items[item_index] = item;
60 item_index++;
61 }
62
63 if (config_size > max_config_size)
64 {
65 max_config_size = config_size;
66 }
67 config_index++;
68 }
69
70 buffer_.addr_ = new uint8_t[max_config_size];
71 buffer_.size_ = max_config_size;
72}
73
74ErrorCode ConfigDescriptor::SwitchConfig(size_t index)
75{
76 if (index == 0 || index > CFG_NUM)
77 {
78 return ErrorCode::NOT_FOUND;
79 }
80
82 current_cfg_ = index - 1;
84 return ErrorCode::OK;
85}
86
88{
89 if (ep_assigned_)
90 {
91 return;
92 }
93 ep_assigned_ = true;
94
95 auto config = items_[current_cfg_];
96
97 size_t start_itf = 0;
98
99 for (size_t i = 0; i < config.item_num; ++i)
100 {
101 config.items[i]->Init(endpoint_pool_, start_itf);
102 start_itf += config.items[i]->GetInterfaceNum();
103 }
104}
105
107{
108 if (!ep_assigned_)
109 {
110 return;
111 }
112 ep_assigned_ = false;
113
114 auto config = items_[current_cfg_];
115
116 for (size_t i = 0; i < config.item_num; ++i)
117 {
118 config.items[i]->Deinit(endpoint_pool_);
119 }
120}
121
123{
124 uint8_t* buffer = reinterpret_cast<uint8_t*>(buffer_.addr_);
125 Header* header = reinterpret_cast<Header*>(buffer);
126
127 // 填充默认或已设定的 header 信息
128 *header = Header{};
129
130 header->bLength = 9;
131 header->bDescriptorType = 0x02;
132 header->bConfigurationValue = this->current_cfg_ + 1;
133 header->iConfiguration = this->i_configuration_;
134 header->bmAttributes = this->bm_attributes_;
135 header->bMaxPower = this->b_max_power_;
136
137 size_t offset = sizeof(Header);
138 uint8_t total_interfaces = 0;
139
140 auto config = items_[current_cfg_];
141
142 for (size_t i = 0; i < config.item_num; ++i)
143 {
144 auto data = config.items[i]->GetData();
145
146 LibXR::Memory::FastCopy(&buffer[offset], data.addr_, data.size_);
147 offset += data.size_;
148
149 total_interfaces += config.items[i]->GetInterfaceNum();
150 }
151
152 header->wTotalLength = offset;
153 header->bNumInterfaces = total_interfaces;
154 buffer_index_ = offset;
155
156 return ErrorCode::OK;
157}
158
160
162{
163 if (COMPOSITE || items_[current_cfg_].item_num != 1)
164 {
165 return ErrorCode::NOT_SUPPORT;
166 }
167
168 auto config = items_[0];
169
170 if (config.item_num != 1 || config.items[0]->GetInterfaceNum() != 1)
171 {
172 return ErrorCode::NOT_SUPPORT;
173 }
174
175 return config.items[0]->WriteDeviceDescriptor(descriptor);
176}
177
179
180size_t ConfigDescriptor::GetConfigNum() const { return CFG_NUM; }
181
183
185{
186 return ((bm_attributes_ & CFG_SELF_POWERED) ? 0x01 : 0x00) |
187 ((bm_attributes_ & CFG_REMOTE_WAKEUP) ? 0x02 : 0x00);
188}
189
191{
192 auto config = items_[current_cfg_];
193 int interface_index = -1;
194 for (size_t i = 0; i < config.item_num; ++i)
195 {
196 interface_index += config.items[i]->GetInterfaceNum();
197 if (interface_index >= static_cast<int>(index))
198 {
199 return config.items[i];
200 }
201 }
202 return nullptr;
203}
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:17
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
bool IsComposite() const
判断是否为复合设备(composite device) Check if this is a composite device
Definition desc_cfg.cpp:159
RawData GetData() const
获取拼接好的配置描述符数据 Get the generated configuration descriptor data
Definition desc_cfg.cpp:178
uint8_t i_configuration_
配置字符串索引 / String descriptor index
Definition desc_cfg.hpp:320
uint8_t bm_attributes_
配置属性 / bmAttributes
Definition desc_cfg.hpp:321
uint16_t GetDeviceStatus() const
获取当前设备状态 / Get the current device status
Definition desc_cfg.cpp:184
void AssignEndpoints()
分配端点并分配总缓冲区 Assign endpoints and allocate the total config descriptor buffer
Definition desc_cfg.cpp:87
ErrorCode OverrideDeviceDescriptor(DeviceDescriptor &descriptor)
覆盖设备描述符(非IAD时可用) Override the device descriptor (can be used when not using IAD)
Definition desc_cfg.cpp:161
uint8_t current_cfg_
配置值 / Configuration value
Definition desc_cfg.hpp:319
size_t GetConfigNum() const
获取配置项数量 / Get the number of configuration items
Definition desc_cfg.cpp:180
bool ep_assigned_
端点是否已分配 / Is endpoint assigned
Definition desc_cfg.hpp:316
const bool COMPOSITE
是否为复合设备 / Is composite device
Definition desc_cfg.hpp:324
size_t buffer_index_
数据写入索引 / Write index (for internal use)
Definition desc_cfg.hpp:328
void ReleaseEndpoints()
释放所有功能项占用的端点资源 Release all endpoints/resources allocated by function blocks
Definition desc_cfg.cpp:106
EndpointPool & endpoint_pool_
端点资源池 / Endpoint pool
Definition desc_cfg.hpp:318
uint8_t b_max_power_
最大电流(2mA 单位)/ Max power (2mA unit)
Definition desc_cfg.hpp:322
const size_t CFG_NUM
当前功能项数 / Current item count
Definition desc_cfg.hpp:325
ErrorCode Generate()
生成完整的配置描述符(自动拼接 header 和所有功能项数据) Generate and assemble the full configuration descriptor (header + al...
Definition desc_cfg.cpp:122
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: setup item list and descriptor attributes
Definition desc_cfg.cpp:34
Config * items_
功能项数组 / Item array
Definition desc_cfg.hpp:326
RawData buffer_
拼接后的描述符缓冲区 / Assembled descriptor buffer
Definition desc_cfg.hpp:327
size_t GetCurrentConfig() const
获取当前配置值 / Get the current configuration value
Definition desc_cfg.cpp:182
ConfigDescriptorItem * GetItemByInterfaceNum(size_t index) const
获取指定接口的配置项 / Get the configuration item by interface number
Definition desc_cfg.cpp:190
USB 配置项接口类 USB configuration item base class.
Definition desc_cfg.hpp:29
RawData GetData()
获取本配置项描述符的二进制数据 Get the binary data of this configuration item
Definition desc_cfg.cpp:5
virtual ErrorCode WriteDeviceDescriptor(DeviceDescriptor &header)
写入/补全设备描述符(非IAD情况下会被调用) Write device descriptor (non-IAD case will be called)
Definition desc_cfg.hpp:120
USB描述符基类 USB descriptor base class.
Definition desc_dev.hpp:37
USB端点池类 / USB endpoint pool class.
Definition ep_pool.hpp:23
配置描述符头部结构体 Configuration descriptor header (USB 2.0 Spec 9.6.3)
Definition desc_cfg.hpp:38
uint8_t bLength
结构体长度 / Descriptor length (always 9)
Definition desc_cfg.hpp:39
uint8_t bmAttributes
属性位 / Attributes bitmap
Definition desc_cfg.hpp:46
uint8_t bNumInterfaces
接口数量 / Number of interfaces
Definition desc_cfg.hpp:43
uint8_t bMaxPower
最大电流(单位2mA)/ Max power (in units of 2mA)
Definition desc_cfg.hpp:47
uint8_t bConfigurationValue
配置值 / Configuration value
Definition desc_cfg.hpp:44
uint8_t iConfiguration
字符串描述符索引 / String descriptor index
Definition desc_cfg.hpp:45
uint8_t bDescriptorType
描述符类型(0x02)/ Descriptor type (0x02)
Definition desc_cfg.hpp:40