summaryrefslogtreecommitdiff
path: root/network
diff options
context:
space:
mode:
authorYang You (UU) <[email protected]>2025-11-13 19:29:17 -0800
committerYang You (UU) <[email protected]>2025-11-13 19:29:17 -0800
commitefa7a263ea3939ecf56e6a1256458d12c400e169 (patch)
tree9cdc5d9c7205385a96eb350ad11291bc18700982 /network
parent773e9d01f3348ec31b63eccb6b42bd72d206a32c (diff)
move the logic to CPP
Diffstat (limited to 'network')
-rw-r--r--network/wlan/WIFICX/drivercode/wifitransition.cpp314
-rw-r--r--network/wlan/WIFICX/drivercode/wifitransition.h313
2 files changed, 314 insertions, 313 deletions
diff --git a/network/wlan/WIFICX/drivercode/wifitransition.cpp b/network/wlan/WIFICX/drivercode/wifitransition.cpp
index 4e55f39c..9ac857bc 100644
--- a/network/wlan/WIFICX/drivercode/wifitransition.cpp
+++ b/network/wlan/WIFICX/drivercode/wifitransition.cpp
@@ -1,5 +1,319 @@
#include "wifitransition.h"
+// Common TLV parsing helper: computes TLV span, optional dump, calls a parser, converts status.
+template<typename Param, typename ParserFn>
+NTSTATUS ParseTlvCommon(TransitionContext& ctx,
+ UINT16 messageId,
+ ParserFn parser,
+ Param& outParams,
+ bool dumpStream = true)
+{
+ if (ctx.InLen < sizeof(WDI_MESSAGE_HEADER))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ auto* tlvBytes = static_cast<UCHAR*>(ctx.RawBuffer) + sizeof(WDI_MESSAGE_HEADER);
+ auto tlvLen = static_cast<ULONG>(ctx.InLen - sizeof(WDI_MESSAGE_HEADER));
+
+ if (dumpStream)
+ {
+ DumpMessageTlvByteStream(
+ messageId,
+ TRUE,
+ ctx.DevCtx->TlvContext.PeerVersion,
+ tlvLen,
+ tlvBytes,
+ 0,
+ nullptr);
+ }
+
+ auto ndisStatus = parser(tlvLen, tlvBytes, &ctx.DevCtx->TlvContext, &outParams);
+ return Wifi::ConvertNDISSTATUSToNTSTATUS(ndisStatus);
+}
+
+// Execute two step callables.
+// StepM3Fn signature: NTSTATUS (TransitionContext&, Param&, UINT& bytesWritten)
+// StepM4Fn signature: NTSTATUS (TransitionContext&, Param&)
+// Always calls WifiRequestComplete after StepM3 with the bytesWritten produced by StepM3.
+// Skips StepM4 if StepM3 failed
+template<typename Param, typename StepM3Fn, typename StepM4Fn>
+NTSTATUS ExecuteSteps(TransitionContext& ctx, Param& p, StepM3Fn stepM3, StepM4Fn stepM4)
+{
+ UINT bytesWritten = sizeof(WDI_MESSAGE_HEADER); // default minimum
+ NTSTATUS m3Status = stepM3(ctx, p, bytesWritten);
+ // Report the M3 status back to OS
+ // OS expects M3 before the M4
+ WifiIhvNotifyM3Completion(ctx.WifiRequest, m3Status, bytesWritten);
+ if (!NT_SUCCESS(m3Status))
+ {
+ return m3Status;
+ }
+ return stepM4(ctx, p);
+}
+// Primary traits template (specialize per MessageId)
+template<UINT16 MsgId>
+struct TransitionTraits;
+
+// -------- WDI_TASK_SET_RADIO_STATE --------
+template<>
+struct TransitionTraits<WDI_TASK_SET_RADIO_STATE>
+{
+ using ParamType = WDI_SET_RADIO_STATE_PARAMETERS;
+ enum : UINT16 { CompleteIndication = WDI_INDICATION_SET_RADIO_STATE_COMPLETE };
+
+ NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
+ {
+ return ParseTlvCommon(ctx,
+ WDI_TASK_SET_RADIO_STATE,
+ [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
+ {
+ return ParseWdiTaskSetRadioState(len, bytes, tlvCtx, out);
+ },
+ p,
+ true);
+ }
+ void Cleanup(ParamType& p) { CleanupParsedWdiTaskSetRadioState(&p); }
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // STEPM3
+ [](TransitionContext&, ParamType&, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return STATUS_SUCCESS;
+ },
+ // STEPM4
+ [](TransitionContext& c, ParamType& par)
+ {
+ return c.DevCtx->wifiHAL->WifiIhvSetRadioState(par, c.Header);
+ }
+ );
+ }
+ bool ShouldSendComplete(NTSTATUS) const { return true; }
+};
+
+// -------- WDI_TASK_SCAN --------
+template<>
+struct TransitionTraits<WDI_TASK_SCAN>
+{
+ using ParamType = WDI_SCAN_PARAMETERS;
+ enum : UINT16 { CompleteIndication = WDI_INDICATION_SCAN_COMPLETE };
+
+ NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
+ {
+ return ParseTlvCommon(ctx,
+ WDI_TASK_SCAN,
+ [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
+ {
+ return ParseWdiTaskScan(len, bytes, tlvCtx, out);
+ },
+ p,
+ true);
+ }
+ void Cleanup(ParamType& p) { CleanupParsedWdiTaskScan(&p); }
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // STEPM3
+ [](TransitionContext&, ParamType&, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return STATUS_SUCCESS;
+ },
+ // STEPM4
+ [](TransitionContext& c, ParamType& par)
+ {
+ return c.DevCtx->wifiHAL->WifiIhvScan(par, c.Header);
+ }
+ );
+ }
+ bool ShouldSendComplete(NTSTATUS) const { return true; }
+};
+
+// -------- WDI_TASK_DOT11_RESET --------
+template<>
+struct TransitionTraits<WDI_TASK_DOT11_RESET>
+{
+ using ParamType = WDI_TASK_DOT11_RESET_PARAMETERS;
+ enum : UINT16 { CompleteIndication = WDI_INDICATION_DOT11_RESET_COMPLETE };
+
+ NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
+ {
+ return ParseTlvCommon(ctx,
+ WDI_TASK_DOT11_RESET,
+ [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
+ {
+ return ParseWdiTaskDot11Reset(len, bytes, tlvCtx, out);
+ },
+ p,
+ false);
+ }
+ void Cleanup(ParamType& p) { CleanupParsedWdiTaskDot11Reset(&p); }
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // STEPM3
+ [](TransitionContext&, ParamType&, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return STATUS_SUCCESS;
+ },
+ // STEPM4
+ [](TransitionContext& c, ParamType& par)
+ {
+ return c.DevCtx->wifiHAL->WifiIhvReset(par, c.Header);
+ });
+ }
+ bool ShouldSendComplete(NTSTATUS) const { return true; }
+};
+
+// -------- WDI_TASK_CONNECT --------
+template<>
+struct TransitionTraits<WDI_TASK_CONNECT>
+{
+ using ParamType = WDI_TASK_CONNECT_PARAMETERS;
+ enum : UINT16 { CompleteIndication = WDI_INDICATION_CONNECT_COMPLETE };
+
+ NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
+ {
+ return ParseTlvCommon(ctx,
+ WDI_TASK_CONNECT,
+ [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
+ {
+ return ParseWdiTaskConnect(len, bytes, tlvCtx, out);
+ },
+ p,
+ true);
+ }
+ void Cleanup(ParamType& p) { CleanupParsedWdiTaskConnect(&p); }
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // STEPM3
+ [](TransitionContext&, ParamType&, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return STATUS_SUCCESS;
+ },
+ // STEPM4
+ [](TransitionContext& c, ParamType& par)
+ {
+ return c.DevCtx->wifiHAL->WifiIhvConnect(par, c.Header);
+ });
+ }
+ bool ShouldSendComplete(NTSTATUS s) const { return s != STATUS_PENDING; }
+};
+
+// -------- WDI_TASK_DISCONNECT --------
+template<>
+struct TransitionTraits<WDI_TASK_DISCONNECT>
+{
+ struct ParamType {};
+ enum : UINT16 { CompleteIndication = WDI_INDICATION_DISCONNECT_COMPLETE };
+
+ NTSTATUS Parse(TransitionContext&, ParamType&) { return STATUS_SUCCESS; }
+ void Cleanup(ParamType&) {}
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // STEPM3
+ [](TransitionContext&, ParamType&, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return STATUS_SUCCESS;
+ },
+ // STEPM4
+ [](TransitionContext& c, ParamType&)
+ {
+ c.DevCtx->wifiHAL->WifiIhvPerformDisassociation(c.Header, WDI_ASSOC_STATUS_DISASSOCIATED_BY_HOST);
+ return STATUS_SUCCESS;
+ });
+ }
+ bool ShouldSendComplete(NTSTATUS) const { return true; }
+};
+
+// -------- WDI_SET_SAE_AUTH_PARAMS --------
+template<>
+struct TransitionTraits<WDI_SET_SAE_AUTH_PARAMS>
+{
+ using ParamType = WDI_SET_SAE_AUTH_PARAMS_COMMAND;
+ enum : UINT16 { CompleteIndication = 0 };
+
+ NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
+ {
+ return ParseTlvCommon(ctx,
+ WDI_SET_SAE_AUTH_PARAMS,
+ [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
+ {
+ return ParseWdiSetSaeAuthParams(len, bytes, tlvCtx, out);
+ },
+ p,
+ /*dumpStream*/ false);
+ }
+
+ void Cleanup(ParamType& p)
+ {
+ CleanupParsedWdiSetSaeAuthParams(&p);
+ }
+
+ NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
+ {
+ return ExecuteSteps(ctx, p,
+ // Step M3: invoke HAL handler, report bytes written (just header)
+ [](TransitionContext& c, ParamType& par, UINT& bytesWritten)
+ {
+ bytesWritten = sizeof(WDI_MESSAGE_HEADER);
+ return c.DevCtx->wifiHAL->WifiIhvSetSaeAuthParams(par, c.Header);
+ },
+ // Step M4: no-op (no completion indication for this OID)
+ [](TransitionContext&, ParamType&) { return STATUS_SUCCESS; });
+ }
+
+ bool ShouldSendComplete(NTSTATUS) const
+ {
+ // Do not send M4 indication for WDI_SET_SAE_AUTH_PARAMS (original code omitted it).
+ return false;
+ }
+};
+
+// -------- Generic runner (compile-time) --------
+template<UINT16 MsgId>
+NTSTATUS RunTransition(TransitionContext& ctx)
+{
+ TransitionTraits<MsgId> traits;
+ typename TransitionTraits<MsgId>::ParamType params{};
+ NTSTATUS parseStatus = traits.Parse(ctx, params);
+ if (!NT_SUCCESS(parseStatus))
+ {
+ traits.Cleanup(params);
+ // Report Failed M3 to OS
+ // Note: No M4 indication on parse failure
+ WifiIhvNotifyM3Completion(ctx.WifiRequest, parseStatus, 0);
+ return parseStatus;
+ }
+
+ NTSTATUS m4Status = traits.Handle(ctx, params);
+
+ if (traits.ShouldSendComplete(m4Status))
+ {
+ WifiIhvSendM4IndicationToOs(
+ ctx.Device,
+ TransitionTraits<MsgId>::CompleteIndication,
+ ctx.Header,
+ m4Status);
+ }
+
+ traits.Cleanup(params);
+ return m4Status;
+}
+
+
// Runtime dispatcher switches on MessageId and invokes the matching compile-time runner.
NTSTATUS RunTransitionByMessage(TransitionContext& ctx, UINT16 messageId)
{
diff --git a/network/wlan/WIFICX/drivercode/wifitransition.h b/network/wlan/WIFICX/drivercode/wifitransition.h
index d57e73cb..74d8dff6 100644
--- a/network/wlan/WIFICX/drivercode/wifitransition.h
+++ b/network/wlan/WIFICX/drivercode/wifitransition.h
@@ -15,318 +15,5 @@ struct TransitionContext
UINT OutLen;
};
-// Common TLV parsing helper: computes TLV span, optional dump, calls a parser, converts status.
-template<typename Param, typename ParserFn>
-NTSTATUS ParseTlvCommon(TransitionContext& ctx,
- UINT16 messageId,
- ParserFn parser,
- Param& outParams,
- bool dumpStream = true)
-{
- if (ctx.InLen < sizeof(WDI_MESSAGE_HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- auto* tlvBytes = static_cast<UCHAR*>(ctx.RawBuffer) + sizeof(WDI_MESSAGE_HEADER);
- auto tlvLen = static_cast<ULONG>(ctx.InLen - sizeof(WDI_MESSAGE_HEADER));
-
- if (dumpStream)
- {
- DumpMessageTlvByteStream(
- messageId,
- TRUE,
- ctx.DevCtx->TlvContext.PeerVersion,
- tlvLen,
- tlvBytes,
- 0,
- nullptr);
- }
-
- auto ndisStatus = parser(tlvLen, tlvBytes, &ctx.DevCtx->TlvContext, &outParams);
- return Wifi::ConvertNDISSTATUSToNTSTATUS(ndisStatus);
-}
-
-// Execute two step callables.
-// StepM3Fn signature: NTSTATUS (TransitionContext&, Param&, UINT& bytesWritten)
-// StepM4Fn signature: NTSTATUS (TransitionContext&, Param&)
-// Always calls WifiRequestComplete after StepM3 with the bytesWritten produced by StepM3.
-// Skips StepM4 if StepM3 failed
-template<typename Param, typename StepM3Fn, typename StepM4Fn>
-NTSTATUS ExecuteSteps(TransitionContext& ctx, Param& p, StepM3Fn stepM3, StepM4Fn stepM4)
-{
- UINT bytesWritten = sizeof(WDI_MESSAGE_HEADER); // default minimum
- NTSTATUS m3Status = stepM3(ctx, p, bytesWritten);
- // Report the M3 status back to OS
- // OS expects M3 before the M4
- WifiIhvNotifyM3Completion(ctx.WifiRequest, m3Status, bytesWritten);
- if (!NT_SUCCESS(m3Status))
- {
- return m3Status;
- }
- return stepM4(ctx, p);
-}
-// Primary traits template (specialize per MessageId)
-template<UINT16 MsgId>
-struct TransitionTraits;
-
-// -------- WDI_TASK_SET_RADIO_STATE --------
-template<>
-struct TransitionTraits<WDI_TASK_SET_RADIO_STATE>
-{
- using ParamType = WDI_SET_RADIO_STATE_PARAMETERS;
- enum : UINT16 { CompleteIndication = WDI_INDICATION_SET_RADIO_STATE_COMPLETE };
-
- NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
- {
- return ParseTlvCommon(ctx,
- WDI_TASK_SET_RADIO_STATE,
- [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
- {
- return ParseWdiTaskSetRadioState(len, bytes, tlvCtx, out);
- },
- p,
- true);
- }
- void Cleanup(ParamType& p) { CleanupParsedWdiTaskSetRadioState(&p); }
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // STEPM3
- [](TransitionContext&, ParamType&, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return STATUS_SUCCESS;
- },
- // STEPM4
- [](TransitionContext& c, ParamType& par)
- {
- return c.DevCtx->wifiHAL->WifiIhvSetRadioState(par, c.Header);
- }
- );
- }
- bool ShouldSendComplete(NTSTATUS) const { return true; }
-};
-
-// -------- WDI_TASK_SCAN --------
-template<>
-struct TransitionTraits<WDI_TASK_SCAN>
-{
- using ParamType = WDI_SCAN_PARAMETERS;
- enum : UINT16 { CompleteIndication = WDI_INDICATION_SCAN_COMPLETE };
-
- NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
- {
- return ParseTlvCommon(ctx,
- WDI_TASK_SCAN,
- [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
- {
- return ParseWdiTaskScan(len, bytes, tlvCtx, out);
- },
- p,
- true);
- }
- void Cleanup(ParamType& p){ CleanupParsedWdiTaskScan(&p); }
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // STEPM3
- [](TransitionContext&, ParamType&, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return STATUS_SUCCESS;
- },
- // STEPM4
- [](TransitionContext& c, ParamType& par)
- {
- return c.DevCtx->wifiHAL->WifiIhvScan(par, c.Header);
- }
- );
- }
- bool ShouldSendComplete(NTSTATUS) const { return true; }
-};
-
-// -------- WDI_TASK_DOT11_RESET --------
-template<>
-struct TransitionTraits<WDI_TASK_DOT11_RESET>
-{
- using ParamType = WDI_TASK_DOT11_RESET_PARAMETERS;
- enum : UINT16 { CompleteIndication = WDI_INDICATION_DOT11_RESET_COMPLETE };
-
- NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
- {
- return ParseTlvCommon(ctx,
- WDI_TASK_DOT11_RESET,
- [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
- {
- return ParseWdiTaskDot11Reset(len, bytes, tlvCtx, out);
- },
- p,
- false);
- }
- void Cleanup(ParamType& p){ CleanupParsedWdiTaskDot11Reset(&p); }
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // STEPM3
- [](TransitionContext&, ParamType&, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return STATUS_SUCCESS;
- },
- // STEPM4
- [](TransitionContext& c, ParamType& par)
- {
- return c.DevCtx->wifiHAL->WifiIhvReset(par, c.Header);
- });
- }
- bool ShouldSendComplete(NTSTATUS) const { return true; }
-};
-
-// -------- WDI_TASK_CONNECT --------
-template<>
-struct TransitionTraits<WDI_TASK_CONNECT>
-{
- using ParamType = WDI_TASK_CONNECT_PARAMETERS;
- enum : UINT16 { CompleteIndication = WDI_INDICATION_CONNECT_COMPLETE };
-
- NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
- {
- return ParseTlvCommon(ctx,
- WDI_TASK_CONNECT,
- [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
- {
- return ParseWdiTaskConnect(len, bytes, tlvCtx, out);
- },
- p,
- true);
- }
- void Cleanup(ParamType& p){ CleanupParsedWdiTaskConnect(&p); }
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // STEPM3
- [](TransitionContext&, ParamType&, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return STATUS_SUCCESS;
- },
- // STEPM4
- [](TransitionContext& c, ParamType& par)
- {
- return c.DevCtx->wifiHAL->WifiIhvConnect(par, c.Header);
- });
- }
- bool ShouldSendComplete(NTSTATUS s) const { return s != STATUS_PENDING; }
-};
-
-// -------- WDI_TASK_DISCONNECT --------
-template<>
-struct TransitionTraits<WDI_TASK_DISCONNECT>
-{
- struct ParamType {};
- enum : UINT16 { CompleteIndication = WDI_INDICATION_DISCONNECT_COMPLETE };
-
- NTSTATUS Parse(TransitionContext&, ParamType&){ return STATUS_SUCCESS; }
- void Cleanup(ParamType&){}
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // STEPM3
- [](TransitionContext&, ParamType&, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return STATUS_SUCCESS;
- },
- // STEPM4
- [](TransitionContext& c, ParamType&)
- {
- c.DevCtx->wifiHAL->WifiIhvPerformDisassociation(c.Header, WDI_ASSOC_STATUS_DISASSOCIATED_BY_HOST);
- return STATUS_SUCCESS;
- });
- }
- bool ShouldSendComplete(NTSTATUS) const { return true; }
-};
-
-// -------- WDI_SET_SAE_AUTH_PARAMS --------
-template<>
-struct TransitionTraits<WDI_SET_SAE_AUTH_PARAMS>
-{
- using ParamType = WDI_SET_SAE_AUTH_PARAMS_COMMAND;
- enum : UINT16 { CompleteIndication = 0 };
-
- NTSTATUS Parse(TransitionContext& ctx, ParamType& p)
- {
- return ParseTlvCommon(ctx,
- WDI_SET_SAE_AUTH_PARAMS,
- [](ULONG len, UINT8* bytes, PCTLV_CONTEXT tlvCtx, ParamType* out)
- {
- return ParseWdiSetSaeAuthParams(len, bytes, tlvCtx, out);
- },
- p,
- /*dumpStream*/ false);
- }
-
- void Cleanup(ParamType& p)
- {
- CleanupParsedWdiSetSaeAuthParams(&p);
- }
-
- NTSTATUS Handle(TransitionContext& ctx, ParamType& p)
- {
- return ExecuteSteps(ctx, p,
- // Step M3: invoke HAL handler, report bytes written (just header)
- [](TransitionContext& c, ParamType& par, UINT& bytesWritten)
- {
- bytesWritten = sizeof(WDI_MESSAGE_HEADER);
- return c.DevCtx->wifiHAL->WifiIhvSetSaeAuthParams(par, c.Header);
- },
- // Step M4: no-op (no completion indication for this OID)
- [](TransitionContext&, ParamType&) { return STATUS_SUCCESS; });
- }
-
- bool ShouldSendComplete(NTSTATUS) const
- {
- // Do not send M4 indication for WDI_SET_SAE_AUTH_PARAMS (original code omitted it).
- return false;
- }
-};
-
-// -------- Generic runner (compile-time) --------
-template<UINT16 MsgId>
-NTSTATUS RunTransition(TransitionContext& ctx)
-{
- TransitionTraits<MsgId> traits;
- typename TransitionTraits<MsgId>::ParamType params{};
- NTSTATUS parseStatus = traits.Parse(ctx, params);
- if (!NT_SUCCESS(parseStatus))
- {
- traits.Cleanup(params);
- // Report Failed M3 to OS
- // Note: No M4 indication on parse failure
- WifiIhvNotifyM3Completion(ctx.WifiRequest, parseStatus, 0);
- return parseStatus;
- }
-
- NTSTATUS m4Status = traits.Handle(ctx, params);
-
- if (traits.ShouldSendComplete(m4Status))
- {
- WifiIhvSendM4IndicationToOs(
- ctx.Device,
- TransitionTraits<MsgId>::CompleteIndication,
- ctx.Header,
- m4Status);
- }
-
- traits.Cleanup(params);
- return m4Status;
-}
-
// -------- Runtime dispatcher (decl) --------
NTSTATUS RunTransitionByMessage(TransitionContext& ctx, UINT16 messageId); \ No newline at end of file