@@ -45,205 +45,191 @@ namespace ThreadBorderRouterManagement {
45
45
46
46
using Protocols::InteractionModel::Status;
47
47
48
- static bool CheckOverCASESession (CommandHandlerInterface::HandlerContext & ctx)
48
+ static bool IsOverCASESession (CommandHandlerInterface::HandlerContext & ctx)
49
49
{
50
50
Messaging::ExchangeContext * exchangeCtx = ctx.mCommandHandler .GetExchangeContext ();
51
- if (!exchangeCtx || !exchangeCtx->HasSessionHandle () || !exchangeCtx->GetSessionHandle ()->IsSecureSession () ||
52
- exchangeCtx->GetSessionHandle ()->AsSecureSession ()->GetSecureSessionType () != Transport::SecureSession::Type::kCASE )
53
- {
54
- ChipLogError (Zcl, " This command MUST be over a valid CASE session" );
55
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::UnsupportedAccess);
56
- return false ;
57
- }
58
- return true ;
51
+ return exchangeCtx && exchangeCtx->HasSessionHandle () && exchangeCtx->GetSessionHandle ()->IsSecureSession () &&
52
+ exchangeCtx->GetSessionHandle ()->AsSecureSession ()->GetSecureSessionType () == Transport::SecureSession::Type::kCASE ;
59
53
}
60
54
61
- static bool CheckFailSafeArmed (CommandHandlerInterface::HandlerContext & ctx)
55
+ static bool IsFailSafeArmed (CommandHandlerInterface::HandlerContext & ctx)
62
56
{
63
57
auto & failSafeContext = Server::GetInstance ().GetFailSafeContext ();
64
- if (failSafeContext.IsFailSafeArmed (ctx.mCommandHandler .GetAccessingFabricIndex ()))
65
- {
66
- return true ;
67
- }
68
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::FailsafeRequired);
69
- return false ;
58
+ return failSafeContext.IsFailSafeArmed (ctx.mCommandHandler .GetAccessingFabricIndex ());
70
59
}
71
60
72
- static bool CheckDelegate (CommandHandlerInterface::HandlerContext & ctx, Delegate * delegate)
61
+ Status ServerInstance::HandleGetDatasetRequest (bool isOverCASESession, Delegate::DatasetType type,
62
+ Thread::OperationalDataset & dataset)
73
63
{
74
- if (!delegate )
64
+ if (!isOverCASESession )
75
65
{
76
- ChipLogError (Zcl, " Thread Border Router Management server not initialized" );
77
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::InvalidInState);
66
+ return Status::UnsupportedAccess;
78
67
}
79
- return delegate;
80
- }
81
-
82
- void ServerInstance::HandleGetDatasetRequest (HandlerContext & ctx, Delegate::DatasetType type)
83
- {
84
- VerifyOrReturn (CheckOverCASESession (ctx));
85
- VerifyOrReturn (CheckDelegate (ctx, mDelegate ));
86
68
87
- Commands::DatasetResponse::Type response;
88
- Thread::OperationalDataset dataset;
89
69
CHIP_ERROR err = mDelegate ->GetDataset (dataset, type);
90
70
if (err != CHIP_NO_ERROR)
91
71
{
92
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath ,
93
- err == CHIP_IM_GLOBAL_STATUS (NotFound) ? StatusIB (err).mStatus : Status::Failure);
94
- return ;
72
+ return err == CHIP_IM_GLOBAL_STATUS (NotFound) ? StatusIB (err).mStatus : Status::Failure;
95
73
}
96
- response.dataset = dataset.AsByteSpan ();
97
- ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
74
+ return Status::Success;
98
75
}
99
76
100
- void ServerInstance::HandleSetActiveDatasetRequest (HandlerContext & ctx ,
101
- const Commands::SetActiveDatasetRequest::DecodableType & req)
77
+ Status ServerInstance::HandleSetActiveDatasetRequest (bool failSafeArmed ,
78
+ const Commands::SetActiveDatasetRequest::DecodableType & req)
102
79
{
103
80
// The SetActiveDatasetRequest command SHALL be FailSafeArmed. Upon receiving this command, the Thread BR will set its
104
81
// active dataset. If the dataset is set successfully, OnActivateDatasetComplete will be called with CHIP_NO_ERROR, prompting
105
82
// the Thread BR to respond with a success status and disarm the FailSafe timer. If an error occurs while setting the active
106
83
// dataset, the Thread BR should respond with a failure status. In this case, when the FailSafe timer expires, the active
107
84
// dataset set by this command will be reverted. If the FailSafe timer expires before the Thread BR responds, the Thread BR will
108
85
// respond with a timeout status and the active dataset should also be reverted.
109
- VerifyOrReturn (CheckFailSafeArmed (ctx));
110
- VerifyOrReturn (CheckDelegate (ctx, mDelegate ));
111
- if (mAsyncCommandHandle .Get () != nullptr )
112
- {
113
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::Busy);
114
- return ;
115
- }
86
+ ReturnErrorCodeIf (!failSafeArmed, Status::FailsafeRequired);
87
+ ReturnErrorCodeIf (!mDelegate , Status::InvalidInState);
116
88
117
89
Thread::OperationalDataset activeDataset;
118
90
Thread::OperationalDataset currentActiveDataset;
119
91
uint64_t currentActiveDatasetTimestamp;
120
- if (activeDataset.Init (req.activeDataset ) != CHIP_NO_ERROR)
121
- {
122
- // If any of the parameters in the ActiveDataset is invalid, the command SHALL fail with a status code
123
- // of INVALID_COMMAND.
124
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::InvalidCommand);
125
- return ;
126
- }
92
+ // If any of the parameters in the ActiveDataset is invalid, the command SHALL fail with a status code
93
+ // of INVALID_COMMAND.
94
+ ReturnErrorCodeIf (activeDataset.Init (req.activeDataset ) != CHIP_NO_ERROR, Status::InvalidCommand);
127
95
96
+ // If this command is invoked when the ActiveDatasetTimestamp attribute is not null, the command SHALL
97
+ // fail with a status code of INVALID_IN_STATE.
128
98
if (mDelegate ->GetDataset (currentActiveDataset, Delegate::DatasetType::kActive ) == CHIP_NO_ERROR &&
129
99
currentActiveDataset.GetActiveTimestamp (currentActiveDatasetTimestamp) == CHIP_NO_ERROR)
130
100
{
131
- // If this command is invoked when the ActiveDatasetTimestamp attribute is not null, the command SHALL
132
- // fail with a status code of INVALID_IN_STATE.
133
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::InvalidInState);
134
- return ;
101
+ return Status::InvalidInState;
135
102
}
136
103
137
- mPath = ctx.mRequestPath ;
138
- mAsyncCommandHandle = CommandHandler::Handle (&ctx.mCommandHandler );
139
- ctx.mCommandHandler .FlushAcksRightAwayOnSlowCommand ();
140
104
mBreadcrumb = req.breadcrumb ;
141
- CHIP_ERROR err = CHIP_NO_ERROR;
142
- if ((err = mDelegate ->SetActiveDataset (activeDataset, this )) != CHIP_NO_ERROR)
143
- {
144
- OnActivateDatasetComplete (err);
145
- }
105
+ CHIP_ERROR err = mDelegate ->SetActiveDataset (activeDataset, this );
106
+ return StatusIB (err).mStatus ;
146
107
}
147
108
148
- void ServerInstance::HandleSetPendingDatasetRequest (HandlerContext & ctx,
149
- const Commands::SetPendingDatasetRequest::DecodableType & req)
109
+ Status ServerInstance::HandleSetPendingDatasetRequest (const Commands::SetPendingDatasetRequest::DecodableType & req)
150
110
{
151
- VerifyOrReturn ( CheckDelegate (ctx, mDelegate ) );
111
+ ReturnErrorCodeIf (! mDelegate , Status::InvalidInState );
152
112
bool panChangeSupported;
153
113
if (mDelegate ->GetPanChangeSupported (panChangeSupported) != CHIP_NO_ERROR || !panChangeSupported)
154
114
{
155
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::UnsupportedCommand);
156
- return ;
115
+ return Status::UnsupportedCommand;
157
116
}
158
117
Thread::OperationalDataset pendingDataset;
159
- if (pendingDataset.Init (req.pendingDataset ) != CHIP_NO_ERROR)
118
+ // If any of the parameters in the PendingDataset is invalid, the command SHALL fail with a status code
119
+ // of INVALID_COMMAND.
120
+ ReturnErrorCodeIf (pendingDataset.Init (req.pendingDataset ) != CHIP_NO_ERROR, Status::InvalidCommand);
121
+ CHIP_ERROR err = mDelegate ->SetPendingDataset (pendingDataset);
122
+ return StatusIB (err).mStatus ;
123
+ }
124
+
125
+ void AddDatasetResponse (CommandHandlerInterface::HandlerContext & ctx, Status status, Thread::OperationalDataset & dataset)
126
+ {
127
+ if (status != Status::Success)
160
128
{
161
- // If any of the parameters in the PendingDataset is invalid, the command SHALL fail with a status code
162
- // of INVALID_COMMAND.
163
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::InvalidCommand);
129
+ ctx.mCommandHandler .AddStatus (ctx.mRequestPath , status);
164
130
return ;
165
131
}
166
- CHIP_ERROR err = mDelegate ->SetPendingDataset (pendingDataset);
167
- ctx.mCommandHandler .AddStatus (ctx.mRequestPath , StatusIB (err).mStatus );
132
+ Commands::DatasetResponse::Type response;
133
+ response.dataset = dataset.AsByteSpan ();
134
+ ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
168
135
}
169
136
170
- void ServerInstance::InvokeCommand (HandlerContext & ctx )
137
+ void ServerInstance::InvokeCommand (HandlerContext & ctxt )
171
138
{
172
- switch (ctx .mRequestPath .mCommandId )
139
+ switch (ctxt .mRequestPath .mCommandId )
173
140
{
174
141
case Commands::GetActiveDatasetRequest::Id:
175
- HandleCommand<Commands::GetActiveDatasetRequest::DecodableType>(
176
- ctx, [this ](HandlerContext & ctx, const auto & req) { HandleGetActiveDatasetRequest (ctx, req); });
142
+ HandleCommand<Commands::GetActiveDatasetRequest::DecodableType>(ctxt, [this ](HandlerContext & ctx, const auto & req) {
143
+ Thread::OperationalDataset dataset;
144
+ Status status = HandleGetActiveDatasetRequest (IsOverCASESession (ctx), dataset);
145
+ AddDatasetResponse (ctx, status, dataset);
146
+ });
177
147
break ;
178
148
case Commands::GetPendingDatasetRequest::Id:
179
- HandleCommand<Commands::GetPendingDatasetRequest::DecodableType>(
180
- ctx, [this ](HandlerContext & ctx, const auto & req) { HandleGetPendingDatasetRequest (ctx, req); });
149
+ HandleCommand<Commands::GetPendingDatasetRequest::DecodableType>(ctxt, [this ](HandlerContext & ctx, const auto & req) {
150
+ Thread::OperationalDataset dataset;
151
+ Status status = HandleGetPendingDatasetRequest (IsOverCASESession (ctx), dataset);
152
+ AddDatasetResponse (ctx, status, dataset);
153
+ });
181
154
break ;
182
155
case Commands::SetActiveDatasetRequest::Id:
183
- HandleCommand<Commands::SetActiveDatasetRequest::DecodableType>(
184
- ctx, [this ](HandlerContext & ctx, const auto & req) { HandleSetActiveDatasetRequest (ctx, req); });
156
+ HandleCommand<Commands::SetActiveDatasetRequest::DecodableType>(ctxt, [this ](HandlerContext & ctx, const auto & req) {
157
+ if (!mAsyncCommandHandle .Get ())
158
+ {
159
+ mPath = ctx.mRequestPath ;
160
+ mAsyncCommandHandle = CommandHandler::Handle (&ctx.mCommandHandler );
161
+ ctx.mCommandHandler .FlushAcksRightAwayOnSlowCommand ();
162
+ Status status = HandleSetActiveDatasetRequest (IsFailSafeArmed (ctx), req);
163
+ if (status != Status::Success)
164
+ {
165
+ OnActivateDatasetComplete (ChipError (ChipError::SdkPart::kIMGlobalStatus , to_underlying (status)));
166
+ }
167
+ }
168
+ else
169
+ {
170
+ ctx.mCommandHandler .AddStatus (ctx.mRequestPath , Status::Busy);
171
+ }
172
+ });
185
173
break ;
186
174
case Commands::SetPendingDatasetRequest::Id:
187
- HandleCommand<Commands::SetPendingDatasetRequest::DecodableType>(
188
- ctx, [this ](HandlerContext & ctx, const auto & req) { HandleSetPendingDatasetRequest (ctx, req); });
175
+ HandleCommand<Commands::SetPendingDatasetRequest::DecodableType>(ctxt, [this ](HandlerContext & ctx, const auto & req) {
176
+ ctx.mCommandHandler .AddStatus (ctx.mRequestPath , HandleSetPendingDatasetRequest (req));
177
+ });
189
178
break ;
190
179
default :
191
180
break ;
192
181
}
193
182
}
194
183
195
- CHIP_ERROR ServerInstance::ReadFeatureMap (AttributeValueEncoder & aEncoder )
184
+ CHIP_ERROR ServerInstance::ReadFeatureMap (BitFlags<Feature> & featureMap )
196
185
{
197
- BitFlags<Feature> featureMap;
198
186
bool panChangeSupported;
199
187
ReturnErrorOnFailure (mDelegate ->GetPanChangeSupported (panChangeSupported));
200
188
if (panChangeSupported)
201
189
{
202
190
featureMap.Set (Feature::kPANChange );
203
191
}
204
- return aEncoder. Encode (featureMap) ;
192
+ return CHIP_NO_ERROR ;
205
193
}
206
194
207
- CHIP_ERROR ServerInstance::ReadBorderRouterName (AttributeValueEncoder & aEncoder )
195
+ CHIP_ERROR ServerInstance::ReadBorderRouterName (MutableCharSpan & borderRouterName )
208
196
{
209
- char borderRouterName[kBorderRouterNameMaxLength ];
210
- MutableCharSpan borderRouterNameSpan (borderRouterName);
211
- ReturnErrorOnFailure (mDelegate ->GetBorderRouterName (borderRouterNameSpan));
212
- return aEncoder.Encode (borderRouterNameSpan);
197
+ ReturnErrorOnFailure (mDelegate ->GetBorderRouterName (borderRouterName));
198
+ ReturnErrorCodeIf (borderRouterName.size () > kBorderRouterNameMaxLength , CHIP_IM_GLOBAL_STATUS (ConstraintError));
199
+ return CHIP_NO_ERROR;
213
200
}
214
201
215
- CHIP_ERROR ServerInstance::ReadBorderAgentID (AttributeValueEncoder & aEncoder )
202
+ CHIP_ERROR ServerInstance::ReadBorderAgentID (MutableByteSpan & borderAgentId )
216
203
{
217
- uint8_t borderAgentId[kBorderAgentIdLength ];
218
- MutableByteSpan borderAgentIdSpan (borderAgentId);
219
- ReturnErrorOnFailure (mDelegate ->GetBorderAgentId (borderAgentIdSpan));
220
- return aEncoder.Encode (borderAgentIdSpan);
204
+ ReturnErrorOnFailure (mDelegate ->GetBorderAgentId (borderAgentId));
205
+ ReturnErrorCodeIf (borderAgentId.size () != kBorderAgentIdLength , CHIP_IM_GLOBAL_STATUS (ConstraintError));
206
+ return CHIP_NO_ERROR;
221
207
}
222
208
223
- CHIP_ERROR ServerInstance::ReadThreadVersion (AttributeValueEncoder & aEncoder )
209
+ CHIP_ERROR ServerInstance::ReadThreadVersion (uint16_t & threadVersion )
224
210
{
225
- uint16_t threadVersion;
226
- ReturnErrorOnFailure (mDelegate ->GetThreadVersion (threadVersion));
227
- return aEncoder.Encode (threadVersion);
211
+ return mDelegate ->GetThreadVersion (threadVersion);
228
212
}
229
213
230
- CHIP_ERROR ServerInstance::ReadInterfaceEnabled (AttributeValueEncoder & aEncoder )
214
+ CHIP_ERROR ServerInstance::ReadInterfaceEnabled (bool & interfaceEnabled )
231
215
{
232
- bool interfaceEnabled;
233
- ReturnErrorOnFailure (mDelegate ->GetInterfaceEnabled (interfaceEnabled));
234
- return aEncoder.Encode (interfaceEnabled);
216
+ return mDelegate ->GetInterfaceEnabled (interfaceEnabled);
235
217
}
236
218
237
- CHIP_ERROR ServerInstance::ReadActiveDatasetTimestamp (AttributeValueEncoder & aEncoder )
219
+ CHIP_ERROR ServerInstance::ReadActiveDatasetTimestamp (Optional< uint64_t > & activeDatasetTimestamp )
238
220
{
221
+ uint64_t activeDatasetTimestampValue;
239
222
Thread::OperationalDataset activeDataset;
240
- uint64_t activeDatasetTimestamp;
241
223
if (mDelegate ->GetDataset (activeDataset, Delegate::DatasetType::kActive ) == CHIP_NO_ERROR &&
242
- activeDataset.GetActiveTimestamp (activeDatasetTimestamp ) == CHIP_NO_ERROR)
224
+ activeDataset.GetActiveTimestamp (activeDatasetTimestampValue ) == CHIP_NO_ERROR)
243
225
{
244
- return aEncoder. Encode ( DataModel::MakeNullable (activeDatasetTimestamp) );
226
+ activeDatasetTimestamp. SetValue (activeDatasetTimestampValue );
245
227
}
246
- return aEncoder.EncodeNull ();
228
+ else
229
+ {
230
+ activeDatasetTimestamp.ClearValue ();
231
+ }
232
+ return CHIP_NO_ERROR;
247
233
}
248
234
249
235
CHIP_ERROR ServerInstance::Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
@@ -260,24 +246,63 @@ CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, Attribu
260
246
CHIP_ERROR status = CHIP_NO_ERROR;
261
247
switch (aPath.mAttributeId )
262
248
{
263
- case Globals::Attributes::FeatureMap::Id:
264
- status = ReadFeatureMap (aEncoder);
249
+ case Globals::Attributes::FeatureMap::Id: {
250
+ BitFlags<Feature> featureMap;
251
+ status = ReadFeatureMap (featureMap);
252
+ if (status == CHIP_NO_ERROR)
253
+ {
254
+ status = aEncoder.Encode (featureMap);
255
+ }
265
256
break ;
266
- case Attributes::BorderRouterName::Id:
267
- status = ReadBorderRouterName (aEncoder);
257
+ }
258
+ case Attributes::BorderRouterName::Id: {
259
+ char borderRouterNameBuf[kBorderRouterNameMaxLength + 1 ];
260
+ MutableCharSpan borderRouterName (borderRouterNameBuf);
261
+ status = ReadBorderRouterName (borderRouterName);
262
+ if (status == CHIP_NO_ERROR)
263
+ {
264
+ status = aEncoder.Encode (borderRouterName);
265
+ }
268
266
break ;
269
- case Attributes::BorderAgentID::Id:
270
- status = ReadBorderAgentID (aEncoder);
267
+ }
268
+ case Attributes::BorderAgentID::Id: {
269
+ uint8_t borderAgentIDBuf[kBorderAgentIdLength ];
270
+ MutableByteSpan borderAgentID (borderAgentIDBuf);
271
+ status = ReadBorderAgentID (borderAgentID);
272
+ if (status == CHIP_NO_ERROR)
273
+ {
274
+ status = aEncoder.Encode (borderAgentID);
275
+ }
271
276
break ;
272
- case Attributes::ThreadVersion::Id:
273
- status = ReadThreadVersion (aEncoder);
277
+ }
278
+ case Attributes::ThreadVersion::Id: {
279
+ uint16_t threadVersion;
280
+ status = ReadThreadVersion (threadVersion);
281
+ if (status == CHIP_NO_ERROR)
282
+ {
283
+ status = aEncoder.Encode (threadVersion);
284
+ }
274
285
break ;
275
- case Attributes::InterfaceEnabled::Id:
276
- status = ReadInterfaceEnabled (aEncoder);
286
+ }
287
+ case Attributes::InterfaceEnabled::Id: {
288
+ bool interfaceEnabled;
289
+ status = ReadInterfaceEnabled (interfaceEnabled);
290
+ if (status == CHIP_NO_ERROR)
291
+ {
292
+ status = aEncoder.Encode (interfaceEnabled);
293
+ }
277
294
break ;
278
- case Attributes::ActiveDatasetTimestamp::Id:
279
- status = ReadActiveDatasetTimestamp (aEncoder);
295
+ }
296
+ case Attributes::ActiveDatasetTimestamp::Id: {
297
+ Optional<uint64_t > activeDatasetTimestamp;
298
+ status = ReadActiveDatasetTimestamp (activeDatasetTimestamp);
299
+ if (status == CHIP_NO_ERROR)
300
+ {
301
+ status = activeDatasetTimestamp.HasValue () ? aEncoder.Encode (DataModel::MakeNullable (activeDatasetTimestamp.Value ()))
302
+ : aEncoder.EncodeNull ();
303
+ }
280
304
break ;
305
+ }
281
306
default :
282
307
break ;
283
308
}
0 commit comments