UEFI UDP 接收令牌
UEFI UDP Receive token
MiSimon in 提供的示例代码显示了如何发送和接收单个数据包。我已经成功地发送了多个数据包,但是我在接收端遇到了困难。
UEFI UDP 协议 EFI_UDP4_PROTOCOL.Receive()
函数的 documentation 表示它
Places an asynchronous receive request into the receiving queue.
根据 EDK2 源代码,人们可能会推断这会执行类似于 NetMapInsertTail()
将新令牌放置在 RxTokens 列表中的操作。根据同一消息来源,似乎在传递数据报时,此标记已用 NetMapRemoveHead()
删除。然而,根据经验,在我从回调中成功接收到一个数据包 return 并向 RecycleSignal
发出信号后,我对 Receive()
的下一次调用失败并显示 EFI_ACCESS_DENIED,在此上下文中描述为:
A receive completion token with the same Token.Event was already in the receive queue.
该接口没有提供任何 API 来确定“接收队列”中的内容,因此很难调查 'remove' 操作是否没有按照我的想法进行是,还是重新排队等
所以我的问题的关键是:如何安排从同一个 UDP 端口接收多个数据报?
- 接收队列中的令牌是否应该可以多次重复使用而无需多次调用
Receive()
? (如果是这样,必须做些什么来准备重用?)
- 或者它是否需要为每个传入数据包重新创建? (如果是,那么他们何时以及如何获释?)
令牌中的事件只被调用一次,规范说(Spec 2.9,章节 30.1.2 接收):
"Providing a proper notification function and context for the event
will enable the user to receive the notification and receiving status.
That notification function is guaranteed to not be re-entered."
您需要为每个令牌分配一个新事件。如果您想同时监听多个数据报,您可以为每个事件使用唯一的上下文,但使用相同的通知功能。
对于每个令牌,您必须:
创建事件和令牌 -> 调用接收 -> 处理数据报或错误 -> 发出回收事件信号 -> 释放令牌事件
MiSimon in
UEFI UDP 协议 EFI_UDP4_PROTOCOL.Receive()
函数的 documentation 表示它
Places an asynchronous receive request into the receiving queue.
根据 EDK2 源代码,人们可能会推断这会执行类似于 NetMapInsertTail()
将新令牌放置在 RxTokens 列表中的操作。根据同一消息来源,似乎在传递数据报时,此标记已用 NetMapRemoveHead()
删除。然而,根据经验,在我从回调中成功接收到一个数据包 return 并向 RecycleSignal
发出信号后,我对 Receive()
的下一次调用失败并显示 EFI_ACCESS_DENIED,在此上下文中描述为:
A receive completion token with the same Token.Event was already in the receive queue.
该接口没有提供任何 API 来确定“接收队列”中的内容,因此很难调查 'remove' 操作是否没有按照我的想法进行是,还是重新排队等
所以我的问题的关键是:如何安排从同一个 UDP 端口接收多个数据报?
- 接收队列中的令牌是否应该可以多次重复使用而无需多次调用
Receive()
? (如果是这样,必须做些什么来准备重用?) - 或者它是否需要为每个传入数据包重新创建? (如果是,那么他们何时以及如何获释?)
令牌中的事件只被调用一次,规范说(Spec 2.9,章节 30.1.2 接收):
"Providing a proper notification function and context for the event will enable the user to receive the notification and receiving status. That notification function is guaranteed to not be re-entered."
您需要为每个令牌分配一个新事件。如果您想同时监听多个数据报,您可以为每个事件使用唯一的上下文,但使用相同的通知功能。
对于每个令牌,您必须:
创建事件和令牌 -> 调用接收 -> 处理数据报或错误 -> 发出回收事件信号 -> 释放令牌事件