MiSimon在efi应用程序发送TCP或UDP数据包中提供的示例代码显示了如何发送和接收单个数据包。我已经成功地发送了多个数据包,但我在接收方面遇到了困难。
UEFI UDP协议EFI_UDP4_PROTOCOL.Receive()
功能的文档说明它是
将异步接收请求放入接收队列。
根据EDK2源代码,可以推断这类似于NetMapInsertTail()
将新令牌放在RxTokens列表上。根据同一消息来源,当数据报被传递时,该令牌似乎会被NetMapRemoveHead()
删除。然而,根据经验,在我成功接收到一个数据包、从回调返回并发出RecycleSignal
信号后,我对Receive()
的下一次调用失败,并出现EFI_ACCESS_DENIED,在本文中描述为:
具有相同令牌的接收完成令牌。事件已在接收队列中。
接口不提供任何API来确定";接收队列";,因此,要调查"删除"操作是否没有达到我认为的效果,或者是否被重新排队等,并不容易。
所以我问题的关键是:如何安排从同一个UDP端口接收多个数据报?
- 接收队列上的令牌是否应该在不多次调用
Receive()
的情况下多次重复使用?(如果是的话,需要做些什么来为重用做准备?( - 还是需要为每个传入的数据包重新创建?(如果是这样的话,那么他们何时以及如何被释放?(
令牌中的事件只调用一次,规范中说(规范2.9,第30.1.2章接收(:
"为事件提供适当的通知功能和上下文将使用户能够接收通知和接收状态。该通知功能保证不会被重新输入">
您需要为每个令牌分配一个新事件。如果你想同时监听多个数据报,你可以为每个事件使用唯一的上下文,但使用相同的通知函数。
对于每个代币,您必须:
创建事件和令牌->呼叫接收->处理数据报或错误->发出再循环事件的信号->释放令牌事件