| /* |
| * |
| * 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 defines the Device Description profile, containing |
| * data semantics and methods to specify and query device specific |
| * characteristics that pertain to Weave. |
| * |
| * The Device Description profile is used to query device |
| * specific characteristics of Weave nodes via a client-server |
| * interface. This information is communicated via IdentifyRequest |
| * and IdentifyResponse message types, the former used to discover |
| * devices matching a filter, and the latter used to respond with a |
| * payload detailing some or all of the characteristics specific to that |
| * device. Such characteristics include the device vendor and |
| * make / model, as well as network information including MAC addresses |
| * and connections. |
| */ |
| |
| #ifndef DEVICEDESCRIPTION_H_ |
| #define DEVICEDESCRIPTION_H_ |
| |
| #include <Weave/Support/NLDLLUtil.h> |
| #include <Weave/Core/WeaveCore.h> |
| #include <Weave/Core/WeaveServerBase.h> |
| #include <Weave/Profiles/WeaveProfiles.h> |
| #include <Weave/Core/WeaveTLV.h> |
| |
| /** |
| * @namespace nl::Weave::Profiles::DeviceDescription |
| * |
| * @brief |
| * This namespace includes all interfaces within Weave for the |
| * Weave Device Description profile. |
| */ |
| |
| namespace nl { |
| namespace Weave { |
| namespace Profiles { |
| namespace DeviceDescription { |
| |
| |
| class IdentifyRequestMessage; |
| class IdentifyResponseMessage; |
| |
| /** |
| * Message Types for the Device Description Profile. |
| */ |
| enum |
| { |
| kMessageType_IdentifyRequest = 1, |
| kMessageType_IdentifyResponse = 2 |
| }; |
| |
| |
| /** |
| * Data Element Tags for the Device Description Profile. |
| */ |
| enum |
| { |
| /** |
| * Top-level Tags |
| */ |
| kTag_WeaveDeviceDescriptor = 1, /**< Structure containing information describing a Weave device. */ |
| |
| /** |
| * Context-specific Tags for WeaveDeviceDescriptor Structure |
| */ |
| kTag_VendorId = 0, /**< Code identifying product vendor. [ uint, range 1-65535 ] */ |
| kTag_ProductId = 1, /**< Code identifying product. [ uint, range 1-65535 ] */ |
| kTag_ProductRevision = 2, /**< Code identifying product revision. [ uint, range 1-65535 ] */ |
| kTag_ManufacturingDate = 3, /**< Calendar date of manufacture in encoded form. [ uint, range 1-65535 ] */ |
| kTag_SerialNumber = 4, /**< Device serial number. [ UTF-8 string, len 1-32 ] */ |
| kTag_Primary802154MACAddress = 5, /**< MAC address for device's primary 802.15.4 interface. [ byte string, len = 8 ] */ |
| kTag_PrimaryWiFiMACAddress = 6, /**< MAC address for device's primary WiFi interface. [ byte string, len = 6 ] */ |
| kTag_RendezvousWiFiESSID = 7, /**< ESSID for device's WiFi rendezvous network. [ UTF-8 string, len 1-32 ] */ |
| kTag_PairingCode = 8, /**< The pairing code for the device. [ UTF-8 string, len 1-16 ] */ |
| /**< @note @b IMPORTANT: For security reasons, the PairingCode field should *never* |
| * be sent over the network. It is present in a WeaveDeviceDescriptor structure so |
| * that is can encoded in a data label (e.g. QR-code) that is physically associated |
| * with the device. */ |
| kTag_SoftwareVersion = 9, /**< Version of software on the device. [ UTF-8 string, len 1-32 ] */ |
| kTag_DeviceId = 10, /**< Weave device ID. [ uint, 2^64 max ] */ |
| kTag_FabricId = 11, /**< ID of Weave fabric to which the device belongs. [ uint, 2^64 max ] */ |
| kTag_PairingCompatibilityVersionMajor = 12, /**< Pairing software compatibility major version. [ uint, range 1-65535 ] */ |
| kTag_PairingCompatibilityVersionMinor = 13, /**< Pairing software compatibility minor version. [ uint, range 1-65535 ] */ |
| |
| /** |
| * Feature Tags (Context-specific Tags in WeaveDeviceDescriptor that indicate presence of device features) |
| * |
| * NOTE: The absence of a specific tag indicates that the device does not support the associated feature. |
| */ |
| kTag_DeviceFeature_HomeAlarmLinkCapable = 100, /**< Indicates a Nest Protect that supports connection to a home alarm panel. [ boolean ] */ |
| kTag_DeviceFeature_LinePowered = 101 /**< Indicates a device that requires line power. [ boolean ] */ |
| }; |
| |
| |
| /** |
| * Contains descriptive information about a Weave device. |
| */ |
| class NL_DLL_EXPORT WeaveDeviceDescriptor |
| { |
| public: |
| WeaveDeviceDescriptor(void); |
| |
| /** |
| * Defines the maximum length of some attributes. |
| */ |
| enum |
| { |
| kMaxSerialNumberLength = 32, /**< Maximum serial number length. */ |
| kMaxPairingCodeLength = 16, /**< Maximum pairing code length. */ |
| kMaxRendezvousWiFiESSID = 32, /**< Maximum WiFi ESSID for Rendezvous length. */ |
| kMaxSoftwareVersionLength = 32 /**< Maximum software version length. */ |
| }; |
| |
| /** |
| * Flags indicating specific device capabilities. |
| */ |
| enum |
| { |
| kFeature_HomeAlarmLinkCapable = 0x00000001, /**< Indicates a Nest Protect that supports connection to a home alarm panel. */ |
| kFeature_LinePowered = 0x00000002 /**< Indicates a device that requires line power. */ |
| }; |
| |
| // Device specific characteristics |
| uint64_t DeviceId; /**< Weave device ID. (0 = not present) */ |
| uint64_t FabricId; /**< ID of Weave fabric to which the device belongs. (0 = not present) */ |
| uint32_t DeviceFeatures; /**< Bit field indicating support for specific device features. */ |
| uint16_t VendorId; /**< Device vendor code. (0 = not present) */ |
| uint16_t ProductId; /**< Device product code. (0 = not present) */ |
| uint16_t ProductRevision; /**< Device product revision. (0 = not present) */ |
| struct { |
| uint16_t Year; /**< Year of device manufacture. (valid range 2001 - 2099) */ |
| uint8_t Month; /**< Month of device manufacture. (1 = January) */ |
| uint8_t Day; /**< Day of device manufacture. (0 = not present) */ |
| } ManufacturingDate; |
| uint8_t Primary802154MACAddress[8]; /**< MAC address for primary 802.15.4 interface. (big-endian, all zeros = not present) */ |
| uint8_t PrimaryWiFiMACAddress[6]; /**< MAC address for primary WiFi interface. (big-endian, all zeros = not present) */ |
| char SerialNumber[kMaxSerialNumberLength+1]; /**< Serial number of device. (NUL terminated, 0 length = not present) */ |
| char SoftwareVersion[kMaxSoftwareVersionLength+1]; /**< Active software version. (NUL terminated, 0 length = not present) */ |
| char RendezvousWiFiESSID[kMaxRendezvousWiFiESSID+1]; /**< ESSID for pairing WiFi network. (NUL terminated, 0 length = not present) */ |
| char PairingCode[kMaxPairingCodeLength+1]; /**< Device pairing code. (NUL terminated, 0 length = not present) */ |
| uint16_t PairingCompatibilityVersionMajor; /**< Major device pairing software compatibility version. */ |
| uint16_t PairingCompatibilityVersionMinor; /**< Minor device pairing software compatibility version. */ |
| |
| void Clear(void); |
| |
| static WEAVE_ERROR EncodeText(const WeaveDeviceDescriptor& desc, char *buf, uint32_t bufLen, uint32_t& outEncodedLen); |
| static WEAVE_ERROR EncodeTLV(const WeaveDeviceDescriptor& desc, uint8_t *buf, uint32_t bufLen, uint32_t& outEncodedLen); |
| static WEAVE_ERROR EncodeTLV(const WeaveDeviceDescriptor& desc, nl::Weave::TLV::TLVWriter& writer); |
| static WEAVE_ERROR Decode(const uint8_t *data, uint32_t dataLen, WeaveDeviceDescriptor& outDesc); |
| static WEAVE_ERROR DecodeText(const char *data, uint32_t dataLen, WeaveDeviceDescriptor& outDesc); |
| static WEAVE_ERROR DecodeTLV(const uint8_t *data, uint32_t dataLen, WeaveDeviceDescriptor& outDesc); |
| static WEAVE_ERROR DecodeTLV(nl::Weave::TLV::TLVReader& reader, WeaveDeviceDescriptor& outDesc); |
| static bool IsZeroBytes(const uint8_t *buf, uint32_t len); |
| |
| private: |
| static WEAVE_ERROR EncodeManufacturingDate(uint16_t year, uint8_t month, uint8_t day, uint16_t& outEncodedDate); |
| static WEAVE_ERROR DecodeManufacturingDate(uint16_t encodedDate, uint16_t& outYear, uint8_t& outMonth, uint8_t& outDay); |
| }; |
| |
| |
| /** |
| * Client object for issuing Device Description requests. |
| */ |
| class DeviceDescriptionClient |
| { |
| public: |
| DeviceDescriptionClient(void); |
| |
| /** |
| * Application defined state object. |
| */ |
| void *AppState; |
| |
| const WeaveFabricState *FabricState; /**< [READ ONLY] Fabric state object */ |
| WeaveExchangeManager *ExchangeMgr; /**< [READ ONLY] Exchange manager object */ |
| |
| WEAVE_ERROR Init(WeaveExchangeManager *exchangeMgr); |
| WEAVE_ERROR Shutdown(void); |
| |
| WEAVE_ERROR SendIdentifyRequest(const IPAddress& nodeAddr, const IdentifyRequestMessage& msg); |
| WEAVE_ERROR SendIdentifyRequest(const IdentifyRequestMessage& msg); |
| WEAVE_ERROR CancelExchange(void); |
| |
| /** |
| * This function is responsible for processing IdentityResponse messages. |
| * |
| * @param[in] appState A pointer to the application defined state set when creating the |
| * IdentityRequest Exchange Context. |
| * @param[in] nodeId The Weave node ID of the message source. |
| * @param[in] nodeAddr The IP address of the responding node. |
| * @param[in] msg A reference to the incoming IdentifyResponse message. |
| * |
| */ |
| typedef void (*HandleIdentifyResponseFunct)(void *appState, uint64_t nodeId, const IPAddress& nodeAddr, const IdentifyResponseMessage& msg); |
| HandleIdentifyResponseFunct OnIdentifyResponseReceived; |
| |
| private: |
| ExchangeContext *ExchangeCtx; |
| |
| static void HandleResponse(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payload); |
| |
| DeviceDescriptionClient(const DeviceDescriptionClient&); // not defined |
| }; |
| |
| |
| /** |
| * Server object for responding to Device Description requests. |
| */ |
| class NL_DLL_EXPORT DeviceDescriptionServer : public WeaveServerBase |
| { |
| public: |
| DeviceDescriptionServer(void); |
| |
| void *AppState; /**< Application defined state pointer to provide context for callbacks. */ |
| |
| WEAVE_ERROR Init(WeaveExchangeManager *exchangeMgr); |
| WEAVE_ERROR Shutdown(void); |
| |
| typedef void (*HandleIdentifyRequestFunct)(void *appState, uint64_t nodeId, const IPAddress& nodeAddr, const IdentifyRequestMessage& reqMsg, bool& sendResp, IdentifyResponseMessage& respMsg); |
| |
| /** |
| * This function is responsible for processing IdentityRequest messages. |
| * |
| * @param[in] appState A pointer to the application defined state set when registering |
| * to receive messages of this type. |
| * @param[in] nodeId The Weave node ID of the message source. |
| * @param[in] nodeAddr The IP address of the message source. |
| * @param[in] reqMsg A reference to the incoming IdentifyRequest message. |
| * @param[out] sendResp A reference to a boolean that should be set to true if a response message should be sent to the initiator. |
| * @param[out] respMsg A reference to the IdentifyResponse message to be sent to the initiator. |
| * |
| */ |
| HandleIdentifyRequestFunct OnIdentifyRequestReceived; |
| |
| private: |
| static void HandleRequest(ExchangeContext *ec, const IPPacketInfo *pktInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payload); |
| |
| DeviceDescriptionServer(const DeviceDescriptionServer&); // not defined |
| }; |
| |
| |
| /** |
| * Special target fabric IDs. |
| */ |
| enum TargetFabricIds |
| { |
| kTargetFabricId_NotInFabric = kFabricIdNotSpecified, /**< Specifies that only devices that are __not__ a member of a fabric should respond. */ |
| kTargetFabricId_AnyFabric = kReservedFabricIdStart, /**< Specifies that only devices that __are_ a member of a fabric should respond. */ |
| kTargetFabricId_Any = kMaxFabricId, /**< Specifies that all devices should respond regardless of fabric membership. */ |
| }; |
| |
| extern bool MatchTargetFabricId(uint64_t fabricId, uint64_t targetFabricId); |
| |
| /** |
| * Bit field (32-bits max) identifying which devices should respond |
| * to a LocateRequest Message based on their current mode. |
| * |
| * Note that the modes defined here are intended to be general such that they can be |
| * applied to a variety of device types. |
| */ |
| enum TargetDeviceModes |
| { |
| kTargetDeviceMode_Any = 0x00000000, /**< Locate all devices regardless of mode. */ |
| |
| kTargetDeviceMode_UserSelectedMode = 0x00000001 /**< Locate all devices in 'user-selected' mode -- that is, where the device has |
| been directly identified by a user by pressing a button (or equivalent). */ |
| }; |
| |
| /** |
| * Represents criteria use to select devices in the IdentifyDevice protocol. |
| */ |
| class NL_DLL_EXPORT IdentifyDeviceCriteria |
| { |
| public: |
| /** |
| * Specifies that only devices that are members of the specified Weave fabric |
| * should respond. Value can be an actual fabric ID, or one of the |
| * #TargetFabricIds enum values. |
| */ |
| uint64_t TargetFabricId; |
| |
| /** |
| * Specifies that only devices that are currently in the specified modes |
| * should respond. Values are taken from the #TargetDeviceModes enum. |
| */ |
| uint32_t TargetModes; |
| |
| /** |
| * Specifies that only devices manufactured by the specified vendor should |
| * respond to the identify request. A value of 0xFFFF specifies any vendor. |
| */ |
| uint16_t TargetVendorId; |
| |
| /** |
| * Specifies that only devices with the specified product ID should respond. |
| * A value of 0xFFFF specifies any product. |
| * If the TargetProductId field is specified, then the TargetVendorId must |
| * also be specified. |
| */ |
| uint16_t TargetProductId; |
| |
| /** |
| * Specifies that only the device with the specified Weave Node ID should respond. |
| * A value of #kAnyNodeId specifies any device. |
| * |
| * @note The value of the TargetDeviceId field is carried a Weave IdentifyRequest |
| * in the Destination node ID field of the Weave message header, and thus |
| * does __not__ appear in the payload of the message. |
| */ |
| uint64_t TargetDeviceId; |
| |
| IdentifyDeviceCriteria(void); |
| |
| void Reset(void); |
| }; |
| |
| |
| /** |
| * Parsed form of an IdentifyRequest Message. |
| */ |
| class NL_DLL_EXPORT IdentifyRequestMessage : public IdentifyDeviceCriteria |
| { |
| public: |
| WEAVE_ERROR Encode(PacketBuffer *msgBuf) const; |
| static WEAVE_ERROR Decode(PacketBuffer *msgBuf, uint64_t msgDestNodeId, IdentifyRequestMessage& msg); |
| }; |
| |
| |
| /** |
| * Parsed form of an IdentifyResponse Message. |
| */ |
| class NL_DLL_EXPORT IdentifyResponseMessage |
| { |
| public: |
| WeaveDeviceDescriptor DeviceDesc; // A device descriptor describing the responding device. |
| |
| WEAVE_ERROR Encode(PacketBuffer *msgBuf); |
| static WEAVE_ERROR Decode(PacketBuffer *msgBuf, IdentifyResponseMessage& msg); |
| }; |
| |
| |
| } // namespace DeviceDescription |
| } // namespace Profiles |
| } // namespace Weave |
| } // namespace nl |
| |
| #endif // DEVICEDESCRIPTION_H_ |