| /* |
| * |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * This file implements objects for a Weave Service Provisioning |
| * profile unsolicited responder (server). |
| * |
| */ |
| |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Core/WeaveTLV.h> |
| #include <Weave/Support/CodeUtils.h> |
| #include <Weave/Core/WeaveEncoding.h> |
| #include <Weave/Profiles/WeaveProfiles.h> |
| #include "ServiceProvisioning.h" |
| #include <Weave/Profiles/common/CommonProfile.h> |
| |
| namespace nl { |
| namespace Weave { |
| namespace Profiles { |
| namespace ServiceProvisioning { |
| |
| using namespace nl::Weave::Encoding; |
| using namespace nl::Weave::TLV; |
| |
| ServiceProvisioningServer::ServiceProvisioningServer() |
| { |
| FabricState = NULL; |
| ExchangeMgr = NULL; |
| mDelegate = NULL; |
| mCurClientOp = NULL; |
| mCurClientOpBuf = NULL; |
| mCurServerOp = NULL; |
| mServerOpState = kServerOpState_Idle; |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::Init(WeaveExchangeManager *exchangeMgr) |
| { |
| FabricState = exchangeMgr->FabricState; |
| ExchangeMgr = exchangeMgr; |
| mDelegate = NULL; |
| mCurClientOp = NULL; |
| mCurClientOpBuf = NULL; |
| mCurServerOp = NULL; |
| mServerOpState = kServerOpState_Idle; |
| |
| // Register to receive unsolicited Service Provisioning messages from the exchange manager. |
| WEAVE_ERROR err = |
| ExchangeMgr->RegisterUnsolicitedMessageHandler(kWeaveProfile_ServiceProvisioning, HandleClientRequest, this); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::Shutdown() |
| { |
| if (ExchangeMgr != NULL) |
| ExchangeMgr->UnregisterUnsolicitedMessageHandler(kWeaveProfile_ServiceProvisioning); |
| |
| if (mCurClientOpBuf != NULL) |
| PacketBuffer::Free(mCurClientOpBuf); |
| |
| FabricState = NULL; |
| ExchangeMgr = NULL; |
| mDelegate = NULL; |
| mCurClientOp = NULL; |
| mCurClientOpBuf = NULL; |
| mCurServerOp = NULL; |
| mServerOpState = kServerOpState_Idle; |
| |
| return WEAVE_NO_ERROR; |
| } |
| |
| void ServiceProvisioningServer::SetDelegate(ServiceProvisioningDelegate *delegate) |
| { |
| mDelegate = delegate; |
| } |
| |
| ServiceProvisioningDelegate* ServiceProvisioningServer::GetDelegate(void) const |
| { |
| return mDelegate; |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::SendSuccessResponse() |
| { |
| return SendStatusReport(kWeaveProfile_Common, Common::kStatus_Success); |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::SendStatusReport(uint32_t statusProfileId, uint16_t statusCode, WEAVE_ERROR sysError) |
| { |
| WEAVE_ERROR err; |
| |
| VerifyOrExit(mCurClientOp != NULL, err = WEAVE_ERROR_INCORRECT_STATE); |
| |
| err = WeaveServerBase::SendStatusReport(mCurClientOp, statusProfileId, statusCode, sysError); |
| |
| exit: |
| mServerOpState = kServerOpState_Idle; |
| |
| if (mCurClientOp != NULL) |
| { |
| mCurClientOp->Close(); |
| mCurClientOp = NULL; |
| } |
| |
| if (mCurClientOpBuf != NULL) |
| { |
| PacketBuffer::Free(mCurClientOpBuf); |
| mCurClientOpBuf = NULL; |
| } |
| |
| return err; |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::SendPairDeviceToAccountRequest(WeaveConnection *serverCon, uint64_t serviceId, uint64_t fabricId, |
| const char *accountId, uint16_t accountIdLen, |
| const uint8_t *pairingToken, uint16_t pairingTokenLen, |
| const uint8_t *pairingInitData, uint16_t pairingInitDataLen, |
| const uint8_t *deviceInitData, uint16_t deviceInitDataLen) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| PairDeviceToAccountMessage msg; |
| PacketBuffer* msgBuf = NULL; |
| uint16_t msgLen = sizeof(accountIdLen) + sizeof(pairingTokenLen) + sizeof(pairingInitDataLen) + sizeof(deviceInitDataLen) + |
| sizeof(serviceId) + sizeof(fabricId) + accountIdLen + pairingTokenLen + pairingInitDataLen + deviceInitDataLen; |
| |
| if (mServerOpState != kServerOpState_Idle) |
| return WEAVE_ERROR_INCORRECT_STATE; |
| |
| msg.ServiceId = serviceId; |
| msg.FabricId = fabricId; |
| msg.AccountId = accountId; |
| msg.AccountIdLen = accountIdLen; |
| msg.PairingToken = pairingToken; |
| msg.PairingTokenLen = pairingTokenLen; |
| msg.PairingInitData = pairingInitData; |
| msg.PairingInitDataLen = pairingInitDataLen; |
| msg.DeviceInitData = deviceInitData; |
| msg.DeviceInitDataLen = deviceInitDataLen; |
| |
| // Allocate a buffer for the message. |
| msgBuf = PacketBuffer::NewWithAvailableSize(msgLen); |
| VerifyOrExit(msgBuf != NULL, err = WEAVE_ERROR_NO_MEMORY); |
| |
| // Encode the message. |
| err = msg.Encode(msgBuf); |
| SuccessOrExit(err); |
| |
| // Allocate and initialize an exchange context. |
| mCurServerOp = ExchangeMgr->NewContext(serverCon, this); |
| VerifyOrExit(mCurServerOp != NULL, err = WEAVE_ERROR_NO_MEMORY); |
| |
| mCurServerOp->OnMessageReceived = HandleServerResponse; |
| |
| if (mCurServerOp->ResponseTimeout == 0) |
| { |
| mCurServerOp->ResponseTimeout = WEAVE_CONFIG_SERVICE_PROV_RESPONSE_TIMEOUT; |
| } |
| mCurServerOp->OnResponseTimeout = HandleServerResponseTimeout; |
| mCurServerOp->OnConnectionClosed = HandleServerConnectionClosed; |
| mCurServerOp->OnKeyError = HandleServerKeyError; |
| |
| // Record that a PairDeviceToAccount request is outstanding. |
| mServerOpState = kServerOpState_PairDeviceToAccount; |
| |
| // Send the PairDeviceToAccount message to the service. |
| err = mCurServerOp->SendMessage(kWeaveProfile_ServiceProvisioning, kMsgType_PairDeviceToAccount, msgBuf, 0); |
| msgBuf = NULL; |
| |
| exit: |
| if (msgBuf != NULL) |
| PacketBuffer::Free(msgBuf); |
| if (err != WEAVE_NO_ERROR) |
| { |
| if (mCurServerOp != NULL) |
| { |
| mCurServerOp->Close(); |
| mCurServerOp = NULL; |
| } |
| mServerOpState = kServerOpState_Idle; |
| } |
| return err; |
| } |
| |
| WEAVE_ERROR ServiceProvisioningServer::SendPairDeviceToAccountRequest(Binding *binding, uint64_t serviceId, uint64_t fabricId, |
| const char *accountId, uint16_t accountIdLen, |
| const uint8_t *pairingToken, uint16_t pairingTokenLen, |
| const uint8_t *pairingInitData, uint16_t pairingInitDataLen, |
| const uint8_t *deviceInitData, uint16_t deviceInitDataLen) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| PairDeviceToAccountMessage msg; |
| PacketBuffer* msgBuf = NULL; |
| uint16_t flags = 0; |
| uint16_t msgLen = sizeof(accountIdLen) + sizeof(pairingTokenLen) + sizeof(pairingInitDataLen) + sizeof(deviceInitDataLen) + |
| sizeof(serviceId) + sizeof(fabricId) + accountIdLen + pairingTokenLen + pairingInitDataLen + deviceInitDataLen; |
| |
| if (mServerOpState != kServerOpState_Idle) |
| return WEAVE_ERROR_INCORRECT_STATE; |
| |
| msg.ServiceId = serviceId; |
| msg.FabricId = fabricId; |
| msg.AccountId = accountId; |
| msg.AccountIdLen = accountIdLen; |
| msg.PairingToken = pairingToken; |
| msg.PairingTokenLen = pairingTokenLen; |
| msg.PairingInitData = pairingInitData; |
| msg.PairingInitDataLen = pairingInitDataLen; |
| msg.DeviceInitData = deviceInitData; |
| msg.DeviceInitDataLen = deviceInitDataLen; |
| |
| // Allocate a buffer for the message. |
| msgBuf = PacketBuffer::NewWithAvailableSize(msgLen); |
| VerifyOrExit(msgBuf != NULL, err = WEAVE_ERROR_NO_MEMORY); |
| |
| // Encode the message. |
| err = msg.Encode(msgBuf); |
| SuccessOrExit(err); |
| |
| // Allocate and initialize an exchange context. |
| err = binding->NewExchangeContext(mCurServerOp); |
| SuccessOrExit(err); |
| |
| mCurServerOp->AppState = this; |
| mCurServerOp->OnMessageReceived = HandleServerResponse; |
| |
| if (mCurServerOp->ResponseTimeout == 0) |
| { |
| mCurServerOp->ResponseTimeout = WEAVE_CONFIG_SERVICE_PROV_RESPONSE_TIMEOUT; |
| } |
| mCurServerOp->OnResponseTimeout = HandleServerResponseTimeout; |
| mCurServerOp->OnConnectionClosed = HandleServerConnectionClosed; |
| mCurServerOp->OnKeyError = HandleServerKeyError; |
| |
| #if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING |
| mCurServerOp->OnSendError = HandleServerSendError; |
| #endif // #if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING |
| |
| // Record that a PairDeviceToAccount request is outstanding. |
| mServerOpState = kServerOpState_PairDeviceToAccount; |
| |
| // TODO: [TT] Not needed for Jay's new bindings WEAV-1870. |
| flags = (mCurServerOp->Con == NULL) ? ExchangeContext::kSendFlag_RequestAck : 0; |
| |
| // Send the PairDeviceToAccount message to the service. |
| err = mCurServerOp->SendMessage(kWeaveProfile_ServiceProvisioning, kMsgType_PairDeviceToAccount, msgBuf, flags); |
| msgBuf = NULL; |
| |
| exit: |
| if (msgBuf != NULL) |
| PacketBuffer::Free(msgBuf); |
| if (err != WEAVE_NO_ERROR) |
| { |
| mServerOpState = kServerOpState_Idle; |
| if (mCurServerOp != NULL) |
| { |
| mCurServerOp->Close(); |
| mCurServerOp = NULL; |
| } |
| } |
| return err; |
| } |
| |
| void ServiceProvisioningServer::HandleClientRequest(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, |
| uint32_t profileId, uint8_t msgType, PacketBuffer *payload) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| ServiceProvisioningDelegate *delegate = server->mDelegate; |
| uint16_t dataLen = payload->DataLength(); |
| uint8_t *p = payload->Start(); |
| |
| // Fail messages for the wrong profile. This shouldn't happen, but better safe than sorry. |
| if (profileId != kWeaveProfile_ServiceProvisioning) |
| { |
| WeaveServerBase::SendStatusReport(ec, kWeaveProfile_Common, Common::kStatus_BadRequest, WEAVE_NO_ERROR); |
| ec->Close(); |
| goto exit; |
| } |
| |
| // Call on the delegate to enforce message-level access control. If policy dictates the message should NOT |
| // be processed, then simply end the exchange and return. If an error response was warranted, the appropriate |
| // response will have been sent within EnforceAccessControl(). |
| if (!server->EnforceAccessControl(ec, profileId, msgType, msgInfo, server->mDelegate)) |
| { |
| ec->Close(); |
| ExitNow(); |
| } |
| |
| // Disallow simultaneous requests. |
| if (server->mCurClientOp != NULL) |
| { |
| WeaveServerBase::SendStatusReport(ec, kWeaveProfile_Common, Common::kStatus_Busy, WEAVE_NO_ERROR); |
| ec->Close(); |
| goto exit; |
| } |
| |
| // Record that we have a request in process. |
| server->mCurClientOp = ec; |
| |
| // Decode and dispatch the message. |
| switch (msgType) |
| { |
| case kMsgType_RegisterServicePairAccount: |
| |
| err = RegisterServicePairAccountMessage::Decode(payload, server->mCurClientOpMsg.RegisterServicePairAccount); |
| SuccessOrExit(err); |
| |
| server->mCurClientOpBuf = payload; |
| payload = NULL; |
| |
| err = delegate->HandleRegisterServicePairAccount(server->mCurClientOpMsg.RegisterServicePairAccount); |
| SuccessOrExit(err); |
| |
| break; |
| |
| case kMsgType_UpdateService: |
| err = UpdateServiceMessage::Decode(payload, server->mCurClientOpMsg.UpdateService); |
| SuccessOrExit(err); |
| |
| server->mCurClientOpBuf = payload; |
| payload = NULL; |
| |
| err = delegate->HandleUpdateService(server->mCurClientOpMsg.UpdateService); |
| SuccessOrExit(err); |
| |
| break; |
| |
| case kMsgType_UnregisterService: |
| { |
| uint64_t serviceId; |
| |
| VerifyOrExit(dataLen == 8, err = WEAVE_ERROR_INVALID_MESSAGE_LENGTH); |
| serviceId = LittleEndian::Get64(p); |
| |
| err = delegate->HandleUnregisterService(serviceId); |
| SuccessOrExit(err); |
| |
| break; |
| } |
| |
| default: |
| server->SendStatusReport(kWeaveProfile_Common, Common::kStatus_BadRequest); |
| break; |
| } |
| |
| exit: |
| |
| if (payload != NULL) |
| PacketBuffer::Free(payload); |
| |
| if (err != WEAVE_NO_ERROR && server->mCurClientOp != NULL && ec == server->mCurClientOp) |
| { |
| uint16_t statusCode = (err == WEAVE_ERROR_INVALID_MESSAGE_LENGTH) |
| ? Common::kStatus_BadRequest |
| : Common::kStatus_InternalError; |
| server->SendStatusReport(kWeaveProfile_Common, statusCode, err); |
| } |
| } |
| |
| void ServiceProvisioningServer::HandleServerResponse(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, |
| uint32_t profileId, uint8_t msgType, PacketBuffer *payload) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| WEAVE_ERROR delegateErr = WEAVE_NO_ERROR; |
| StatusReport statusReport; |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| |
| // Sanity check that the passed-in exchange context is in fact the one that represents the current |
| // outstanding server operation. If not, it'll get closed at exit. If it does match, we'll null ec |
| // to prevent it from getting closed at exit. |
| VerifyOrExit(ec == server->mCurServerOp, err = WEAVE_NO_ERROR); |
| ec = NULL; |
| |
| // Verify the message is expected. |
| VerifyOrExit((profileId == kWeaveProfile_Common && msgType == nl::Weave::Profiles::Common::kMsgType_StatusReport) || |
| (profileId == kWeaveProfile_StatusReport_Deprecated), |
| err = WEAVE_ERROR_INVALID_MESSAGE_TYPE); |
| |
| err = StatusReport::parse(payload, statusReport); |
| SuccessOrExit(err); |
| |
| // Free the payload here to reduce buffer pressure. |
| PacketBuffer::Free(payload); |
| payload = NULL; |
| |
| delegateErr = (statusReport.mProfileId == kWeaveProfile_Common && statusReport.mStatusCode == Common::kStatus_Success) |
| ? WEAVE_NO_ERROR |
| : WEAVE_ERROR_STATUS_REPORT_RECEIVED; |
| |
| server->HandlePairDeviceToAccountResult(delegateErr, statusReport.mProfileId, statusReport.mStatusCode); |
| |
| exit: |
| // Free the payload first to reduce buffer pressure. |
| if (payload != NULL) |
| PacketBuffer::Free(payload); |
| if (err != WEAVE_NO_ERROR) |
| server->HandlePairDeviceToAccountResult(err, 0, 0); |
| if (ec != NULL) |
| ec->Close(); |
| } |
| |
| void ServiceProvisioningServer::HandleServerResponseTimeout(ExchangeContext *ec) |
| { |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| |
| // Sanity check that the passed-in exchange context is in fact the one that represents the current |
| // outstanding server operation. If not, it'll get closed at exit. If it does match, we'll null ec |
| // to prevent it from getting closed at exit. |
| VerifyOrExit(ec == server->mCurServerOp, ); |
| ec = NULL; |
| |
| server->HandlePairDeviceToAccountResult(WEAVE_ERROR_TIMEOUT, 0, 0); |
| |
| exit: |
| if (ec != NULL) |
| ec->Close(); |
| } |
| |
| void ServiceProvisioningServer::HandleServerConnectionClosed(ExchangeContext *ec, WeaveConnection *con, WEAVE_ERROR conErr) |
| { |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| |
| // Sanity check that the passed-in exchange context is in fact the one that represents the current |
| // outstanding server operation. If not, it'll get closed at exit. If it does match, we'll null ec |
| // to prevent it from getting closed at exit. |
| VerifyOrExit(ec == server->mCurServerOp, ); |
| ec = NULL; |
| |
| // No error on connection close means the service simply closed the connection without responding. In that case |
| // deliver WEAVE_ERROR_CONNECTION_CLOSED_UNEXPECTEDLY to the delegate. |
| if (conErr == WEAVE_NO_ERROR) |
| conErr = WEAVE_ERROR_CONNECTION_CLOSED_UNEXPECTEDLY; |
| |
| server->HandlePairDeviceToAccountResult(conErr, 0, 0); |
| |
| exit: |
| if (ec != NULL) |
| ec->Close(); |
| } |
| |
| void ServiceProvisioningServer::HandleServerKeyError(ExchangeContext *ec, WEAVE_ERROR keyErr) |
| { |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| |
| // Sanity check that the passed-in exchange context is in fact the one that represents the current |
| // outstanding server operation. If not, it'll get closed at exit. If it does match, we'll null ec |
| // to prevent it from getting closed at exit. |
| VerifyOrExit(ec == server->mCurServerOp, ); |
| ec = NULL; |
| |
| server->HandlePairDeviceToAccountResult(keyErr, 0, 0); |
| |
| exit: |
| if (ec != NULL) |
| ec->Close(); |
| } |
| |
| #if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING |
| void ServiceProvisioningServer::HandleServerSendError(ExchangeContext *ec, WEAVE_ERROR err, void *msgCtxt) |
| { |
| ServiceProvisioningServer *server = (ServiceProvisioningServer *) ec->AppState; |
| |
| // Sanity check that the passed-in exchange context is in fact the one that represents the current |
| // outstanding server operation. If not, it'll get closed at exit. If it does match, we'll null ec |
| // to prevent it from getting closed at exit. |
| VerifyOrExit(ec == server->mCurServerOp, ); |
| ec = NULL; |
| |
| server->HandlePairDeviceToAccountResult(err, 0, 0); |
| |
| exit: |
| if (ec != NULL) |
| ec->Close(); |
| } |
| #endif // #if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING |
| |
| void ServiceProvisioningServer::HandlePairDeviceToAccountResult(WEAVE_ERROR localErr, uint32_t serverStatusProfileId, uint16_t serverStatusCode) |
| { |
| mServerOpState = kServerOpState_Idle; |
| mCurServerOp->Close(); |
| mCurServerOp = NULL; |
| |
| if (mDelegate) |
| { |
| mDelegate->HandlePairDeviceToAccountResult(localErr, serverStatusProfileId, serverStatusCode); |
| } |
| } |
| |
| bool ServiceProvisioningServer::IsValidServiceConfig(const uint8_t *serviceConfig, uint16_t serviceConfigLen) |
| { |
| WEAVE_ERROR err; |
| nl::Weave::TLV::TLVReader reader; |
| |
| reader.Init(serviceConfig, serviceConfigLen); |
| |
| err = reader.Next(); |
| SuccessOrExit(err); |
| |
| VerifyOrExit(reader.GetTag() == ProfileTag(kWeaveProfile_ServiceProvisioning, kTag_ServiceConfig), err = WEAVE_ERROR_INVALID_TLV_TAG); |
| |
| { |
| TLVType topLevelContainer; |
| bool caCertsPresent = false, dirEndPointPresent = false; |
| |
| err = reader.EnterContainer(topLevelContainer); |
| SuccessOrExit(err); |
| |
| while ((err = reader.Next()) == WEAVE_NO_ERROR) |
| { |
| uint64_t elemTag = reader.GetTag(); |
| |
| if (!IsContextTag(elemTag)) |
| continue; |
| |
| switch (TagNumFromTag(elemTag)) |
| { |
| case kTag_ServiceConfig_CACerts: |
| VerifyOrExit(reader.GetType() == kTLVType_Array, err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| caCertsPresent = true; |
| break; |
| case kTag_ServiceConfig_DirectoryEndPoint: |
| VerifyOrExit(reader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_INVALID_TLV_ELEMENT); |
| dirEndPointPresent = true; |
| break; |
| default: |
| // Ignore unknown elements |
| break; |
| } |
| } |
| |
| if (err != WEAVE_END_OF_TLV) |
| ExitNow(); |
| |
| err = reader.ExitContainer(topLevelContainer); |
| SuccessOrExit(err); |
| |
| VerifyOrExit(caCertsPresent && dirEndPointPresent, err = WEAVE_ERROR_MISSING_TLV_ELEMENT); |
| } |
| |
| exit: |
| return err == WEAVE_NO_ERROR; |
| } |
| |
| void ServiceProvisioningDelegate::EnforceAccessControl(ExchangeContext *ec, uint32_t msgProfileId, uint8_t msgType, |
| const WeaveMessageInfo *msgInfo, AccessControlResult& result) |
| { |
| enum { kServiceProvisioningEndpointId = 0x18B4300200000010ull }; |
| |
| // If the result has not already been determined by a subclass... |
| if (result == kAccessControlResult_NotDetermined) |
| { |
| switch (msgType) |
| { |
| #if WEAVE_CONFIG_REQUIRE_AUTH_SERVICE_PROV |
| |
| case kMsgType_RegisterServicePairAccount: |
| if (msgInfo->PeerAuthMode == kWeaveAuthMode_PASE_PairingCode && !IsPairedToAccount()) |
| { |
| result = kAccessControlResult_Accepted; |
| } |
| break; |
| |
| case kMsgType_UpdateService: |
| if (msgInfo->PeerAuthMode == kWeaveAuthMode_CASE_AccessToken) |
| { |
| result = kAccessControlResult_Accepted; |
| } |
| break; |
| |
| case kMsgType_UnregisterService: |
| if (msgInfo->PeerAuthMode == kWeaveAuthMode_CASE_AccessToken || |
| (msgInfo->PeerAuthMode == kWeaveAuthMode_CASE_ServiceEndPoint && msgInfo->SourceNodeId == kServiceProvisioningEndpointId)) |
| { |
| result = kAccessControlResult_Accepted; |
| } |
| break; |
| |
| #else // WEAVE_CONFIG_REQUIRE_AUTH_SERVICE_PROV |
| |
| case kMsgType_RegisterServicePairAccount: |
| case kMsgType_UpdateService: |
| case kMsgType_UnregisterService: |
| result = kAccessControlResult_Accepted; |
| break; |
| |
| #endif // WEAVE_CONFIG_REQUIRE_AUTH_SERVICE_PROV |
| |
| default: |
| WeaveServerBase::SendStatusReport(ec, kWeaveProfile_Common, Common::kStatus_UnsupportedMessage, WEAVE_NO_ERROR); |
| result = kAccessControlResult_Rejected_RespSent; |
| break; |
| } |
| } |
| |
| // Call up to the base class. |
| WeaveServerDelegateBase::EnforceAccessControl(ec, msgProfileId, msgType, msgInfo, result); |
| } |
| |
| // TODO: eliminate this method when device code provides appropriate implementations. |
| bool ServiceProvisioningDelegate::IsPairedToAccount() const |
| { |
| return false; |
| } |
| |
| } // ServiceProvisioning |
| } // namespace Profiles |
| } // namespace Weave |
| } // namespace nl |