这部分是4.5 Command error handling讲的是HCI Command 发生错误时Controller 应该通过什么事件返回错误、错误码放在哪里、命令是否还会继续执行、哪些返回参数仍然有效。前面 4.4 讲的是命令流控Host 能不能继续发 HCI Command Command Complete / Command Status 怎么控制命令发送数量这一节 4.5 讲的是命令出错时错误怎么返回 命令还执不执行 返回哪个事件 Status 怎么理解 哪些参数还有效1. 这部分整体表达了哪些知识这一节主要分成两部分4.5.1 Generic error handling 通用命令错误处理规则 4.5.2 Error handling specific to a command 某个具体命令自己的错误处理规则可以理解为4.5.1 是所有 HCI Command 通用的错误处理原则。 4.5.2 是某些命令在 Section 7 里会有额外的专用错误处理表。2. 4.5.1 Generic error handling 想表达什么这一节的核心是除非具体命令描述中另有说明否则命令参数中只要有任何错误这个命令就不会开始执行只会返回错误码。原文第一句非常关键Unless explicitly stated otherwise in the description of a command, any error in any parameter means that the command will not begin to execute; it will only return an error code.意思是除非某个命令自己的说明中特别说了例外 否则只要命令参数有错误 Controller 就不会开始执行这个命令 而是只返回错误码。例如 Host 发了一个命令参数非法Advertising_Interval_Min Advertising_Interval_Max Scan_Window Scan_Interval Connection_Handle 无效 参数取值超出范围 当前状态下不允许执行通常结果就是Controller 不执行命令 Controller 返回错误码3. 如果多个错误码都适用Controller 可以选一个返回原文说If more than one error code is applicable, the implementation shall choose one of them.意思是如果同一个命令同时触发多个错误条件Controller 实现可以选择其中一个错误码返回。例如某个命令同时存在参数 A 非法 参数 B 也非法 当前状态也不允许执行那么 Controller 不一定要把所有错误都告诉 Host。它可以只返回其中一个错误码。这点在调试时很重要。不要认为Controller 返回了一个错误码就说明只有这一个问题。更准确地说返回的错误码只是 Controller 选择报告的一个错误原因。4. Command Complete 类型命令发生错误时错误放在 Status 参数中原文说If an error occurs for a command for which an HCI_Command_Complete event is returned, the error shall be reported in the Status parameter.意思是如果某个命令正常情况下是通过 HCI_Command_Complete event 返回结果的那么出错时错误码放在 Command Complete 事件的 Status 参数中。例如Host → HCI_LE_Set_Advertising_Data Controller → HCI_Command_Complete Status 非 0 错误码这里的重点是Command Complete 事件仍然会返回 但是 Status 不是 Success而是错误码HCI 中通常Status 0x00 表示 Success Status ! 0x00 表示错误5. Command Status completion event 类型命令发生错误时有两种情况有些命令不是直接 Command Complete而是先返回 HCI_Command_Status 后续再返回 completion event例如 BLE 建立连接Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Controller → HCI_LE_Connection_Complete这类命令发生错误时规范分成两种情况。5.1 错误在命令开始执行前就被发现原文说If the error is one which means the command will not begin to execute, the error shall be returned as a non-zero Status parameter in the HCI_Command_Status event and no completion event will be returned.意思是如果这个错误导致命令根本不会开始执行那么 Controller 会在 HCI_Command_Status event 中返回非 0 Status并且不会再返回后续 completion event。例如Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Status Command Disallowed这表示命令没有开始执行 后面不会再有 LE Connection Complete event所以这类命令要特别注意Command Status 错误 ↓ 命令结束不会有后续 completion event5.2 命令已经开始执行后才发现错误原文说If the error is not detected until after the HCI_Command_Status event has been generated, the HCI_Command_Status event shall have the Status parameter set to zero and the error shall be returned in the Status parameter of the completion event.意思是如果错误是在 Command Status 已经返回之后才发现的那么 Command Status 的 Status 应为 0真正错误要放在后续 completion event 的 Status 中。流程就是Host → HCI Command Controller → HCI_Command_Status Status 0x00 Success ↓ 命令已经开始执行进入 pending ↓ 后续过程失败 ↓ Controller → completion event Status 非 0 错误码以 BLE 连接为例Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Status 0x00这只表示Controller 接受了建立连接命令并开始执行连接过程。但连接过程可能后面失败例如对端没有响应 连接超时 空口过程失败最终可能返回HCI_LE_Connection_Complete event Status 非 0 错误码所以再次强调Command Status Success 不等于最终操作成功。6. Controller 不支持某个命令时返回 Unknown HCI Command原文说If the Controller does not support an issued command, it shall return the error code Unknown HCI command (0x01)意思是如果 Controller 不支持 Host 发出的某个 HCI Command应返回错误码 Unknown HCI Command错误码是 0x01。这个错误码可能出现在HCI_Command_Complete event 的 Status 参数中或者HCI_Command_Status event 的 Status 参数中具体用哪个事件是 vendor-specific也就是由厂商实现决定。例如 Host 使用了一个新版本蓝牙命令但 Controller 固件不支持Host → HCI_LE_Set_Extended_Advertising_Parameters Controller → Status Unknown HCI Command (0x01)这说明Controller 根本不认识这个 HCI Command它和Unsupported Feature or Parameter Value不完全一样。7. Unknown HCI Command 和 Unsupported Feature 的区别这里顺便要区分两个常见错误。7.1 Unknown HCI Command0x01含义是Controller 不认识这个命令 或者不支持这个命令 opcode例如Controller 是旧版本不支持某个新 HCI Command。7.2 Unsupported Feature or Parameter Value0x11含义通常是Controller 认识这个命令 但是某个功能或参数值不支持例如命令本身支持 但某个 PHY 不支持 某个 advertising type 不支持 某个参数组合不支持 某个连接类型不支持可以简单理解为0x01命令都不认识 0x11命令认识但你要的功能/参数不支持8. Command Complete 出错时Return Parameters 可能不完整原文说If an error occurs for a command for which an HCI_Command_Complete event is returned, the Return Parameters field may only contain some of the return parameters specified for the command.意思是如果一个通过 Command Complete 返回的命令发生错误那么 Return Parameters 字段可能只包含该命令规定返回参数中的一部分。但是有一个参数必须返回Status 参数必须返回因为 Status 是解释错误原因的核心字段。也就是说出错时不要假设所有返回参数都有效或都存在。Host 处理 Command Complete 时应该先看Status如果 Status 不是 Success那么后面的返回参数可能缺失也可能无效不能随便使用。9. Status 参数必须是第一个返回参数原文说The Status parameter, which explains the error reason and which is the first return parameter, shall always be returned.意思是Status 参数解释错误原因并且是第一个返回参数它必须始终返回。所以 HCI 命令返回时常见结构是Return Parameters: Status 其他返回参数...Host 解析时应该优先判断Status 0x00如果不是 0再考虑哪些参数仍然可用。10. 如果 Status 后面紧跟 Handle 或 BD_ADDR这个参数也必须返回原文说If there is a Handle parameter or a BD_ADDR parameter right after the Status parameter, this parameter shall also be returned so that the Host can identify the instance of a command the HCI_Command_Complete event belongs to.意思是如果 Status 参数后面紧跟的是 Handle 或 BD_ADDR 参数那么出错时这个参数也必须返回。原因是 Host 需要知道这个错误属于哪个连接 这个错误属于哪个远端设备 这个返回对应哪一次命令例如某些命令是针对某个连接的Connection_Handle有些命令是针对某个设备地址的BD_ADDR如果出错时连这些标识都不返回Host 就不知道错误对应的是哪个实例。所以规范要求Status 后面紧跟的 Handle / BD_ADDR 必须返回。并且它的值应与对应 command parameter 中的值完全相同。11. 其他返回参数是否返回是 implementation-specific原文说It is implementation specific whether more parameters will be returned in case of an error; if they are not, the event will be shorter than if they were.意思是发生错误时除了必须返回的参数之外是否返回更多参数由具体实现决定。也就是说不同 Controller 可能有不同表现Controller A出错时只返回 Status Handle Controller B出错时仍然返回完整参数所以 Host 侧不能强依赖错误情况下的所有返回参数。这在解析 HCI log 时也很重要错误返回事件可能比成功返回事件更短。12. Table 4.1 想表达什么Table 4.1 的标题是Valid parameters for command completion events reporting an error意思是当命令特定 completion event 报告错误时哪些参数仍然是有效的。有些命令的完成事件不是HCI_Command_Complete而是命令自己的 completion event。例如Connection_Complete LE_Connection_Complete LE_CIS_Established LE_Create_BIG_Complete这些事件里也有 Status 参数。当 Status 表示错误时事件里不是所有参数都一定有效。Table 4.1 就告诉你在错误情况下除了 Status 之外哪些参数仍然有效。13. Table 4.1 中 none 是什么意思表中有些事件的 Valid parameters 是none意思是当该事件报告错误时除了 Status 之外没有其他参数被认为是有效参数。例如截图里LE_Connection_Complete none LE_Enhanced_Connection_Complete none LE_Periodic_Advertising_Sync_Established none这表示这些事件发生错误时Host 不能依赖其他参数的有效性。例如LE_Connection_Complete如果 Status 非 0连接没有建立成功那么事件中的很多连接相关参数自然没有意义。14. Table 4.1 中 BD_ADDR、Connection_Handle、BIG_Handle 是什么意思表里有些事件的 Valid parameters 不是 none而是BD_ADDR Connection_Handle BIG_Handle意思是即使事件报告错误这些参数仍然有效。例如Connection_Complete BD_ADDR Synchronous_Connection_Complete BD_ADDR LE_CIS_Established Connection_Handle LE_Create_BIG_Complete BIG_Handle含义是虽然过程失败了 但这个参数仍然可以用来识别失败对应的是哪个设备、哪个连接或哪个 BIG。15. SubEvent_Code 不作为参数处理并且始终有效原文说For the purposes of this section, the Subevent_Code parameter of the HCI_LE_Meta event is not treated as a parameter and is always valid.意思是在这一节的语境下HCI_LE_Meta event 里的 Subevent_Code 不当作普通参数处理并且它总是有效的。LE 相关事件很多都是通过HCI_LE_Meta event承载的。里面会有Subevent_Code用于区分具体是哪种 LE 事件例如LE Connection Complete LE Advertising Report LE Enhanced Connection Complete规范强调它始终有效是因为 Host 必须先通过它知道这到底是哪一种 LE 子事件。否则连事件类型都无法判断。16. HCI_Read_BD_ADDR 的特殊说明截图底部 Note 说The BD_ADDR return parameter of the command HCI_Read_BD_ADDR is not used to identify to which instance of the HCI_Read_BD_ADDR command the HCI_Command_Complete event belongs. It is optional for the Controller to return this parameter in case of an error.意思是HCI_Read_BD_ADDR 命令返回的 BD_ADDR不是用来识别这次 Command Complete 属于哪一次 HCI_Read_BD_ADDR 命令的。发生错误时Controller 可以选择不返回 BD_ADDR。原因是HCI_Read_BD_ADDR 本身是读取本地设备地址 它不是针对某个远端 BD_ADDR 发出的命令。所以它返回的 BD_ADDR 是结果数据不是“命令实例标识”。因此错误时可不返回。17. 4.5.2 Error handling specific to a command 想表达什么这一节讲的是除了通用错误处理规则之外Section 7 中某些具体 HCI Command 的描述还会包含该命令专门的错误条件和错误处理表。也就是说4.5.1 是通用规则。 Section 7 里某些命令还会有自己的专用错误规则。如果某个命令有专用错误处理表应结合它一起看。例如你看一个具体命令时除了看Command Parameters Return Parameters Generated Events还要看Error Codes Error Conditions18. Table 4.2 是什么Table 4.2 标题是Types of error handling意思是错误处理类型它定义了 Section 7 中命令专用错误处理表里会用到的几种错误处理强度。表里有四种 TypeMC M RC R它们用来说明Controller 是否必须拒绝命令 是否必须返回指定错误码19. MC 类型是什么意思Table 4.2 中 MC 的 Error Condition 是The Controller shall return the specified error code and not execute the command.意思是Controller 必须返回指定错误码并且不得执行命令。表中Command Rejected with Error CodeMandatory Return Specified Error CodeMandatory也就是说MC 是最强要求必须拒绝命令 必须返回指定错误码 不能执行命令例如某个命令表写了一个错误条件是 MC那么 Controller 遇到这个条件时没有太多自由度必须按规范返回指定错误码。20. M 类型是什么意思M 的 Error Condition 是The Controller shall return an error code and not execute the command. The error code returned should be the one specified.意思是Controller 必须返回错误码并且不得执行命令推荐返回规范指定的那个错误码。表中Command Rejected with Error CodeMandatory Return Specified Error CodeRecommended也就是说必须拒绝命令 必须返回某个错误码 但返回指定错误码只是推荐不是强制它比 MC 稍弱。21. RC 类型是什么意思RC 的 Error Condition 是The Controller should return an error code and not execute the command. If it does return an error code, it shall be the one specified.意思是Controller 应该返回错误码并且不执行命令如果它返回错误码那么必须返回指定错误码。表中Command Rejected with Error CodeRecommended Return Specified Error CodeMandatory也就是说推荐拒绝命令 如果拒绝并返回错误码那么错误码必须是指定错误码这里的“拒绝命令”不是强制但一旦拒绝并返回错误码错误码必须符合规范指定值。22. R 类型是什么意思R 的 Error Condition 是The Controller should return an error code and not execute the command. If it does return an error code, it should be the one specified.意思是Controller 推荐返回错误码并且不执行命令如果返回错误码也推荐返回指定错误码。表中Command Rejected with Error CodeRecommended Return Specified Error CodeRecommended这是四种里约束最弱的一类。可以理解为推荐拒绝 推荐返回指定错误码 但不是强制23. MC / M / RC / R 对比可以整理成这样Type是否要拒绝命令是否要返回指定错误码强度MC必须必须最强M必须推荐强RC推荐如果返回错误码则必须是指定错误码中等R推荐推荐最弱简化理解MC必须拒绝必须指定错误码 M必须拒绝建议指定错误码 RC建议拒绝如果报错必须指定错误码 R建议拒绝建议指定错误码24. 什么时候判断 error condition 成立截图最后一段说An error situation occurs if any of the conditions in the table apply at the moment the Controller starts to process the command parameters, and before the Controller starts to execute the command.意思是当 Controller 开始处理命令参数、但还没有开始执行命令时如果错误条件表里的某个条件成立就认为发生了错误情况。这里的时间点很重要Controller 开始检查命令参数 ↓ 如果发现错误条件成立 ↓ 返回错误不执行命令 ↓ 如果没有错误 ↓ 才开始执行命令也就是说这些错误处理表主要针对命令开始执行之前就能检查出来的错误25. 如果状态在发送命令和 Controller 检查命令之间发生变化呢最后一句举了一个例子For example, an error condition because a conflicting mode was enabled would not apply if that mode is disabled between the Host sending the command to the HCI transport and the Controller starting to check the command parameters.意思是某个错误条件是否成立要看 Controller 开始检查命令参数那一刻而不是 Host 发送命令那一刻。例如Host 发送命令时Controller 处于某个冲突模式 但是在 Controller 实际开始检查这个命令参数之前这个冲突模式已经被关闭那么这个错误条件就不算成立。这个规则体现的是命令错误判断以 Controller 实际处理命令参数的时刻为准。不是以 Host 发出命令的时刻为准。26. 对 BLE 学习的实际意义对 BLE 来说这部分特别有用因为你后面看具体命令时经常会看到各种错误码。例如HCI_LE_Set_Advertising_Enable HCI_LE_Set_Extended_Advertising_Enable HCI_LE_Create_Connection HCI_LE_Set_Scan_Enable HCI_LE_Connection_Update这些命令可能返回Command Disallowed Invalid HCI Command Parameters Unsupported Feature or Parameter Value Unknown HCI Command Memory Capacity Exceeded Connection Timeout理解 4.5 后就能知道错误是在 Command Complete 里返回还是 Command Status 里返回 如果 Command Status 返回错误后面还会不会有 completion event 如果 Command Status 成功后续 completion event 还可能失败吗 错误时哪些返回参数还能相信27. 最关键的理解先看 Status再看其他参数无论是HCI_Command_Complete HCI_Command_Status 某个 command-specific completion event只要事件里有 Status就应该先看 Status。Status 0x00 才能按成功路径理解后面的参数 Status ! 0x00 表示错误 后面的参数可能不完整或无效 只有规范明确说有效的参数才能可靠使用这是解析 HCI log 时非常重要的习惯。28. 这部分关键信息总结28.1 参数错误通常导致命令不会开始执行除非具体命令另有说明否则任何参数错误都会让命令不执行只返回错误码。28.2 多个错误同时存在时Controller 可以选择返回其中一个不要认为返回的错误码一定覆盖所有问题。28.3 Command Complete 类型命令错误放在 Command Complete 的 Status 中流程是Host → Command Controller → HCI_Command_Complete Status 非 028.4 Command Status completion event 类型命令要区分错误发生时机如果命令未开始执行HCI_Command_Status Status 非 0 后续没有 completion event如果命令已开始执行后续失败HCI_Command_Status Status 0x00 completion event Status 非 028.5 不支持的命令返回 Unknown HCI Command0x01如果 Controller 不支持某个命令应返回Unknown HCI Command 0x0128.6 出错时 Return Parameters 可能不完整Status 一定返回。如果 Status 后面紧跟 Handle 或 BD_ADDR这个参数也应返回。其他参数是否返回取决于实现。28.7 Table 4.1 告诉你错误 completion event 中哪些参数仍然有效none表示除了 Status 之外没有其他参数可依赖。28.8 Table 4.2 定义命令专用错误处理类型MC必须拒绝必须返回指定错误码 M必须拒绝推荐返回指定错误码 RC推荐拒绝如果返回错误码必须是指定错误码 R推荐拒绝推荐返回指定错误码28.9 错误条件是否成立以 Controller 开始检查命令参数的时刻为准不是以 Host 发出命令的那一刻为准。29. 最核心的一句话这一节可以总结为Command error handling 的核心是规定 HCI Command 出错时错误码放在哪里、命令是否还会执行、后续 completion event 是否还会生成以及错误情况下哪些返回参数仍然有效Host 解析 HCI 事件时必须先看 StatusStatus 非 0 时不能默认后续所有参数都有效。对 BLE 学习最重要的是Command Status 非 0命令没开始后面通常没有 completion event。 Command Status 0命令开始了但最终结果还要看后续 completion event。 Command Complete / completion event 里的 Status 非 0表示命令或过程失败后面的参数要谨慎使用。
HCI 功能规范【4.5. Command error handling】
这部分是4.5 Command error handling讲的是HCI Command 发生错误时Controller 应该通过什么事件返回错误、错误码放在哪里、命令是否还会继续执行、哪些返回参数仍然有效。前面 4.4 讲的是命令流控Host 能不能继续发 HCI Command Command Complete / Command Status 怎么控制命令发送数量这一节 4.5 讲的是命令出错时错误怎么返回 命令还执不执行 返回哪个事件 Status 怎么理解 哪些参数还有效1. 这部分整体表达了哪些知识这一节主要分成两部分4.5.1 Generic error handling 通用命令错误处理规则 4.5.2 Error handling specific to a command 某个具体命令自己的错误处理规则可以理解为4.5.1 是所有 HCI Command 通用的错误处理原则。 4.5.2 是某些命令在 Section 7 里会有额外的专用错误处理表。2. 4.5.1 Generic error handling 想表达什么这一节的核心是除非具体命令描述中另有说明否则命令参数中只要有任何错误这个命令就不会开始执行只会返回错误码。原文第一句非常关键Unless explicitly stated otherwise in the description of a command, any error in any parameter means that the command will not begin to execute; it will only return an error code.意思是除非某个命令自己的说明中特别说了例外 否则只要命令参数有错误 Controller 就不会开始执行这个命令 而是只返回错误码。例如 Host 发了一个命令参数非法Advertising_Interval_Min Advertising_Interval_Max Scan_Window Scan_Interval Connection_Handle 无效 参数取值超出范围 当前状态下不允许执行通常结果就是Controller 不执行命令 Controller 返回错误码3. 如果多个错误码都适用Controller 可以选一个返回原文说If more than one error code is applicable, the implementation shall choose one of them.意思是如果同一个命令同时触发多个错误条件Controller 实现可以选择其中一个错误码返回。例如某个命令同时存在参数 A 非法 参数 B 也非法 当前状态也不允许执行那么 Controller 不一定要把所有错误都告诉 Host。它可以只返回其中一个错误码。这点在调试时很重要。不要认为Controller 返回了一个错误码就说明只有这一个问题。更准确地说返回的错误码只是 Controller 选择报告的一个错误原因。4. Command Complete 类型命令发生错误时错误放在 Status 参数中原文说If an error occurs for a command for which an HCI_Command_Complete event is returned, the error shall be reported in the Status parameter.意思是如果某个命令正常情况下是通过 HCI_Command_Complete event 返回结果的那么出错时错误码放在 Command Complete 事件的 Status 参数中。例如Host → HCI_LE_Set_Advertising_Data Controller → HCI_Command_Complete Status 非 0 错误码这里的重点是Command Complete 事件仍然会返回 但是 Status 不是 Success而是错误码HCI 中通常Status 0x00 表示 Success Status ! 0x00 表示错误5. Command Status completion event 类型命令发生错误时有两种情况有些命令不是直接 Command Complete而是先返回 HCI_Command_Status 后续再返回 completion event例如 BLE 建立连接Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Controller → HCI_LE_Connection_Complete这类命令发生错误时规范分成两种情况。5.1 错误在命令开始执行前就被发现原文说If the error is one which means the command will not begin to execute, the error shall be returned as a non-zero Status parameter in the HCI_Command_Status event and no completion event will be returned.意思是如果这个错误导致命令根本不会开始执行那么 Controller 会在 HCI_Command_Status event 中返回非 0 Status并且不会再返回后续 completion event。例如Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Status Command Disallowed这表示命令没有开始执行 后面不会再有 LE Connection Complete event所以这类命令要特别注意Command Status 错误 ↓ 命令结束不会有后续 completion event5.2 命令已经开始执行后才发现错误原文说If the error is not detected until after the HCI_Command_Status event has been generated, the HCI_Command_Status event shall have the Status parameter set to zero and the error shall be returned in the Status parameter of the completion event.意思是如果错误是在 Command Status 已经返回之后才发现的那么 Command Status 的 Status 应为 0真正错误要放在后续 completion event 的 Status 中。流程就是Host → HCI Command Controller → HCI_Command_Status Status 0x00 Success ↓ 命令已经开始执行进入 pending ↓ 后续过程失败 ↓ Controller → completion event Status 非 0 错误码以 BLE 连接为例Host → HCI_LE_Create_Connection Controller → HCI_Command_Status Status 0x00这只表示Controller 接受了建立连接命令并开始执行连接过程。但连接过程可能后面失败例如对端没有响应 连接超时 空口过程失败最终可能返回HCI_LE_Connection_Complete event Status 非 0 错误码所以再次强调Command Status Success 不等于最终操作成功。6. Controller 不支持某个命令时返回 Unknown HCI Command原文说If the Controller does not support an issued command, it shall return the error code Unknown HCI command (0x01)意思是如果 Controller 不支持 Host 发出的某个 HCI Command应返回错误码 Unknown HCI Command错误码是 0x01。这个错误码可能出现在HCI_Command_Complete event 的 Status 参数中或者HCI_Command_Status event 的 Status 参数中具体用哪个事件是 vendor-specific也就是由厂商实现决定。例如 Host 使用了一个新版本蓝牙命令但 Controller 固件不支持Host → HCI_LE_Set_Extended_Advertising_Parameters Controller → Status Unknown HCI Command (0x01)这说明Controller 根本不认识这个 HCI Command它和Unsupported Feature or Parameter Value不完全一样。7. Unknown HCI Command 和 Unsupported Feature 的区别这里顺便要区分两个常见错误。7.1 Unknown HCI Command0x01含义是Controller 不认识这个命令 或者不支持这个命令 opcode例如Controller 是旧版本不支持某个新 HCI Command。7.2 Unsupported Feature or Parameter Value0x11含义通常是Controller 认识这个命令 但是某个功能或参数值不支持例如命令本身支持 但某个 PHY 不支持 某个 advertising type 不支持 某个参数组合不支持 某个连接类型不支持可以简单理解为0x01命令都不认识 0x11命令认识但你要的功能/参数不支持8. Command Complete 出错时Return Parameters 可能不完整原文说If an error occurs for a command for which an HCI_Command_Complete event is returned, the Return Parameters field may only contain some of the return parameters specified for the command.意思是如果一个通过 Command Complete 返回的命令发生错误那么 Return Parameters 字段可能只包含该命令规定返回参数中的一部分。但是有一个参数必须返回Status 参数必须返回因为 Status 是解释错误原因的核心字段。也就是说出错时不要假设所有返回参数都有效或都存在。Host 处理 Command Complete 时应该先看Status如果 Status 不是 Success那么后面的返回参数可能缺失也可能无效不能随便使用。9. Status 参数必须是第一个返回参数原文说The Status parameter, which explains the error reason and which is the first return parameter, shall always be returned.意思是Status 参数解释错误原因并且是第一个返回参数它必须始终返回。所以 HCI 命令返回时常见结构是Return Parameters: Status 其他返回参数...Host 解析时应该优先判断Status 0x00如果不是 0再考虑哪些参数仍然可用。10. 如果 Status 后面紧跟 Handle 或 BD_ADDR这个参数也必须返回原文说If there is a Handle parameter or a BD_ADDR parameter right after the Status parameter, this parameter shall also be returned so that the Host can identify the instance of a command the HCI_Command_Complete event belongs to.意思是如果 Status 参数后面紧跟的是 Handle 或 BD_ADDR 参数那么出错时这个参数也必须返回。原因是 Host 需要知道这个错误属于哪个连接 这个错误属于哪个远端设备 这个返回对应哪一次命令例如某些命令是针对某个连接的Connection_Handle有些命令是针对某个设备地址的BD_ADDR如果出错时连这些标识都不返回Host 就不知道错误对应的是哪个实例。所以规范要求Status 后面紧跟的 Handle / BD_ADDR 必须返回。并且它的值应与对应 command parameter 中的值完全相同。11. 其他返回参数是否返回是 implementation-specific原文说It is implementation specific whether more parameters will be returned in case of an error; if they are not, the event will be shorter than if they were.意思是发生错误时除了必须返回的参数之外是否返回更多参数由具体实现决定。也就是说不同 Controller 可能有不同表现Controller A出错时只返回 Status Handle Controller B出错时仍然返回完整参数所以 Host 侧不能强依赖错误情况下的所有返回参数。这在解析 HCI log 时也很重要错误返回事件可能比成功返回事件更短。12. Table 4.1 想表达什么Table 4.1 的标题是Valid parameters for command completion events reporting an error意思是当命令特定 completion event 报告错误时哪些参数仍然是有效的。有些命令的完成事件不是HCI_Command_Complete而是命令自己的 completion event。例如Connection_Complete LE_Connection_Complete LE_CIS_Established LE_Create_BIG_Complete这些事件里也有 Status 参数。当 Status 表示错误时事件里不是所有参数都一定有效。Table 4.1 就告诉你在错误情况下除了 Status 之外哪些参数仍然有效。13. Table 4.1 中 none 是什么意思表中有些事件的 Valid parameters 是none意思是当该事件报告错误时除了 Status 之外没有其他参数被认为是有效参数。例如截图里LE_Connection_Complete none LE_Enhanced_Connection_Complete none LE_Periodic_Advertising_Sync_Established none这表示这些事件发生错误时Host 不能依赖其他参数的有效性。例如LE_Connection_Complete如果 Status 非 0连接没有建立成功那么事件中的很多连接相关参数自然没有意义。14. Table 4.1 中 BD_ADDR、Connection_Handle、BIG_Handle 是什么意思表里有些事件的 Valid parameters 不是 none而是BD_ADDR Connection_Handle BIG_Handle意思是即使事件报告错误这些参数仍然有效。例如Connection_Complete BD_ADDR Synchronous_Connection_Complete BD_ADDR LE_CIS_Established Connection_Handle LE_Create_BIG_Complete BIG_Handle含义是虽然过程失败了 但这个参数仍然可以用来识别失败对应的是哪个设备、哪个连接或哪个 BIG。15. SubEvent_Code 不作为参数处理并且始终有效原文说For the purposes of this section, the Subevent_Code parameter of the HCI_LE_Meta event is not treated as a parameter and is always valid.意思是在这一节的语境下HCI_LE_Meta event 里的 Subevent_Code 不当作普通参数处理并且它总是有效的。LE 相关事件很多都是通过HCI_LE_Meta event承载的。里面会有Subevent_Code用于区分具体是哪种 LE 事件例如LE Connection Complete LE Advertising Report LE Enhanced Connection Complete规范强调它始终有效是因为 Host 必须先通过它知道这到底是哪一种 LE 子事件。否则连事件类型都无法判断。16. HCI_Read_BD_ADDR 的特殊说明截图底部 Note 说The BD_ADDR return parameter of the command HCI_Read_BD_ADDR is not used to identify to which instance of the HCI_Read_BD_ADDR command the HCI_Command_Complete event belongs. It is optional for the Controller to return this parameter in case of an error.意思是HCI_Read_BD_ADDR 命令返回的 BD_ADDR不是用来识别这次 Command Complete 属于哪一次 HCI_Read_BD_ADDR 命令的。发生错误时Controller 可以选择不返回 BD_ADDR。原因是HCI_Read_BD_ADDR 本身是读取本地设备地址 它不是针对某个远端 BD_ADDR 发出的命令。所以它返回的 BD_ADDR 是结果数据不是“命令实例标识”。因此错误时可不返回。17. 4.5.2 Error handling specific to a command 想表达什么这一节讲的是除了通用错误处理规则之外Section 7 中某些具体 HCI Command 的描述还会包含该命令专门的错误条件和错误处理表。也就是说4.5.1 是通用规则。 Section 7 里某些命令还会有自己的专用错误规则。如果某个命令有专用错误处理表应结合它一起看。例如你看一个具体命令时除了看Command Parameters Return Parameters Generated Events还要看Error Codes Error Conditions18. Table 4.2 是什么Table 4.2 标题是Types of error handling意思是错误处理类型它定义了 Section 7 中命令专用错误处理表里会用到的几种错误处理强度。表里有四种 TypeMC M RC R它们用来说明Controller 是否必须拒绝命令 是否必须返回指定错误码19. MC 类型是什么意思Table 4.2 中 MC 的 Error Condition 是The Controller shall return the specified error code and not execute the command.意思是Controller 必须返回指定错误码并且不得执行命令。表中Command Rejected with Error CodeMandatory Return Specified Error CodeMandatory也就是说MC 是最强要求必须拒绝命令 必须返回指定错误码 不能执行命令例如某个命令表写了一个错误条件是 MC那么 Controller 遇到这个条件时没有太多自由度必须按规范返回指定错误码。20. M 类型是什么意思M 的 Error Condition 是The Controller shall return an error code and not execute the command. The error code returned should be the one specified.意思是Controller 必须返回错误码并且不得执行命令推荐返回规范指定的那个错误码。表中Command Rejected with Error CodeMandatory Return Specified Error CodeRecommended也就是说必须拒绝命令 必须返回某个错误码 但返回指定错误码只是推荐不是强制它比 MC 稍弱。21. RC 类型是什么意思RC 的 Error Condition 是The Controller should return an error code and not execute the command. If it does return an error code, it shall be the one specified.意思是Controller 应该返回错误码并且不执行命令如果它返回错误码那么必须返回指定错误码。表中Command Rejected with Error CodeRecommended Return Specified Error CodeMandatory也就是说推荐拒绝命令 如果拒绝并返回错误码那么错误码必须是指定错误码这里的“拒绝命令”不是强制但一旦拒绝并返回错误码错误码必须符合规范指定值。22. R 类型是什么意思R 的 Error Condition 是The Controller should return an error code and not execute the command. If it does return an error code, it should be the one specified.意思是Controller 推荐返回错误码并且不执行命令如果返回错误码也推荐返回指定错误码。表中Command Rejected with Error CodeRecommended Return Specified Error CodeRecommended这是四种里约束最弱的一类。可以理解为推荐拒绝 推荐返回指定错误码 但不是强制23. MC / M / RC / R 对比可以整理成这样Type是否要拒绝命令是否要返回指定错误码强度MC必须必须最强M必须推荐强RC推荐如果返回错误码则必须是指定错误码中等R推荐推荐最弱简化理解MC必须拒绝必须指定错误码 M必须拒绝建议指定错误码 RC建议拒绝如果报错必须指定错误码 R建议拒绝建议指定错误码24. 什么时候判断 error condition 成立截图最后一段说An error situation occurs if any of the conditions in the table apply at the moment the Controller starts to process the command parameters, and before the Controller starts to execute the command.意思是当 Controller 开始处理命令参数、但还没有开始执行命令时如果错误条件表里的某个条件成立就认为发生了错误情况。这里的时间点很重要Controller 开始检查命令参数 ↓ 如果发现错误条件成立 ↓ 返回错误不执行命令 ↓ 如果没有错误 ↓ 才开始执行命令也就是说这些错误处理表主要针对命令开始执行之前就能检查出来的错误25. 如果状态在发送命令和 Controller 检查命令之间发生变化呢最后一句举了一个例子For example, an error condition because a conflicting mode was enabled would not apply if that mode is disabled between the Host sending the command to the HCI transport and the Controller starting to check the command parameters.意思是某个错误条件是否成立要看 Controller 开始检查命令参数那一刻而不是 Host 发送命令那一刻。例如Host 发送命令时Controller 处于某个冲突模式 但是在 Controller 实际开始检查这个命令参数之前这个冲突模式已经被关闭那么这个错误条件就不算成立。这个规则体现的是命令错误判断以 Controller 实际处理命令参数的时刻为准。不是以 Host 发出命令的时刻为准。26. 对 BLE 学习的实际意义对 BLE 来说这部分特别有用因为你后面看具体命令时经常会看到各种错误码。例如HCI_LE_Set_Advertising_Enable HCI_LE_Set_Extended_Advertising_Enable HCI_LE_Create_Connection HCI_LE_Set_Scan_Enable HCI_LE_Connection_Update这些命令可能返回Command Disallowed Invalid HCI Command Parameters Unsupported Feature or Parameter Value Unknown HCI Command Memory Capacity Exceeded Connection Timeout理解 4.5 后就能知道错误是在 Command Complete 里返回还是 Command Status 里返回 如果 Command Status 返回错误后面还会不会有 completion event 如果 Command Status 成功后续 completion event 还可能失败吗 错误时哪些返回参数还能相信27. 最关键的理解先看 Status再看其他参数无论是HCI_Command_Complete HCI_Command_Status 某个 command-specific completion event只要事件里有 Status就应该先看 Status。Status 0x00 才能按成功路径理解后面的参数 Status ! 0x00 表示错误 后面的参数可能不完整或无效 只有规范明确说有效的参数才能可靠使用这是解析 HCI log 时非常重要的习惯。28. 这部分关键信息总结28.1 参数错误通常导致命令不会开始执行除非具体命令另有说明否则任何参数错误都会让命令不执行只返回错误码。28.2 多个错误同时存在时Controller 可以选择返回其中一个不要认为返回的错误码一定覆盖所有问题。28.3 Command Complete 类型命令错误放在 Command Complete 的 Status 中流程是Host → Command Controller → HCI_Command_Complete Status 非 028.4 Command Status completion event 类型命令要区分错误发生时机如果命令未开始执行HCI_Command_Status Status 非 0 后续没有 completion event如果命令已开始执行后续失败HCI_Command_Status Status 0x00 completion event Status 非 028.5 不支持的命令返回 Unknown HCI Command0x01如果 Controller 不支持某个命令应返回Unknown HCI Command 0x0128.6 出错时 Return Parameters 可能不完整Status 一定返回。如果 Status 后面紧跟 Handle 或 BD_ADDR这个参数也应返回。其他参数是否返回取决于实现。28.7 Table 4.1 告诉你错误 completion event 中哪些参数仍然有效none表示除了 Status 之外没有其他参数可依赖。28.8 Table 4.2 定义命令专用错误处理类型MC必须拒绝必须返回指定错误码 M必须拒绝推荐返回指定错误码 RC推荐拒绝如果返回错误码必须是指定错误码 R推荐拒绝推荐返回指定错误码28.9 错误条件是否成立以 Controller 开始检查命令参数的时刻为准不是以 Host 发出命令的那一刻为准。29. 最核心的一句话这一节可以总结为Command error handling 的核心是规定 HCI Command 出错时错误码放在哪里、命令是否还会执行、后续 completion event 是否还会生成以及错误情况下哪些返回参数仍然有效Host 解析 HCI 事件时必须先看 StatusStatus 非 0 时不能默认后续所有参数都有效。对 BLE 学习最重要的是Command Status 非 0命令没开始后面通常没有 completion event。 Command Status 0命令开始了但最终结果还要看后续 completion event。 Command Complete / completion event 里的 Status 非 0表示命令或过程失败后面的参数要谨慎使用。