24
24
#include < lib/core/Global.h>
25
25
#include < lib/support/CodeUtils.h>
26
26
27
- #include < functional>
27
+ #include < algorithm>
28
+ #include < cctype>
28
29
29
30
using namespace chip ;
30
31
using namespace chip ::app;
@@ -46,6 +47,12 @@ Server & Server::Instance()
46
47
47
48
Server::Server () : AttributeAccessInterface(NullOptional, Id), CommandHandlerInterface(NullOptional, Id) {}
48
49
50
+ Server::~Server ()
51
+ {
52
+ unregisterAttributeAccessOverride (this );
53
+ InteractionModelEngine::GetInstance ()->UnregisterCommandHandler (this );
54
+ }
55
+
49
56
CHIP_ERROR Server::Init (EndpointId endpoint)
50
57
{
51
58
VerifyOrReturnError (endpoint != kInvalidEndpointId , CHIP_ERROR_INVALID_ARGUMENT);
@@ -59,39 +66,58 @@ CHIP_ERROR Server::Init(EndpointId endpoint)
59
66
60
67
CHIP_ERROR Server::ClearNetworkCredentials ()
61
68
{
62
- VerifyOrReturnError (! SsidSpan (). empty () || ! PassphraseSpan (). empty (), CHIP_NO_ERROR);
69
+ VerifyOrReturnError (HaveNetworkCredentials (), CHIP_NO_ERROR);
63
70
64
71
mSsidLen = 0 ;
65
72
mPassphrase .SetLength (0 );
66
73
MatterReportingAttributeChangeCallback (mEndpointId , Id, Ssid::Id);
67
74
return CHIP_NO_ERROR;
68
75
}
69
76
77
+ // TODO: Move this into lib/support somewhere and also use it network-commissioning.cpp
78
+ bool IsValidWpaPersonalCredential (ByteSpan credential)
79
+ {
80
+ // As per spec section 11.9.7.3. AddOrUpdateWiFiNetwork Command
81
+ if (8 <= credential.size () && credential.size () <= 63 ) // passphrase
82
+ {
83
+ return true ;
84
+ }
85
+ if (credential.size () == 64 ) // raw hex psk
86
+ {
87
+ return std::all_of (credential.begin (), credential.end (), std::isxdigit);
88
+ }
89
+ return false ;
90
+ }
91
+
70
92
CHIP_ERROR Server::SetNetworkCredentials (ByteSpan ssid, ByteSpan passphrase)
71
93
{
72
94
VerifyOrReturnError (1 <= ssid.size () && ssid.size () <= sizeof (mSsid ), CHIP_ERROR_INVALID_ARGUMENT);
73
- VerifyOrReturnError (1 <= passphrase. size () && passphrase. size () <= mPassphrase . Capacity ( ), CHIP_ERROR_INVALID_ARGUMENT);
95
+ VerifyOrReturnError (IsValidWpaPersonalCredential ( passphrase), CHIP_ERROR_INVALID_ARGUMENT);
74
96
75
- VerifyOrReturnError (!SsidSpan ().data_equal (ssid) || !PassphraseSpan ().data_equal (passphrase), CHIP_NO_ERROR);
97
+ bool ssidChanged = !SsidSpan ().data_equal (ssid);
98
+ bool passphraseChanged = !PassphraseSpan ().data_equal (passphrase);
99
+ VerifyOrReturnError (ssidChanged || passphraseChanged, CHIP_NO_ERROR);
76
100
77
101
memcpy (mSsid , ssid.data (), ssid.size ());
78
102
mSsidLen = static_cast <decltype (mSsidLen )>(ssid.size ());
79
103
80
- ReturnErrorOnFailure (mPassphrase .SetLength (passphrase.size ()));
104
+ VerifyOrDie (mPassphrase .SetLength (passphrase.size ()) == CHIP_NO_ERROR );
81
105
memcpy (mPassphrase .Bytes (), passphrase.data (), passphrase.size ());
82
106
83
- MatterReportingAttributeChangeCallback (mEndpointId , Id, Ssid::Id); // report SSID change even if only passphrase changed
107
+ // Note: The spec currently defines no way to signal a passphrase change
108
+ if (ssidChanged)
109
+ {
110
+ MatterReportingAttributeChangeCallback (mEndpointId , Id, Ssid::Id);
111
+ }
84
112
return CHIP_NO_ERROR;
85
113
}
86
114
87
115
CHIP_ERROR Server::Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
88
116
{
89
117
switch (aPath.mAttributeId )
90
118
{
91
- case Ssid::Id: {
92
- auto ssid = SsidSpan ();
93
- return (ssid.empty ()) ? aEncoder.EncodeNull () : aEncoder.Encode (ssid);
94
- }
119
+ case Ssid::Id:
120
+ return HaveNetworkCredentials () ? aEncoder.Encode (SsidSpan ()) : aEncoder.EncodeNull ();
95
121
}
96
122
return CHIP_NO_ERROR;
97
123
}
@@ -102,21 +128,22 @@ void Server::InvokeCommand(HandlerContext & ctx)
102
128
{
103
129
case Commands::NetworkPassphraseRequest::Id:
104
130
HandleCommand<Commands::NetworkPassphraseRequest::DecodableType>(
105
- ctx, std::bind (&Server::HandleNetworkPassphraseRequest, this , _1, _2) );
131
+ ctx, [ this ](HandlerContext & ctx, const auto & req) { HandleNetworkPassphraseRequest (ctx, req); } );
106
132
return ;
107
133
}
108
134
}
109
135
110
136
void Server::HandleNetworkPassphraseRequest (HandlerContext & ctx, const Commands::NetworkPassphraseRequest::DecodableType & req)
111
137
{
112
- if (mPassphrase . Length () > 0 )
138
+ if (HaveNetworkCredentials () )
113
139
{
114
140
Commands::NetworkPassphraseResponse::Type response;
115
141
response.passphrase = mPassphrase .Span ();
116
142
ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
117
143
}
118
144
else
119
145
{
146
+ // TODO: Status code TBC: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/9234
120
147
ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Protocols::InteractionModel::Status::InvalidInState);
121
148
}
122
149
}
0 commit comments