7#include "libxr_type.hpp"
8#include "usb/core/bos.hpp"
10using namespace LibXR::USB;
13 : bos_cap_num_(bos_caps.size())
19 for (
auto* cap : bos_caps)
39 const std::initializer_list<const DescriptorStrings::LanguagePack*>& lang_list,
40 const std::initializer_list<
const std::initializer_list<ConfigDescriptorItem*>>&
43 : config_desc_(ep_pool, configs),
44 device_desc_(spec, packet_size, vid, pid, bcd, config_desc_.GetConfigNum()),
45 strings_(lang_list, reinterpret_cast<const uint8_t*>(uid.addr_), uid.size_),
46 endpoint_({ep_pool,
nullptr,
nullptr, {}, {}}),
57 ASSERT(IsValidUSBCombination(spec, speed, packet_size));
62 endpoint_.ep0_out_cb =
66void DeviceCore::OnEP0OutCompleteStatic(
bool in_isr,
DeviceCore* self,
69 self->OnEP0OutComplete(in_isr,
data);
72void DeviceCore::OnEP0InCompleteStatic(
bool in_isr,
DeviceCore* self,
75 self->OnEP0InComplete(in_isr,
data);
78bool DeviceCore::IsValidUSBCombination(USBSpec spec, Speed speed,
81 const uint8_t SIZE =
static_cast<uint8_t
>(packet_size);
88 return (spec == USBSpec::USB_1_0 || spec == USBSpec::USB_1_1) && SIZE == 8;
93 if (!(spec >= USBSpec::USB_1_0 && spec <= USBSpec::USB_2_1))
97 return SIZE == 8 || SIZE == 16 || SIZE == 32 || SIZE == 64;
102 if (spec < USBSpec::USB_2_0)
109 case Speed::SUPER_PLUS:
117void DeviceCore::ReadZLP(Context context)
119 state_.out0 = context;
120 endpoint_.out0->TransferZLP();
123void DeviceCore::WriteZLP(Context context)
125 state_.in0 = context;
126 endpoint_.in0->TransferZLP();
131 endpoint_.in0 = endpoint_.pool.GetEndpoint0In();
132 endpoint_.out0 = endpoint_.pool.GetEndpoint0Out();
137 endpoint_.in0->SetOnTransferCompleteCallback(endpoint_.ep0_in_cb);
138 endpoint_.out0->SetOnTransferCompleteCallback(endpoint_.ep0_out_cb);
148 state_.inited =
true;
153 state_.inited =
false;
155 endpoint_.in0->Close();
156 endpoint_.out0->Close();
165 auto status = this->state_.out0;
175 endpoint_.in0->Close();
178 state_.write_remain = {
nullptr, 0};
190 if (state_.read_remain.size_ > 0)
193 DevReadEP0Data(state_.read_remain, endpoint_.out0->MaxTransferSize());
195 else if (class_req_.read)
197 class_req_.read =
false;
198 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request, class_req_.data);
208 StallControlEndpoint();
222 auto status = state_.in0;
232 if (state_.pending_addr != 0xFF)
235 state_.pending_addr = 0xFF;
240 if (state_.write_remain.size_ > 0)
242 DevWriteEP0Data(state_.write_remain, endpoint_.in0->MaxTransferSize());
244 else if (state_.need_write_zlp)
246 state_.need_write_zlp =
false;
250 else if (class_req_.write)
252 class_req_.write =
false;
253 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request,
data);
258 StallControlEndpoint();
264 size_t request_size,
bool early_read_zlp)
270 if (request_size > 0 && request_size <
data.
size_)
279 StallControlEndpoint();
285 bool has_more =
data.
size_ > packet_max_length;
291 state_.write_remain = {
292 reinterpret_cast<const uint8_t*
>(
data.
addr_) + packet_max_length,
295 state_.need_write_zlp =
false;
299 state_.write_remain = {
nullptr, 0};
300 state_.need_write_zlp = (
data.
size_ % endpoint_.in0->MaxPacketSize()) == 0;
303 auto buffer = endpoint_.in0->GetBuffer();
309 if (early_read_zlp || (!has_more && !state_.need_write_zlp))
317void DeviceCore::DevReadEP0Data(
LibXR::RawData data,
size_t packet_max_length)
325 StallControlEndpoint();
333 state_.read_remain = {
nullptr, 0};
339 state_.read_remain = {
reinterpret_cast<uint8_t*
>(
data.
addr_) + packet_max_length,
344 state_.out0_buffer =
reinterpret_cast<uint8_t*
>(
data.
addr_);
356 RequestDirection direction =
357 static_cast<RequestDirection
>(setup->
bmRequestType & REQ_DIRECTION_MASK);
358 RequestType type =
static_cast<RequestType
>(setup->
bmRequestType & REQ_TYPE_MASK);
359 Recipient recipient =
static_cast<Recipient
>(setup->
bmRequestType & REQ_RECIPIENT_MASK);
361 if (endpoint_.in0->IsStalled())
363 endpoint_.in0->ClearStall();
366 if (endpoint_.out0->IsStalled())
368 endpoint_.out0->ClearStall();
371 ErrorCode ans = ErrorCode::OK;
375 case RequestType::STANDARD:
376 ans = ProcessStandardRequest(in_isr, setup, direction, recipient);
378 case RequestType::CLASS:
379 ans = ProcessClassRequest(in_isr, setup, direction, recipient);
381 case RequestType::VENDOR:
382 ans = ProcessVendorRequest(in_isr, setup, direction, recipient);
385 ans = ErrorCode::ARG_ERR;
389 if (ans != ErrorCode::OK)
391 StallControlEndpoint();
395ErrorCode DeviceCore::ProcessStandardRequest(
bool in_isr,
const SetupPacket*& setup,
396 RequestDirection direction,
405 StandardRequest req =
static_cast<StandardRequest
>(setup->
bRequest);
407 ErrorCode ans = ErrorCode::OK;
411 case StandardRequest::GET_STATUS:
414 ans = RespondWithStatus(setup, recipient);
417 case StandardRequest::CLEAR_FEATURE:
420 ans = ClearFeature(setup, recipient);
423 case StandardRequest::SET_FEATURE:
426 ans = ApplyFeature(setup, recipient);
429 case StandardRequest::SET_ADDRESS:
432 ans = PrepareAddressChange(setup->
wValue);
435 case StandardRequest::GET_DESCRIPTOR:
438 ans = SendDescriptor(in_isr, setup, recipient);
441 case StandardRequest::SET_DESCRIPTOR:
446 case StandardRequest::GET_CONFIGURATION:
449 ans = SendConfiguration();
452 case StandardRequest::SET_CONFIGURATION:
455 ans = SwitchConfiguration(setup->
wValue, in_isr);
458 case StandardRequest::GET_INTERFACE:
460 if (recipient != Recipient::INTERFACE)
462 ans = ErrorCode::ARG_ERR;
466 uint8_t interface_index =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
473 item->GetAltSetting(interface_index, alt);
477 ans = ErrorCode::NOT_FOUND;
482 return ErrorCode::OK;
485 case StandardRequest::SET_INTERFACE:
487 if (recipient != Recipient::INTERFACE)
489 ans = ErrorCode::ARG_ERR;
493 uint8_t interface_index =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
494 uint8_t alt_setting =
static_cast<uint8_t
>(setup->
wValue);
499 ans = ErrorCode::NOT_FOUND;
504 if (ans == ErrorCode::OK)
511 case StandardRequest::SYNCH_FRAME:
514 ans = ErrorCode::NOT_SUPPORT;
520 ans = ErrorCode::ARG_ERR;
527ErrorCode DeviceCore::RespondWithStatus(
const SetupPacket* setup, Recipient recipient)
531 return ErrorCode::ARG_ERR;
537 case Recipient::DEVICE:
541 case Recipient::INTERFACE:
545 case Recipient::ENDPOINT:
547 uint8_t ep_addr = setup->
wIndex & 0xFF;
549 endpoint_.pool.FindEndpoint(ep_addr, ep);
553 return ErrorCode::NOT_FOUND;
564 return ErrorCode::ARG_ERR;
568 DevWriteEP0Data(
data, endpoint_.in0->MaxTransferSize(), setup->
wLength);
570 return ErrorCode::OK;
573ErrorCode DeviceCore::ClearFeature(
const SetupPacket* setup, Recipient recipient)
577 case Recipient::ENDPOINT:
586 endpoint_.pool.FindEndpoint(ep_addr, ep);
594 return ErrorCode::NOT_FOUND;
599 return ErrorCode::ARG_ERR;
604 case Recipient::DEVICE:
614 return ErrorCode::ARG_ERR;
619 return ErrorCode::ARG_ERR;
622 return ErrorCode::OK;
625ErrorCode DeviceCore::ApplyFeature(
const SetupPacket* setup, Recipient recipient)
629 case Recipient::ENDPOINT:
633 uint8_t ep_addr = setup->
wIndex & 0xFF;
635 endpoint_.pool.FindEndpoint(ep_addr, ep);
643 return ErrorCode::NOT_FOUND;
648 return ErrorCode::ARG_ERR;
653 case Recipient::DEVICE:
661 return ErrorCode::ARG_ERR;
666 return ErrorCode::ARG_ERR;
669 return ErrorCode::OK;
672ErrorCode DeviceCore::SendDescriptor(
bool in_isr,
const SetupPacket* setup,
675 uint8_t desc_type = (setup->
wValue >> 8) & 0xFF;
676 uint8_t desc_idx = (setup->
wValue) & 0xFF;
679 bool early_read_zlp =
false;
691 early_read_zlp =
true;
701 uint8_t string_idx = desc_idx;
702 uint16_t lang = setup->
wIndex;
711 if (ec != ErrorCode::OK)
725 early_read_zlp =
true;
731 return ErrorCode::NOT_SUPPORT;
735 uint8_t intf_num = 0;
737 if (recipient == Recipient::INTERFACE)
739 intf_num = setup->
wIndex & 0xFF;
743 return ErrorCode::ARG_ERR;
748 if (item && item->OnGetDescriptor(in_isr, setup->
bRequest, setup->
wValue,
753 return ErrorCode::ARG_ERR;
757 DevWriteEP0Data(
data, endpoint_.in0->MaxTransferSize(), setup->
wLength, early_read_zlp);
758 return ErrorCode::OK;
761ErrorCode DeviceCore::PrepareAddressChange(uint16_t address)
763 state_.pending_addr =
static_cast<uint8_t
>(address & 0x7F);
769ErrorCode DeviceCore::SwitchConfiguration(uint16_t value,
bool in_isr)
774 return ErrorCode::NOT_SUPPORT;
779 return ErrorCode::NOT_FOUND;
788 return ErrorCode::OK;
791ErrorCode DeviceCore::SendConfiguration()
795 DevWriteEP0Data(
data, endpoint_.in0->MaxTransferSize(), 1);
797 return ErrorCode::OK;
800void DeviceCore::StallControlEndpoint()
802 endpoint_.pool.GetEndpoint0Out()->Stall();
803 endpoint_.pool.GetEndpoint0In()->Stall();
806void DeviceCore::ClearControlEndpointStall()
808 endpoint_.pool.GetEndpoint0Out()->ClearStall();
809 endpoint_.pool.GetEndpoint0In()->ClearStall();
812ErrorCode DeviceCore::ProcessClassRequest(
bool in_isr,
const SetupPacket* setup,
820 return ErrorCode::NOT_SUPPORT;
827 case Recipient::INTERFACE:
831 uint8_t if_num =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
836 case Recipient::ENDPOINT:
840 uint8_t ep_addr =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
848 return ErrorCode::NOT_SUPPORT;
853 return ErrorCode::NOT_FOUND;
859 if (ec != ErrorCode::OK)
866 const bool HAS_READ_BUF = (result.read_data.size_ > 0);
867 const bool HAS_WRITE_BUF = (result.write_data.size_ > 0);
868 if (HAS_READ_BUF && HAS_WRITE_BUF)
870 return ErrorCode::ARG_ERR;
877 if (setup->
wLength == 0 || result.read_data.size_ < setup->
wLength)
879 return ErrorCode::ARG_ERR;
882 class_req_.read =
true;
883 class_req_.class_ptr = item;
884 class_req_.b_request = setup->
bRequest;
885 class_req_.data = result.read_data;
887 DevReadEP0Data(result.read_data, endpoint_.in0->MaxTransferSize());
888 return ErrorCode::OK;
897 return ErrorCode::ARG_ERR;
900 class_req_.write =
true;
901 class_req_.class_ptr = item;
902 class_req_.b_request = setup->
bRequest;
903 class_req_.data = result.write_data;
905 DevWriteEP0Data(result.write_data, endpoint_.in0->MaxTransferSize());
906 return ErrorCode::OK;
914 return ErrorCode::OK;
916 if (result.write_zlp)
919 return ErrorCode::OK;
922 return ErrorCode::OK;
925ErrorCode DeviceCore::ProcessVendorRequest(
bool in_isr,
const SetupPacket*& setup,
933 return ErrorCode::NOT_SUPPORT;
940 auto bec =
config_desc_.BosManager::ProcessVendorRequest(in_isr, setup, bos_ret);
941 if (bec == ErrorCode::OK && bos_ret.handled)
943 if (bos_ret.in_data.addr_ !=
nullptr && bos_ret.in_data.size_ > 0)
947 return ErrorCode::ARG_ERR;
950 DevWriteEP0Data(bos_ret.in_data, endpoint_.in0->MaxTransferSize(), setup->
wLength,
951 bos_ret.early_read_zlp);
952 return ErrorCode::OK;
955 if (bos_ret.write_zlp)
958 return ErrorCode::OK;
964 return ErrorCode::OK;
969 if (bec != ErrorCode::NOT_SUPPORT && bec != ErrorCode::OK)
979 case Recipient::INTERFACE:
981 uint8_t if_num =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
986 case Recipient::ENDPOINT:
988 uint8_t ep_addr =
static_cast<uint8_t
>(setup->
wIndex & 0xFF);
996 return ErrorCode::NOT_SUPPORT;
1001 return ErrorCode::NOT_FOUND;
1007 if (ec != ErrorCode::OK)
1012 const bool HAS_READ_BUF = (result.read_data.size_ > 0);
1013 const bool HAS_WRITE_BUF = (result.write_data.size_ > 0);
1015 if (HAS_READ_BUF && HAS_WRITE_BUF)
1017 return ErrorCode::ARG_ERR;
1024 if (setup->
wLength == 0 || result.read_data.size_ < setup->
wLength)
1026 return ErrorCode::ARG_ERR;
1029 class_req_.read =
true;
1030 class_req_.write =
false;
1031 class_req_.class_ptr = item;
1032 class_req_.b_request = setup->
bRequest;
1033 class_req_.data = result.read_data;
1035 DevReadEP0Data(result.read_data, endpoint_.in0->MaxTransferSize());
1036 return ErrorCode::OK;
1045 return ErrorCode::ARG_ERR;
1048 class_req_.write =
true;
1049 class_req_.read =
false;
1050 class_req_.class_ptr = item;
1051 class_req_.b_request = setup->
bRequest;
1052 class_req_.data = result.write_data;
1054 DevWriteEP0Data(result.write_data, endpoint_.in0->MaxTransferSize(), setup->
wLength);
1055 return ErrorCode::OK;
1060 if (result.read_zlp)
1063 return ErrorCode::OK;
1065 if (result.write_zlp)
1068 return ErrorCode::OK;
1071 return ErrorCode::OK;
static Callback Create(FunType fun, ArgType arg)
创建回调对象并绑定回调函数与参数 / Create a callback instance with bound function and argument
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
原始数据封装类。 A class for encapsulating raw data.
BOS 能力接口 / BOS capability interface.
ConstRawData GetBosDescriptor()
构建 BOS 描述符(BOS 头 + 能力块) Build BOS descriptor (header + blocks).
RawData GetData() const
获取配置描述符数据 / Get configuration descriptor data
ConfigDescriptorItem * FindItemByInterfaceNumber(size_t index) const
按接口号查找配置项 / Find item by interface number
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
void BindEndpoints(bool in_isr)
绑定当前配置端点 / Bind endpoints for current configuration
ConfigDescriptorItem * FindItemByEndpointAddress(uint8_t addr) const
按端点地址查找配置项 / Find item by endpoint address
ErrorCode BuildConfigDescriptor()
构建当前配置描述符 / Build current configuration descriptor
void RebuildBosCache()
重建 BOS 缓存 / Rebuild BOS cache
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
virtual ErrorCode SetAltSetting(uint8_t itf, uint8_t alt)
可选:设置接口备用设置 / Optional: set interface alternate setting
ErrorCode GenerateString(Index index, uint16_t lang)
生成指定语言和索引的字符串描述符 Generate USB string descriptor for given language and string index
RawData GetData()
获取当前构建好的字符串描述符数据 Get the descriptor buffer
RawData GetLangIDData()
获取语言ID描述符内容 Get LangID descriptor data
Index
描述符字符串索引 / USB descriptor string index
USB 设备类接口基类 / USB device class interface base.
virtual ErrorCode OnClassRequest(bool in_isr, uint8_t bRequest, uint16_t wValue, uint16_t wLength, uint16_t wIndex, ControlTransferResult &result)
处理 Class-specific 请求(Setup stage)/ Handle class-specific request (Setup stage)
virtual ErrorCode OnVendorRequest(bool in_isr, uint8_t bRequest, uint16_t wValue, uint16_t wLength, uint16_t wIndex, ControlTransferResult &result)
处理 Vendor request(Setup stage)/ Handle vendor request (Setup stage)
~DeviceClass() override
析构函数 / Destructor
size_t bos_cap_num_
BOS capability 数量 / BOS capability count.
BosCapability ** bos_caps_
BOS capability 指针表 / BOS capability pointer table.
DeviceClass(std::initializer_list< BosCapability * > bos_caps={})
构造:传入本类提供的 BOS capabilities(对象指针列表) Constructor: pass BOS capabilities provided by this class (pointe...
USB 设备协议栈核心:EP0 控制传输、描述符、配置、标准/类/厂商请求 USB device core: EP0 control transfer, descriptors,...
virtual void Deinit(bool in_isr)
反初始化 / Deinitialize
virtual void EnableRemoteWakeup()
启用远程唤醒 / Enable remote wakeup
ConfigDescriptor config_desc_
配置描述符管理器 / Configuration descriptor manager
ConstRawData data
数据阶段数据 / Data stage payload
@ SETUP
Setup stage / Setup stage.
@ STATUS_IN
IN status stage / IN status stage.
@ DATA_OUT
OUT data stage / OUT data stage.
@ STATUS_OUT
OUT status stage / OUT status stage.
@ DATA_IN
IN data stage / IN data stage.
@ ZLP
ZLP stage marker / ZLP stage marker.
virtual void Init(bool in_isr)
初始化 / Initialize
DeviceDescriptor device_desc_
设备描述符 / Device descriptor
Speed GetSpeed() const
获取设备速度 / Get device speed
virtual void DisableRemoteWakeup()
禁用远程唤醒 / Disable remote wakeup
DeviceCore(EndpointPool &ep_pool, USBSpec spec, Speed speed, DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid, uint16_t bcd, const std::initializer_list< const DescriptorStrings::LanguagePack * > &lang_list, const std::initializer_list< const std::initializer_list< ConfigDescriptorItem * > > &configs, ConstRawData uid={nullptr, 0})
构造函数 / Constructor
Speed speed
设备速度 / Device speed
DescriptorStrings strings_
字符串描述符管理器 / String descriptor manager
void OnSetupPacket(bool in_isr, const SetupPacket *setup)
处理 Setup 包 / Handle Setup packet
virtual ErrorCode SetAddress(uint8_t address, Context state)=0
设置设备地址(由子类实现) Set device address (implemented by derived class).
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
RawData GetData()
获取设备描述符的原始数据指针及长度 Get the raw device descriptor data pointer and length
USB 端点基类 / USB Endpoint base class.
virtual ErrorCode Stall()=0
置 STALL / Stall endpoint
@ OUT
输出方向 / OUT direction
virtual ErrorCode ClearStall()=0
清除 STALL / Clear stall
State GetState() const
获取端点状态 / Get endpoint state
USB端点池类 / USB endpoint pool class.
Vendor 请求处理结果(EP0 控制传输) Vendor request handling result for EP0 control transfers.
控制请求(Class/Vendor)处理结果 / Control request (Class/Vendor) handling result
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
uint16_t wIndex
对象索引,如接口号或端点号 / Index (e.g., interface or endpoint)
uint16_t wLength
数据阶段长度 / Number of bytes in data stage
uint16_t wValue
参数字段,含请求相关值 / Value field (e.g., descriptor type/index)
uint8_t bRequest
请求码 / Request code (e.g., GET_DESCRIPTOR)