| /* |
| * |
| * Copyright (c) 2016-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 a derived unsolicited responder |
| * (i.e., server) for the Weave Service Directory profile used |
| * for the Weave mock device command line functional testing |
| * tool. |
| * |
| */ |
| |
| #define __STDC_FORMAT_MACROS |
| |
| #include "MockSDServer.h" |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Core/WeaveTLV.h> |
| #include <Weave/Support/CodeUtils.h> |
| #include <Weave/Core/WeaveEncoding.h> |
| #include <Weave/Core/WeaveServerBase.h> |
| #include <Weave/Profiles/WeaveProfiles.h> |
| #include <Weave/Profiles/common/CommonProfile.h> |
| |
| using namespace nl::Weave; |
| using namespace nl::Weave::TLV; |
| using namespace nl::Weave::Profiles; |
| using namespace nl::Weave::Encoding; |
| using namespace nl::Weave::Profiles::ServiceDirectory; |
| |
| MockServiceDirServer::MockServiceDirServer() |
| { |
| mExchangeMgr = NULL; |
| } |
| |
| WEAVE_ERROR MockServiceDirServer::Init(WeaveExchangeManager *exchangeMgr) |
| { |
| mExchangeMgr = exchangeMgr; |
| |
| WEAVE_ERROR err = mExchangeMgr->RegisterUnsolicitedMessageHandler(kWeaveProfile_ServiceDirectory, |
| HandleServiceDirRequest, this); |
| |
| return err; |
| } |
| |
| WEAVE_ERROR MockServiceDirServer::TearDown(void) |
| { |
| return mExchangeMgr->UnregisterUnsolicitedMessageHandler(kWeaveProfile_ServiceDirectory); |
| } |
| |
| void MockServiceDirServer::HandleServiceDirRequest(ExchangeContext *ec, const IPPacketInfo *packetInfo, |
| const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payloadReceiveInit) |
| { |
| WEAVE_ERROR err = WEAVE_NO_ERROR; |
| const char *host; |
| uint16_t hostLen, port; |
| const char *DirectoryServerURL = "192.168.100.3"; // mock service address in Happy |
| uint8_t *buf; |
| |
| PacketBuffer *payload = PacketBuffer::New(); |
| VerifyOrExit(payload != NULL, err = WEAVE_ERROR_NO_MEMORY); |
| buf = payload->Start(); |
| |
| VerifyOrExit((profileId == kWeaveProfile_ServiceDirectory) && |
| (msgType == kMsgType_ServiceEndpointQuery), err = WEAVE_ERROR_INVALID_MESSAGE_TYPE); |
| |
| err = ParseHostAndPort(DirectoryServerURL, strlen(DirectoryServerURL), host, hostLen, port); |
| port = WEAVE_PORT; |
| |
| // generate a simulate service directory response |
| Write8(buf, 0x62); // directory length = 2 - suffix table and time fields |
| |
| Write8(buf, 0x41); // host/port list length 1 - entry type host/port list |
| LittleEndian::Write64(buf, 0x18B4300200000002ULL); // Software Update Profile Endpoint Id |
| Write8(buf, 0x0d); // hostid type composite - suffix and port id present |
| Write8(buf, hostLen); |
| memcpy(buf, host, hostLen); buf += hostLen; |
| Write8(buf, 0x00); // suffix id 0 |
| LittleEndian::Write16(buf, port); |
| |
| Write8(buf, 0x41); // host/port list length 1 - entry type host/port list |
| LittleEndian::Write64(buf, 0x18B4300200000001ULL); // Directory Service Endpoint Id |
| Write8(buf, 0x0d); // hostid type composite - suffix and port id present |
| Write8(buf, hostLen); |
| memcpy(buf, host, hostLen); buf += hostLen; |
| Write8(buf, 0x01); // suffix id 1 |
| LittleEndian::Write16(buf, port); |
| |
| Write8(buf, 0x02); // suffix table length 1 |
| Write8(buf, 0x00); // suffix 0 length |
| Write8(buf, 0x00); // suffix 1 length |
| LittleEndian::Write32(buf, 0x00000001); // time field |
| |
| payload->SetDataLength(36 + 2 * hostLen); |
| err = ec->SendMessage(kWeaveProfile_ServiceDirectory, kMsgType_ServiceEndpointResponse, payload, 0); |
| payload = NULL; |
| SuccessOrExit(err); |
| |
| exit: |
| if (err == WEAVE_ERROR_INVALID_MESSAGE_TYPE) |
| { |
| printf("MockSDServer: sending Common:UnsupportedMessage\n"); |
| err = nl::Weave::WeaveServerBase::SendStatusReport(ec, |
| nl::Weave::Profiles::kWeaveProfile_Common, |
| nl::Weave::Profiles::Common::kStatus_UnsupportedMessage, |
| WEAVE_NO_ERROR, |
| ec->HasPeerRequestedAck() ? nl::Weave::ExchangeContext::kSendFlag_RequestAck : 0); |
| } |
| if (payloadReceiveInit) |
| { |
| PacketBuffer::Free(payloadReceiveInit); |
| payloadReceiveInit = NULL; |
| } |
| if (payload) |
| { |
| PacketBuffer::Free(payload); |
| payload = NULL; |
| } |
| ec->Close(); |
| return; |
| } |