libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
dev_core.cpp
1#include "dev_core.hpp"
2
3#include <cstdint>
4
5#include "core.hpp"
6#include "desc_cfg.hpp"
7#include "libxr_type.hpp"
8#include "usb/core/bos.hpp"
9
10using namespace LibXR::USB;
11
12DeviceClass::DeviceClass(std::initializer_list<BosCapability*> bos_caps)
13 : bos_cap_num_(bos_caps.size())
14{
15 if (bos_cap_num_ > 0)
16 {
18 size_t i = 0;
19 for (auto* cap : bos_caps)
20 {
21 bos_caps_[i++] = cap;
22 }
23 }
24}
25
27{
28 // 仅释放指针数组本身(capability 对象生命周期由派生类成员管理)
29 // Only free the pointer array itself (capability objects are owned by derived class
30 // members).
31 delete[] bos_caps_;
32 bos_caps_ = nullptr;
33 bos_cap_num_ = 0;
34}
35
37 EndpointPool& ep_pool, USBSpec spec, Speed speed,
38 DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid, uint16_t bcd,
39 const std::initializer_list<const DescriptorStrings::LanguagePack*>& lang_list,
40 const std::initializer_list<const std::initializer_list<ConfigDescriptorItem*>>&
41 configs,
42 ConstRawData uid)
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, {}, {}}),
47 state_({false,
48 speed,
49 Context::UNKNOWN,
50 Context::UNKNOWN,
51 {nullptr, 0},
52 {nullptr, 0},
53 0xff,
54 nullptr,
55 false})
56{
57 ASSERT(IsValidUSBCombination(spec, speed, packet_size));
58
59 endpoint_.ep0_in_cb =
60 LibXR::Callback<LibXR::ConstRawData&>::Create(OnEP0InCompleteStatic, this);
61
62 endpoint_.ep0_out_cb =
63 LibXR::Callback<LibXR::ConstRawData&>::Create(OnEP0OutCompleteStatic, this);
64}
65
66void DeviceCore::OnEP0OutCompleteStatic(bool in_isr, DeviceCore* self,
68{
69 self->OnEP0OutComplete(in_isr, data);
70}
71
72void DeviceCore::OnEP0InCompleteStatic(bool in_isr, DeviceCore* self,
74{
75 self->OnEP0InComplete(in_isr, data);
76}
77
78bool DeviceCore::IsValidUSBCombination(USBSpec spec, Speed speed,
80{
81 const uint8_t SIZE = static_cast<uint8_t>(packet_size);
82
83 switch (speed)
84 {
85 case Speed::LOW:
86 // USB 1.0/1.1 可允许 LOW,包长必须为 8
87 // USB 1.0/1.1 allows LOW speed; EP0 max packet size must be 8.
88 return (spec == USBSpec::USB_1_0 || spec == USBSpec::USB_1_1) && SIZE == 8;
89
90 case Speed::FULL:
91 // USB 1.x/2.0 均可运行在 FULL
92 // USB 1.x/2.0 can run at FULL speed.
93 if (!(spec >= USBSpec::USB_1_0 && spec <= USBSpec::USB_2_1))
94 {
95 return false;
96 }
97 return SIZE == 8 || SIZE == 16 || SIZE == 32 || SIZE == 64;
98
99 case Speed::HIGH:
100 // 只有 USB 2.0+ 才能跑 HIGH,包长必须是 64
101 // Only USB 2.0+ supports HIGH speed; EP0 max packet size must be 64.
102 if (spec < USBSpec::USB_2_0)
103 {
104 return false;
105 }
106 return SIZE == 64;
107
108 case Speed::SUPER: // NOLINT
109 case Speed::SUPER_PLUS:
110 return false;
111
112 default:
113 return false;
114 }
115}
116
117void DeviceCore::ReadZLP(Context context)
118{
119 state_.out0 = context;
120 endpoint_.out0->TransferZLP();
121}
122
123void DeviceCore::WriteZLP(Context context)
124{
125 state_.in0 = context;
126 endpoint_.in0->TransferZLP();
127}
128
129void DeviceCore::Init(bool in_isr)
130{
131 endpoint_.in0 = endpoint_.pool.GetEndpoint0In();
132 endpoint_.out0 = endpoint_.pool.GetEndpoint0Out();
133
134 endpoint_.in0->Configure({Endpoint::Direction::IN, Endpoint::Type::CONTROL, 64});
135 endpoint_.out0->Configure({Endpoint::Direction::OUT, Endpoint::Type::CONTROL, 64});
136
137 endpoint_.in0->SetOnTransferCompleteCallback(endpoint_.ep0_in_cb);
138 endpoint_.out0->SetOnTransferCompleteCallback(endpoint_.ep0_out_cb);
139
141
142 // 收集 BOS capabilities(以对象形式收集;BOS 构建由 BosManager 在 GET_DESCRIPTOR(BOS)
143 // 时动态完成)
144 // Collect BOS capabilities (as objects; BOS building is done dynamically by BosManager
145 // on GET_DESCRIPTOR(BOS)).
147
148 state_.inited = true;
149}
150
151void DeviceCore::Deinit(bool in_isr)
152{
153 state_.inited = false;
155 endpoint_.in0->Close();
156 endpoint_.out0->Close();
157}
158
159void DeviceCore::OnEP0OutComplete(bool in_isr, LibXR::ConstRawData& data)
160{
161 if (!state_.inited)
162 {
163 return;
164 }
165 auto status = this->state_.out0;
166 state_.out0 = Context::UNKNOWN;
167
168 switch (status)
169 {
170 case Context::ZLP:
171 // 主机中断 IN 操作后,重新配置控制端点
172 // Re-configure control endpoint after host aborts IN transfer.
173 if (endpoint_.in0->GetState() == Endpoint::State::BUSY)
174 {
175 endpoint_.in0->Close();
176 endpoint_.in0->Configure({Endpoint::Direction::IN, Endpoint::Type::CONTROL, 64});
177 state_.in0 = Context::ZLP;
178 state_.write_remain = {nullptr, 0};
179 }
180 // fall through
182 break;
183
185 if (data.size_ > 0)
186 {
187 LibXR::Memory::FastCopy(state_.out0_buffer, data.addr_, data.size_);
188 }
189
190 if (state_.read_remain.size_ > 0)
191 {
192 state_.out0_buffer += data.size_;
193 DevReadEP0Data(state_.read_remain, endpoint_.out0->MaxTransferSize());
194 }
195 else if (class_req_.read)
196 {
197 class_req_.read = false;
198 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request, class_req_.data);
199 WriteZLP();
200 }
201 else
202 {
203 WriteZLP();
204 }
205 break;
206
207 default:
208 StallControlEndpoint();
209 break;
210 }
211}
212
213void DeviceCore::OnEP0InComplete(bool in_isr, LibXR::ConstRawData& data)
214{
215 if (!state_.inited)
216 {
217 return;
218 }
219 UNUSED(in_isr);
220 UNUSED(data);
221
222 auto status = state_.in0;
223
224 state_.in0 = Context::UNKNOWN;
225
226 switch (status)
227 {
228 case Context::ZLP:
229 break;
230
232 if (state_.pending_addr != 0xFF)
233 {
234 SetAddress(state_.pending_addr, Context::STATUS_IN);
235 state_.pending_addr = 0xFF;
236 }
237 break;
238
239 case Context::DATA_IN:
240 if (state_.write_remain.size_ > 0)
241 {
242 DevWriteEP0Data(state_.write_remain, endpoint_.in0->MaxTransferSize());
243 }
244 else if (state_.need_write_zlp)
245 {
246 state_.need_write_zlp = false;
247 ReadZLP();
248 WriteZLP();
249 }
250 else if (class_req_.write)
251 {
252 class_req_.write = false;
253 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request, data);
254 }
255 break;
256
257 default:
258 StallControlEndpoint();
259 break;
260 }
261}
262
263void DeviceCore::DevWriteEP0Data(LibXR::ConstRawData data, size_t packet_max_length,
264 size_t request_size, bool early_read_zlp)
265{
266 state_.in0 = Context::DATA_IN;
267
268 // 限制最大传输长度
269 // Clamp max transfer length.
270 if (request_size > 0 && request_size < data.size_)
271 {
272 data.size_ = request_size;
273 }
274
275 // 数据长度为 0,直接 STALL(协议层面不允许)
276 // If length is 0, STALL directly (not allowed by protocol).
277 if (data.size_ == 0 || data.size_ > 0xFFFF)
278 {
279 StallControlEndpoint();
280 return;
281 }
282
283 // 判断是否需要拆包或发送 ZLP
284 // Determine whether to split packets or send ZLP.
285 bool has_more = data.size_ > packet_max_length;
286
287 // 拆分数据包
288 // Split packets.
289 if (has_more)
290 {
291 state_.write_remain = {
292 reinterpret_cast<const uint8_t*>(data.addr_) + packet_max_length,
293 data.size_ - packet_max_length};
294 data.size_ = packet_max_length;
295 state_.need_write_zlp = false;
296 }
297 else
298 {
299 state_.write_remain = {nullptr, 0};
300 state_.need_write_zlp = (data.size_ % endpoint_.in0->MaxPacketSize()) == 0;
301 }
302
303 auto buffer = endpoint_.in0->GetBuffer();
304 ASSERT(buffer.size_ >= data.size_);
306
307 // early_read_zlp 防止主机实际读取小于 wLength,提前进入 DATA_OUT 阶段
308 // early_read_zlp: enter DATA_OUT early to tolerate host short-read (< wLength).
309 if (early_read_zlp || (!has_more && !state_.need_write_zlp))
310 {
311 ReadZLP();
312 }
313
314 endpoint_.in0->Transfer(data.size_);
315}
316
317void DeviceCore::DevReadEP0Data(LibXR::RawData data, size_t packet_max_length)
318{
319 state_.out0 = Context::DATA_OUT;
320
321 // 限制最大接收长度
322 // Validate/clamp max receive length.
323 if (data.size_ == 0 || data.size_ > 0xFFFF)
324 {
325 StallControlEndpoint();
326 return;
327 }
328
329 // 数据长度 <= 一个包长,直接收一次即可
330 // If length <= one packet, receive once.
331 if (data.size_ <= packet_max_length)
332 {
333 state_.read_remain = {nullptr, 0}; // 标记本次已收完 / Mark as completed
334 }
335 else
336 {
337 // 数据需要多包接收
338 // Multi-packet receive.
339 state_.read_remain = {reinterpret_cast<uint8_t*>(data.addr_) + packet_max_length,
340 data.size_ - packet_max_length};
341 data.size_ = packet_max_length;
342 }
343
344 state_.out0_buffer = reinterpret_cast<uint8_t*>(data.addr_);
345 endpoint_.out0->Transfer(data.size_); // 一次性收满,HAL/底层自动搞定多包 /
346 // Receive-full; HAL handles packetization
347}
348
349void DeviceCore::OnSetupPacket(bool in_isr, const SetupPacket* setup)
350{
351 if (!state_.inited)
352 {
353 return;
354 }
355
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);
360
361 if (endpoint_.in0->IsStalled())
362 {
363 endpoint_.in0->ClearStall();
364 }
365
366 if (endpoint_.out0->IsStalled())
367 {
368 endpoint_.out0->ClearStall();
369 }
370
371 ErrorCode ans = ErrorCode::OK;
372
373 switch (type)
374 {
375 case RequestType::STANDARD:
376 ans = ProcessStandardRequest(in_isr, setup, direction, recipient);
377 break;
378 case RequestType::CLASS:
379 ans = ProcessClassRequest(in_isr, setup, direction, recipient);
380 break;
381 case RequestType::VENDOR:
382 ans = ProcessVendorRequest(in_isr, setup, direction, recipient);
383 break;
384 default:
385 ans = ErrorCode::ARG_ERR;
386 break;
387 }
388
389 if (ans != ErrorCode::OK)
390 {
391 StallControlEndpoint();
392 }
393}
394
395ErrorCode DeviceCore::ProcessStandardRequest(bool in_isr, const SetupPacket*& setup,
396 RequestDirection direction,
397 Recipient recipient)
398{
399 UNUSED(in_isr);
400 UNUSED(direction);
401 UNUSED(recipient);
402
403 // 根据 recipient 处理不同目标的请求
404 // Handle requests for different recipients.
405 StandardRequest req = static_cast<StandardRequest>(setup->bRequest);
406
407 ErrorCode ans = ErrorCode::OK;
408
409 switch (req)
410 {
411 case StandardRequest::GET_STATUS:
412 // 设备/接口/端点的状态请求
413 // GET_STATUS for device/interface/endpoint.
414 ans = RespondWithStatus(setup, recipient);
415 break;
416
417 case StandardRequest::CLEAR_FEATURE:
418 // 解除某个特性(如端点的 HALT)
419 // Clear a feature (e.g., endpoint HALT).
420 ans = ClearFeature(setup, recipient);
421 break;
422
423 case StandardRequest::SET_FEATURE:
424 // 设置特性(如 Remote Wakeup/端点 STALL)
425 // Set a feature (e.g., remote wakeup/endpoint STALL).
426 ans = ApplyFeature(setup, recipient);
427 break;
428
429 case StandardRequest::SET_ADDRESS:
430 // 设置 USB 地址,status 阶段后生效
431 // Set USB address; takes effect after status stage.
432 ans = PrepareAddressChange(setup->wValue);
433 break;
434
435 case StandardRequest::GET_DESCRIPTOR:
436 // 返回设备/配置/字符串等描述符
437 // Return device/config/string descriptors.
438 ans = SendDescriptor(in_isr, setup, recipient);
439 break;
440
441 case StandardRequest::SET_DESCRIPTOR:
442 // TODO: 很少用,可选实现
443 // TODO: rarely used; optional implementation.
444 break;
445
446 case StandardRequest::GET_CONFIGURATION:
447 // 返回当前配置
448 // Return current configuration.
449 ans = SendConfiguration();
450 break;
451
452 case StandardRequest::SET_CONFIGURATION:
453 // 设置当前配置(切换 config 描述符索引)
454 // Set current configuration (switch configuration index).
455 ans = SwitchConfiguration(setup->wValue, in_isr);
456 break;
457
458 case StandardRequest::GET_INTERFACE:
459 {
460 if (recipient != Recipient::INTERFACE)
461 {
462 ans = ErrorCode::ARG_ERR;
463 break;
464 }
465
466 uint8_t interface_index = static_cast<uint8_t>(setup->wIndex & 0xFF);
467
468 uint8_t alt = 0;
469 auto item = config_desc_.FindItemByInterfaceNumber(interface_index);
470
471 if (item != nullptr)
472 {
473 item->GetAltSetting(interface_index, alt);
474 }
475 else
476 {
477 ans = ErrorCode::NOT_FOUND;
478 break;
479 }
480
481 DevWriteEP0Data(LibXR::ConstRawData(&alt, 1), endpoint_.in0->MaxTransferSize(), 1);
482 return ErrorCode::OK;
483 }
484
485 case StandardRequest::SET_INTERFACE:
486 {
487 if (recipient != Recipient::INTERFACE)
488 {
489 ans = ErrorCode::ARG_ERR;
490 break;
491 }
492
493 uint8_t interface_index = static_cast<uint8_t>(setup->wIndex & 0xFF);
494 uint8_t alt_setting = static_cast<uint8_t>(setup->wValue);
495
496 auto item = config_desc_.FindItemByInterfaceNumber(interface_index);
497 if (item == nullptr)
498 {
499 ans = ErrorCode::NOT_FOUND;
500 break;
501 }
502
503 ans = item->SetAltSetting(interface_index, alt_setting);
504 if (ans == ErrorCode::OK)
505 {
506 WriteZLP();
507 }
508 break;
509 }
510
511 case StandardRequest::SYNCH_FRAME:
512 // TODO: 一般仅用于同步端点
513 // TODO: typically used for isochronous endpoint sync.
514 ans = ErrorCode::NOT_SUPPORT;
515 break;
516
517 default:
518 // 未知请求,直接 STALL
519 // Unknown request; STALL.
520 ans = ErrorCode::ARG_ERR;
521 break;
522 }
523
524 return ans;
525}
526
527ErrorCode DeviceCore::RespondWithStatus(const SetupPacket* setup, Recipient recipient)
528{
529 if (setup->wLength != 2)
530 {
531 return ErrorCode::ARG_ERR;
532 }
533
534 uint16_t status = 0;
535 switch (recipient)
536 {
537 case Recipient::DEVICE:
538 status = config_desc_.GetDeviceStatus();
539 break;
540
541 case Recipient::INTERFACE:
542 status = 0x0000;
543 break;
544
545 case Recipient::ENDPOINT:
546 {
547 uint8_t ep_addr = setup->wIndex & 0xFF;
548 Endpoint* ep = nullptr;
549 endpoint_.pool.FindEndpoint(ep_addr, ep);
550
551 if (ep == nullptr)
552 {
553 return ErrorCode::NOT_FOUND;
554 }
555
557 {
558 status = 0x0001;
559 }
560 break;
561 }
562
563 default:
564 return ErrorCode::ARG_ERR;
565 }
566
567 LibXR::ConstRawData data(&status, 2);
568 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), setup->wLength);
569
570 return ErrorCode::OK;
571}
572
573ErrorCode DeviceCore::ClearFeature(const SetupPacket* setup, Recipient recipient)
574{
575 switch (recipient)
576 {
577 case Recipient::ENDPOINT:
578 {
579 // 只允许清除 ENDPOINT_HALT 特性(wValue==0)
580 // Only ENDPOINT_HALT (wValue==0) is allowed.
581 if (setup->wValue == 0) // 0 = ENDPOINT_HALT
582 {
583 uint8_t ep_addr =
584 setup->wIndex & 0xFF; // 端点号(低 7 位=EP 号, 高位=方向)/ Endpoint address
585 Endpoint* ep = nullptr;
586 endpoint_.pool.FindEndpoint(ep_addr, ep);
587 if (ep)
588 {
589 ep->ClearStall();
590 WriteZLP(); // 状态阶段:回复 ZLP / Status stage: send ZLP
591 }
592 else
593 {
594 return ErrorCode::NOT_FOUND;
595 }
596 }
597 else
598 {
599 return ErrorCode::ARG_ERR;
600 }
601 break;
602 }
603
604 case Recipient::DEVICE:
605 // 可选:处理 Remote Wakeup 等设备级特性
606 // Optional: device-level feature handling (e.g., remote wakeup).
607 if (setup->wValue == 1) // 1 = DEVICE_REMOTE_WAKEUP
608 {
610 WriteZLP();
611 }
612 else
613 {
614 return ErrorCode::ARG_ERR;
615 }
616 break;
617
618 default:
619 return ErrorCode::ARG_ERR;
620 }
621
622 return ErrorCode::OK;
623}
624
625ErrorCode DeviceCore::ApplyFeature(const SetupPacket* setup, Recipient recipient)
626{
627 switch (recipient)
628 {
629 case Recipient::ENDPOINT:
630 {
631 if (setup->wValue == 0) // 0 = ENDPOINT_HALT
632 {
633 uint8_t ep_addr = setup->wIndex & 0xFF;
634 Endpoint* ep = nullptr;
635 endpoint_.pool.FindEndpoint(ep_addr, ep);
636 if (ep)
637 {
638 ep->Stall();
639 WriteZLP(); // 状态阶段回复 ZLP / Status stage: send ZLP
640 }
641 else
642 {
643 return ErrorCode::NOT_FOUND;
644 }
645 }
646 else
647 {
648 return ErrorCode::ARG_ERR;
649 }
650 break;
651 }
652
653 case Recipient::DEVICE:
654 if (setup->wValue == 1) // 1 = DEVICE_REMOTE_WAKEUP
655 {
657 WriteZLP();
658 }
659 else
660 {
661 return ErrorCode::ARG_ERR;
662 }
663 break;
664
665 default:
666 return ErrorCode::ARG_ERR;
667 }
668
669 return ErrorCode::OK;
670}
671
672ErrorCode DeviceCore::SendDescriptor(bool in_isr, const SetupPacket* setup,
673 Recipient recipient)
674{
675 uint8_t desc_type = (setup->wValue >> 8) & 0xFF;
676 uint8_t desc_idx = (setup->wValue) & 0xFF;
677 ConstRawData data = {nullptr, 0};
678
679 bool early_read_zlp = false;
680
681 switch (desc_type)
682 {
683 case 0x01: // DEVICE
685 // 覆盖设备描述符(非 IAD 时可用)
686 // Override device descriptor (available when not using IAD).
688 {
690 }
691 early_read_zlp = true;
692 break;
693
694 case 0x02: // CONFIGURATION
697 break;
698
699 case 0x03: // STRING
700 {
701 uint8_t string_idx = desc_idx;
702 uint16_t lang = setup->wIndex;
703 if (string_idx == 0)
704 {
706 }
707 else
708 {
709 ErrorCode ec = strings_.GenerateString(
710 static_cast<DescriptorStrings::Index>(string_idx), lang);
711 if (ec != ErrorCode::OK)
712 {
713 return ec;
714 }
716 }
717 break;
718 }
719
720 // BOS (0x0F)
721 case 0x0F: // BOS
722 {
723 data = config_desc_.GetBosDescriptor(); // ConfigDescriptor 继承 BosManager /
724 // Inherits BosManager
725 early_read_zlp = true;
726 break;
727 }
728
729 case 0x06: // Device Qualifier
730 case 0x07: // Other Speed Configurations
731 return ErrorCode::NOT_SUPPORT;
732
733 default:
734 {
735 uint8_t intf_num = 0;
736
737 if (recipient == Recipient::INTERFACE)
738 {
739 intf_num = setup->wIndex & 0xFF;
740 }
741 else
742 {
743 return ErrorCode::ARG_ERR;
744 }
745
746 auto* item = reinterpret_cast<DeviceClass*>(
748 if (item && item->OnGetDescriptor(in_isr, setup->bRequest, setup->wValue,
749 setup->wLength, data) == ErrorCode::OK)
750 {
751 break;
752 }
753 return ErrorCode::ARG_ERR;
754 }
755 }
756
757 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), setup->wLength, early_read_zlp);
758 return ErrorCode::OK;
759}
760
761ErrorCode DeviceCore::PrepareAddressChange(uint16_t address)
762{
763 state_.pending_addr = static_cast<uint8_t>(address & 0x7F);
764
765 WriteZLP(Context::STATUS_IN);
766 return SetAddress(address, Context::SETUP);
767}
768
769ErrorCode DeviceCore::SwitchConfiguration(uint16_t value, bool in_isr)
770{
771 if (value == 0) // reset
772 {
773 // TODO: reset
774 return ErrorCode::NOT_SUPPORT;
775 }
776
777 if (config_desc_.SwitchConfig(value, in_isr) != ErrorCode::OK)
778 {
779 return ErrorCode::NOT_FOUND;
780 }
781
783
784 // ACK status 阶段
785 // ACK status stage.
786 WriteZLP();
787
788 return ErrorCode::OK;
789}
790
791ErrorCode DeviceCore::SendConfiguration()
792{
793 uint8_t cfg = config_desc_.GetCurrentConfig();
794 LibXR::ConstRawData data(&cfg, 1);
795 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), 1);
796
797 return ErrorCode::OK;
798}
799
800void DeviceCore::StallControlEndpoint()
801{
802 endpoint_.pool.GetEndpoint0Out()->Stall();
803 endpoint_.pool.GetEndpoint0In()->Stall();
804}
805
806void DeviceCore::ClearControlEndpointStall()
807{
808 endpoint_.pool.GetEndpoint0Out()->ClearStall();
809 endpoint_.pool.GetEndpoint0In()->ClearStall();
810}
811
812ErrorCode DeviceCore::ProcessClassRequest(bool in_isr, const SetupPacket* setup,
813 RequestDirection /*direction*/,
814 Recipient recipient)
815{
816 // 只处理 Class 请求(bmRequestType bits[6:5] == 01)
817 // Only handle Class requests (bmRequestType bits[6:5] == 01).
818 if ((setup->bmRequestType & 0x60) != 0x20)
819 {
820 return ErrorCode::NOT_SUPPORT;
821 }
822
823 DeviceClass* item = nullptr;
824
825 switch (recipient)
826 {
827 case Recipient::INTERFACE:
828 {
829 // 低字节 = 接口号
830 // Low byte = interface number.
831 uint8_t if_num = static_cast<uint8_t>(setup->wIndex & 0xFF);
832 item =
833 reinterpret_cast<DeviceClass*>(config_desc_.FindItemByInterfaceNumber(if_num));
834 break;
835 }
836 case Recipient::ENDPOINT:
837 {
838 // 低字节 = 端点地址(含 0x80 方向位)
839 // Low byte = endpoint address (including 0x80 direction bit).
840 uint8_t ep_addr = static_cast<uint8_t>(setup->wIndex & 0xFF);
841 item =
842 reinterpret_cast<DeviceClass*>(config_desc_.FindItemByEndpointAddress(ep_addr));
843 break;
844 }
845 default:
846 // Device/Other 一般不在这里处理
847 // Device/Other is typically not handled here.
848 return ErrorCode::NOT_SUPPORT;
849 }
850
851 if (!item)
852 {
853 return ErrorCode::NOT_FOUND;
854 }
855
857 auto ec = item->OnClassRequest(in_isr, setup->bRequest, setup->wValue, setup->wLength,
858 setup->wIndex, result);
859 if (ec != ErrorCode::OK)
860 {
861 return ec;
862 }
863
864 // 不允许同时提供读写缓冲
865 // Do not allow both read and write buffers simultaneously.
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)
869 {
870 return ErrorCode::ARG_ERR;
871 }
872
873 // Host->Device(OUT):从主机读数据进 read_data
874 // Host->Device (OUT): read host data into read_data.
875 if (HAS_READ_BUF)
876 {
877 if (setup->wLength == 0 || result.read_data.size_ < setup->wLength)
878 {
879 return ErrorCode::ARG_ERR;
880 }
881
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;
886
887 DevReadEP0Data(result.read_data, endpoint_.in0->MaxTransferSize());
888 return ErrorCode::OK;
889 }
890
891 // Device->Host(IN):从 write_data 发数据给主机
892 // Device->Host (IN): send write_data to host.
893 if (HAS_WRITE_BUF)
894 {
895 if (setup->wLength == 0)
896 {
897 return ErrorCode::ARG_ERR;
898 }
899
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;
904
905 DevWriteEP0Data(result.write_data, endpoint_.in0->MaxTransferSize());
906 return ErrorCode::OK;
907 }
908
909 // 无数据阶段:按类的意愿发送/接收 ZLP(如果有)
910 // No data stage: send/receive ZLP as requested by class (if any).
911 if (result.read_zlp)
912 {
913 ReadZLP();
914 return ErrorCode::OK;
915 }
916 if (result.write_zlp)
917 {
918 WriteZLP();
919 return ErrorCode::OK;
920 }
921
922 return ErrorCode::OK;
923}
924
925ErrorCode DeviceCore::ProcessVendorRequest(bool in_isr, const SetupPacket*& setup,
926 RequestDirection /*direction*/,
927 Recipient recipient)
928{
929 // 只处理 Vendor 请求(bmRequestType bits[6:5] == 10)
930 // Only handle Vendor requests (bmRequestType bits[6:5] == 10).
931 if ((setup->bmRequestType & 0x60) != 0x40)
932 {
933 return ErrorCode::NOT_SUPPORT;
934 }
935
936 // 先交给 BOS capabilities 尝试处理(WinUSB / WebUSB / ContainerID 等)
937 // First, try BOS capabilities (WinUSB / WebUSB / ContainerID, etc.).
938 {
939 BosVendorResult bos_ret{};
940 auto bec = config_desc_.BosManager::ProcessVendorRequest(in_isr, setup, bos_ret);
941 if (bec == ErrorCode::OK && bos_ret.handled)
942 {
943 if (bos_ret.in_data.addr_ != nullptr && bos_ret.in_data.size_ > 0)
944 {
945 if (setup->wLength == 0)
946 {
947 return ErrorCode::ARG_ERR;
948 }
949
950 DevWriteEP0Data(bos_ret.in_data, endpoint_.in0->MaxTransferSize(), setup->wLength,
951 bos_ret.early_read_zlp);
952 return ErrorCode::OK;
953 }
954
955 if (bos_ret.write_zlp)
956 {
957 WriteZLP();
958 return ErrorCode::OK;
959 }
960
961 // handled 但既没有 in_data 也没有 write_zlp:默认 ACK
962 // handled but no in_data and no write_zlp: default ACK.
963 WriteZLP();
964 return ErrorCode::OK;
965 }
966
967 // bec != OK:匹配但错误,直接返回让上层 STALL
968 // bec != OK: matched but failed; return to upper layer to STALL.
969 if (bec != ErrorCode::NOT_SUPPORT && bec != ErrorCode::OK)
970 {
971 return bec;
972 }
973 }
974
975 DeviceClass* item = nullptr;
976
977 switch (recipient)
978 {
979 case Recipient::INTERFACE:
980 {
981 uint8_t if_num = static_cast<uint8_t>(setup->wIndex & 0xFF);
982 item =
983 reinterpret_cast<DeviceClass*>(config_desc_.FindItemByInterfaceNumber(if_num));
984 break;
985 }
986 case Recipient::ENDPOINT:
987 {
988 uint8_t ep_addr = static_cast<uint8_t>(setup->wIndex & 0xFF);
989 item =
990 reinterpret_cast<DeviceClass*>(config_desc_.FindItemByEndpointAddress(ep_addr));
991 break;
992 }
993 default:
994 // 先不处理 DEVICE/OTHER 级别的 Vendor 请求
995 // Do not handle DEVICE/OTHER vendor requests for now
996 return ErrorCode::NOT_SUPPORT;
997 }
998
999 if (!item)
1000 {
1001 return ErrorCode::NOT_FOUND;
1002 }
1003
1005 auto ec = item->OnVendorRequest(in_isr, setup->bRequest, setup->wValue, setup->wLength,
1006 setup->wIndex, result);
1007 if (ec != ErrorCode::OK)
1008 {
1009 return ec;
1010 }
1011
1012 const bool HAS_READ_BUF = (result.read_data.size_ > 0);
1013 const bool HAS_WRITE_BUF = (result.write_data.size_ > 0);
1014
1015 if (HAS_READ_BUF && HAS_WRITE_BUF)
1016 {
1017 return ErrorCode::ARG_ERR;
1018 }
1019
1020 // Host -> Device(OUT)路径:从主机读数据进 read_data
1021 // Host->Device (OUT): read host data into read_data.
1022 if (HAS_READ_BUF)
1023 {
1024 if (setup->wLength == 0 || result.read_data.size_ < setup->wLength)
1025 {
1026 return ErrorCode::ARG_ERR;
1027 }
1028
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;
1034
1035 DevReadEP0Data(result.read_data, endpoint_.in0->MaxTransferSize());
1036 return ErrorCode::OK;
1037 }
1038
1039 // Device -> Host(IN)路径:从 write_data 发数据给主机
1040 // Device->Host (IN): send write_data to host.
1041 if (HAS_WRITE_BUF)
1042 {
1043 if (setup->wLength == 0)
1044 {
1045 return ErrorCode::ARG_ERR;
1046 }
1047
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;
1053
1054 DevWriteEP0Data(result.write_data, endpoint_.in0->MaxTransferSize(), setup->wLength);
1055 return ErrorCode::OK;
1056 }
1057
1058 // 无数据阶段,只需要 ZLP 的情况
1059 // No data stage; ZLP only.
1060 if (result.read_zlp)
1061 {
1062 ReadZLP();
1063 return ErrorCode::OK;
1064 }
1065 if (result.write_zlp)
1066 {
1067 WriteZLP();
1068 return ErrorCode::OK;
1069 }
1070
1071 return ErrorCode::OK;
1072}
1073
1074Speed DeviceCore::GetSpeed() const { return state_.speed; }
static Callback Create(FunType fun, ArgType arg)
创建回调对象并绑定回调函数与参数 / Create a callback instance with bound function and argument
Definition libxr_cb.hpp:167
常量原始数据封装类。 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
Definition libxr_mem.cpp:3
原始数据封装类。 A class for encapsulating raw data.
BOS 能力接口 / BOS capability interface.
Definition bos.hpp:56
ConstRawData GetBosDescriptor()
构建 BOS 描述符(BOS 头 + 能力块) Build BOS descriptor (header + blocks).
Definition bos.hpp:181
RawData GetData() const
获取配置描述符数据 / Get configuration descriptor data
Definition desc_cfg.cpp:381
ConfigDescriptorItem * FindItemByInterfaceNumber(size_t index) const
按接口号查找配置项 / Find item by interface number
Definition desc_cfg.cpp:393
bool CanOverrideDeviceDescriptor() const
是否允许覆盖设备描述符 / Whether device descriptor override is allowed
Definition desc_cfg.cpp:147
uint16_t GetDeviceStatus() const
设备状态(GET_STATUS)/ Device status (GET_STATUS)
Definition desc_cfg.cpp:387
ErrorCode OverrideDeviceDescriptor(DeviceDescriptor &descriptor)
覆盖设备描述符 / Override device descriptor
Definition desc_cfg.cpp:365
void BindEndpoints(bool in_isr)
绑定当前配置端点 / Bind endpoints for current configuration
Definition desc_cfg.cpp:275
ConfigDescriptorItem * FindItemByEndpointAddress(uint8_t addr) const
按端点地址查找配置项 / Find item by endpoint address
Definition desc_cfg.cpp:416
ErrorCode BuildConfigDescriptor()
构建当前配置描述符 / Build current configuration descriptor
Definition desc_cfg.cpp:320
void RebuildBosCache()
重建 BOS 缓存 / Rebuild BOS cache
Definition desc_cfg.cpp:178
size_t GetCurrentConfig() const
当前配置索引 / Current configuration index
Definition desc_cfg.cpp:385
ErrorCode SwitchConfig(size_t index, bool in_isr)
切换当前 configuration / Switch current configuration
Definition desc_cfg.cpp:260
void UnbindEndpoints(bool in_isr)
解绑当前配置端点 / Unbind endpoints for current configuration
Definition desc_cfg.cpp:299
virtual ErrorCode SetAltSetting(uint8_t itf, uint8_t alt)
可选:设置接口备用设置 / Optional: set interface alternate setting
Definition desc_cfg.hpp:135
ErrorCode GenerateString(Index index, uint16_t lang)
生成指定语言和索引的字符串描述符 Generate USB string descriptor for given language and string index
Definition desc_str.cpp:58
RawData GetData()
获取当前构建好的字符串描述符数据 Get the descriptor buffer
Definition desc_str.cpp:138
RawData GetLangIDData()
获取语言ID描述符内容 Get LangID descriptor data
Definition desc_str.cpp:145
Index
描述符字符串索引 / USB descriptor string index
Definition desc_str.hpp:25
USB 设备类接口基类 / USB device class interface base.
Definition dev_core.hpp:26
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)
Definition dev_core.hpp:108
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)
Definition dev_core.hpp:152
~DeviceClass() override
析构函数 / Destructor
Definition dev_core.cpp:26
size_t bos_cap_num_
BOS capability 数量 / BOS capability count.
Definition dev_core.hpp:170
BosCapability ** bos_caps_
BOS capability 指针表 / BOS capability pointer table.
Definition dev_core.hpp:168
DeviceClass(std::initializer_list< BosCapability * > bos_caps={})
构造:传入本类提供的 BOS capabilities(对象指针列表) Constructor: pass BOS capabilities provided by this class (pointe...
Definition dev_core.cpp:12
USB 设备协议栈核心:EP0 控制传输、描述符、配置、标准/类/厂商请求 USB device core: EP0 control transfer, descriptors,...
Definition dev_core.hpp:179
virtual void Deinit(bool in_isr)
反初始化 / Deinitialize
Definition dev_core.cpp:151
virtual void EnableRemoteWakeup()
启用远程唤醒 / Enable remote wakeup
Definition dev_core.hpp:270
ConfigDescriptor config_desc_
配置描述符管理器 / Configuration descriptor manager
Definition dev_core.hpp:329
ConstRawData data
数据阶段数据 / Data stage payload
Definition dev_core.hpp:362
@ SETUP
Setup stage / Setup stage.
Definition dev_core.hpp:190
@ STATUS_IN
IN status stage / IN status stage.
Definition dev_core.hpp:194
@ DATA_OUT
OUT data stage / OUT data stage.
Definition dev_core.hpp:191
@ STATUS_OUT
OUT status stage / OUT status stage.
Definition dev_core.hpp:192
@ DATA_IN
IN data stage / IN data stage.
Definition dev_core.hpp:193
@ ZLP
ZLP stage marker / ZLP stage marker.
Definition dev_core.hpp:195
@ UNKNOWN
未知 / Unknown
Definition dev_core.hpp:189
virtual void Init(bool in_isr)
初始化 / Initialize
Definition dev_core.cpp:129
DeviceDescriptor device_desc_
设备描述符 / Device descriptor
Definition dev_core.hpp:330
Speed GetSpeed() const
获取设备速度 / Get device speed
virtual void DisableRemoteWakeup()
禁用远程唤醒 / Disable remote wakeup
Definition dev_core.hpp:275
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
Definition dev_core.cpp:36
Speed speed
设备速度 / Device speed
Definition dev_core.hpp:346
DescriptorStrings strings_
字符串描述符管理器 / String descriptor manager
Definition dev_core.hpp:331
void OnSetupPacket(bool in_isr, const SetupPacket *setup)
处理 Setup 包 / Handle Setup packet
Definition dev_core.cpp:349
virtual ErrorCode SetAddress(uint8_t address, Context state)=0
设置设备地址(由子类实现) Set device address (implemented by derived class).
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:75
RawData GetData()
获取设备描述符的原始数据指针及长度 Get the raw device descriptor data pointer and length
Definition desc_dev.cpp:24
USB 端点基类 / USB Endpoint base class.
Definition ep.hpp:23
virtual ErrorCode Stall()=0
置 STALL / Stall endpoint
@ IN
输入方向 / IN direction
@ OUT
输出方向 / OUT direction
virtual ErrorCode ClearStall()=0
清除 STALL / Clear stall
@ CONTROL
控制端点 / Control
@ STALLED
停止/挂起 / Stalled
State GetState() const
获取端点状态 / Get endpoint state
Definition ep.hpp:207
USB端点池类 / USB endpoint pool class.
Definition ep_pool.hpp:23
Vendor 请求处理结果(EP0 控制传输) Vendor request handling result for EP0 control transfers.
Definition bos.hpp:44
控制请求(Class/Vendor)处理结果 / Control request (Class/Vendor) handling result
Definition dev_core.hpp:51
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:57
uint16_t wIndex
对象索引,如接口号或端点号 / Index (e.g., interface or endpoint)
Definition core.hpp:63
uint16_t wLength
数据阶段长度 / Number of bytes in data stage
Definition core.hpp:64
uint16_t wValue
参数字段,含请求相关值 / Value field (e.g., descriptor type/index)
Definition core.hpp:62
uint8_t bRequest
请求码 / Request code (e.g., GET_DESCRIPTOR)
Definition core.hpp:60