blob: 59ee31204d5d77bd9108705e0696a80b89d0ccef [file] [log] [blame]
/*
*
* 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
* Objective-C representation of the DeviceDescription data communicated via device-description profile.
*
*/
#import "NLWeaveDeviceDescriptor_Protected.h"
#import <Weave/Profiles/device-description/DeviceDescription.h>
#import "NLLogging.h"
#include <Weave/Support/CodeUtils.h>
@implementation NLWeaveDeviceDescriptor
+ (instancetype)decodeDeviceDescriptor:(NSString *)descriptorStr
{
WDM_LOG_METHOD_SIG();
WEAVE_ERROR err;
WeaveDeviceDescriptor deviceDesc;
NSData *buffer = [descriptorStr dataUsingEncoding:NSUTF8StringEncoding];
err = WeaveDeviceDescriptor::Decode((const uint8_t *)buffer.bytes, (uint32_t)buffer.length, deviceDesc);
SuccessOrExit(err);
exit:
return [NLWeaveDeviceDescriptor createUsing:deviceDesc];
}
+ (NLWeaveDeviceDescriptor *)createUsing:(WeaveDeviceDescriptor)deviceDescriptor
{
return [[NLWeaveDeviceDescriptor alloc] initWith:deviceDescriptor];
}
- (id)initWith:(nl::Weave::Profiles::DeviceDescription::WeaveDeviceDescriptor)deviceDescriptor
{
if (self = [super init]) {
WDM_LOG_DEBUG(@"Creating new NLWeaveDeviceDescriptor using: ");
WDM_LOG_DEBUG(@"WeaveDeviceDescriptor: %@", [self debugDescriptionWithDeviceDescriptor:&deviceDescriptor]);
_DeviceId = [NSNumber numberWithUnsignedLongLong:deviceDescriptor.DeviceId];
_FabricId = [NSNumber numberWithUnsignedLongLong:deviceDescriptor.FabricId];
_DeviceFeatures = kNLDeviceFeatureNone;
if ((deviceDescriptor.DeviceFeatures & WeaveDeviceDescriptor::kFeature_LinePowered)
== WeaveDeviceDescriptor::kFeature_LinePowered) {
_DeviceFeatures |= kNLDeviceFeature_LinePowered;
}
_VendorId = deviceDescriptor.VendorId;
_ProductId = deviceDescriptor.ProductId;
_ProductRevision = deviceDescriptor.ProductRevision;
_ManufacturingDate.NLManufacturingDateMonth = deviceDescriptor.ManufacturingDate.Month;
_ManufacturingDate.NLManufacturingDateDay = deviceDescriptor.ManufacturingDate.Day;
_ManufacturingDate.NLManufacturingDateYear = deviceDescriptor.ManufacturingDate.Year;
if (!WeaveDeviceDescriptor::IsZeroBytes(
deviceDescriptor.Primary802154MACAddress, sizeof(deviceDescriptor.Primary802154MACAddress))) {
NSUInteger length
= sizeof(deviceDescriptor.Primary802154MACAddress) / sizeof(deviceDescriptor.Primary802154MACAddress[0]);
_Primary802154MACAddress = [[NSData alloc] initWithBytes:deviceDescriptor.Primary802154MACAddress length:length];
}
if (!WeaveDeviceDescriptor::IsZeroBytes(
deviceDescriptor.PrimaryWiFiMACAddress, sizeof(deviceDescriptor.PrimaryWiFiMACAddress))) {
NSUInteger length = sizeof(deviceDescriptor.PrimaryWiFiMACAddress) / sizeof(deviceDescriptor.PrimaryWiFiMACAddress[0]);
_PrimaryWiFiMACAddress = [[NSData alloc] initWithBytes:deviceDescriptor.PrimaryWiFiMACAddress length:length];
}
_SerialNumber = [[NSString alloc] initWithUTF8String:deviceDescriptor.SerialNumber];
_SoftwareVersion = [[NSString alloc] initWithUTF8String:deviceDescriptor.SoftwareVersion];
_RendezvousWiFiESSID = [[NSString alloc] initWithUTF8String:deviceDescriptor.RendezvousWiFiESSID];
_IsRendezvousWiFiESSIDSuffix = (deviceDescriptor.Flags & WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix)
== WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix;
_PairingCode = [[NSString alloc] initWithUTF8String:deviceDescriptor.PairingCode];
_PairingCompatibilityVersionMajor = deviceDescriptor.PairingCompatibilityVersionMajor;
_PairingCompatibilityVersionMinor = deviceDescriptor.PairingCompatibilityVersionMinor;
}
return self;
}
- (BOOL)requiresLinePower
{
if ((_DeviceFeatures & kNLDeviceFeature_LinePowered) == kNLDeviceFeature_LinePowered) {
return YES;
} else {
return NO;
}
}
#pragma mark - NSCoding, NSCopying
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self != nil) {
_DeviceId = [decoder decodeObjectForKey:NSStringFromSelector(@selector(DeviceId))];
_FabricId = [decoder decodeObjectForKey:NSStringFromSelector(@selector(FabricId))];
_DeviceFeatures = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(DeviceFeatures))];
_VendorId = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(VendorId))];
_ProductId = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(ProductId))];
_ProductRevision = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(ProductRevision))];
// Because encoding and decoding structs are a bit of a pain...
_ManufacturingDate.NLManufacturingDateYear = [decoder decodeIntegerForKey:@"NLManufacturingDateYear"];
_ManufacturingDate.NLManufacturingDateMonth = [decoder decodeIntegerForKey:@"NLManufacturingDateMonth"];
_ManufacturingDate.NLManufacturingDateDay = [decoder decodeIntegerForKey:@"NLManufacturingDateDay"];
_Primary802154MACAddress = [decoder decodeObjectForKey:NSStringFromSelector(@selector(Primary802154MACAddress))];
_PrimaryWiFiMACAddress = [decoder decodeObjectForKey:NSStringFromSelector(@selector(PrimaryWiFiMACAddress))];
_SerialNumber = [decoder decodeObjectForKey:NSStringFromSelector(@selector(SerialNumber))];
_SoftwareVersion = [decoder decodeObjectForKey:NSStringFromSelector(@selector(SoftwareVersion))];
_RendezvousWiFiESSID = [decoder decodeObjectForKey:NSStringFromSelector(@selector(RendezvousWiFiESSID))];
_IsRendezvousWiFiESSIDSuffix = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(IsRendezvousWiFiESSIDSuffix))];
_PairingCode = [decoder decodeObjectForKey:NSStringFromSelector(@selector(PairingCode))];
_PairingCompatibilityVersionMajor =
[decoder decodeIntegerForKey:NSStringFromSelector(@selector(PairingCompatibilityVersionMajor))];
_PairingCompatibilityVersionMinor =
[decoder decodeIntegerForKey:NSStringFromSelector(@selector(PairingCompatibilityVersionMinor))];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.DeviceId forKey:NSStringFromSelector(@selector(DeviceId))];
[coder encodeObject:self.FabricId forKey:NSStringFromSelector(@selector(FabricId))];
[coder encodeInteger:self.DeviceFeatures forKey:NSStringFromSelector(@selector(DeviceFeatures))];
[coder encodeInteger:self.VendorId forKey:NSStringFromSelector(@selector(VendorId))];
[coder encodeInteger:self.ProductId forKey:NSStringFromSelector(@selector(ProductId))];
[coder encodeInteger:self.ProductRevision forKey:NSStringFromSelector(@selector(ProductRevision))];
// Because encoding and decoding structs are a bit of a pain...
[coder encodeInteger:self.ManufacturingDate.NLManufacturingDateYear forKey:@"NLManufacturingDateYear"];
[coder encodeInteger:self.ManufacturingDate.NLManufacturingDateMonth forKey:@"NLManufacturingDateMonth"];
[coder encodeInteger:self.ManufacturingDate.NLManufacturingDateDay forKey:@"NLManufacturingDateDay"];
[coder encodeObject:self.Primary802154MACAddress forKey:NSStringFromSelector(@selector(Primary802154MACAddress))];
[coder encodeObject:self.PrimaryWiFiMACAddress forKey:NSStringFromSelector(@selector(PrimaryWiFiMACAddress))];
[coder encodeObject:self.SerialNumber forKey:NSStringFromSelector(@selector(SerialNumber))];
[coder encodeObject:self.SoftwareVersion forKey:NSStringFromSelector(@selector(SoftwareVersion))];
[coder encodeObject:self.RendezvousWiFiESSID forKey:NSStringFromSelector(@selector(RendezvousWiFiESSID))];
[coder encodeInteger:self.IsRendezvousWiFiESSIDSuffix forKey:NSStringFromSelector(@selector(IsRendezvousWiFiESSIDSuffix))];
[coder encodeObject:self.PairingCode forKey:NSStringFromSelector(@selector(PairingCode))];
[coder encodeInteger:self.PairingCompatibilityVersionMajor
forKey:NSStringFromSelector(@selector(PairingCompatibilityVersionMajor))];
[coder encodeInteger:self.PairingCompatibilityVersionMinor
forKey:NSStringFromSelector(@selector(PairingCompatibilityVersionMinor))];
}
- (id)copyWithZone:(NSZone *)zone
{
NLWeaveDeviceDescriptor * copy = [[[self class] allocWithZone:zone] init];
copy.DeviceId = [self.DeviceId copy];
copy.FabricId = [self.FabricId copy];
copy.DeviceFeatures = self.DeviceFeatures;
copy.VendorId = self.VendorId;
copy.ProductId = self.ProductId;
copy.ProductRevision = self.ProductRevision;
copy.ManufacturingDate = self.ManufacturingDate;
copy.Primary802154MACAddress = [self.Primary802154MACAddress copy];
copy.PrimaryWiFiMACAddress = [self.PrimaryWiFiMACAddress copy];
copy.SerialNumber = [self.SerialNumber copy];
copy.SoftwareVersion = [self.SoftwareVersion copy];
copy.RendezvousWiFiESSID = [self.RendezvousWiFiESSID copy];
copy.IsRendezvousWiFiESSIDSuffix = self.IsRendezvousWiFiESSIDSuffix;
copy.PairingCode = [self.PairingCode copy];
copy.PairingCompatibilityVersionMajor = self.PairingCompatibilityVersionMajor;
copy.PairingCompatibilityVersionMinor = self.PairingCompatibilityVersionMinor;
return copy;
}
#pragma mark - NSObject
- (NSUInteger)hash
{
return [self.DeviceId hash] ^ self.VendorId;
}
- (BOOL)isEqual:(id)object
{
if (self == object) {
return YES;
}
if (![object isKindOfClass:[NLWeaveDeviceDescriptor class]]) {
return NO;
}
return [self isEqualToNLWeaveDeviceDescriptor:(NLWeaveDeviceDescriptor *) object];
}
- (BOOL)isEqualToNLWeaveDeviceDescriptor:(NLWeaveDeviceDescriptor *)descriptor
{
BOOL equalDeviceId = (self.DeviceId == nil && descriptor.DeviceId == nil) || [self.DeviceId isEqual:descriptor.DeviceId];
BOOL equalFabricId = (self.FabricId == nil && descriptor.FabricId == nil) || [self.FabricId isEqual:descriptor.FabricId];
BOOL equalDeviceFeatures = self.DeviceFeatures == descriptor.DeviceFeatures;
BOOL equalVendorId = self.VendorId == descriptor.VendorId;
BOOL equalProductId = self.ProductId == descriptor.ProductId;
BOOL equalProductRevision = self.ProductRevision == descriptor.ProductRevision;
BOOL equalManufacturingDate
= (self.ManufacturingDate.NLManufacturingDateYear == descriptor.ManufacturingDate.NLManufacturingDateYear)
&& (self.ManufacturingDate.NLManufacturingDateMonth == descriptor.ManufacturingDate.NLManufacturingDateMonth)
&& (self.ManufacturingDate.NLManufacturingDateDay == descriptor.ManufacturingDate.NLManufacturingDateDay);
BOOL equalPrimary802154MACAddress = (self.Primary802154MACAddress == nil && descriptor.Primary802154MACAddress == nil) ||
[self.Primary802154MACAddress isEqual:descriptor.Primary802154MACAddress];
BOOL equalPrimaryWiFiMACAddress = (self.PrimaryWiFiMACAddress == nil && descriptor.PrimaryWiFiMACAddress == nil) ||
[self.PrimaryWiFiMACAddress isEqual:descriptor.PrimaryWiFiMACAddress];
BOOL equalSerialNumber = (self.SerialNumber == nil && descriptor.SerialNumber == nil) ||
[self.SerialNumber isEqualToString:descriptor.SerialNumber];
BOOL equalSoftwareVersion = (self.SoftwareVersion == nil && descriptor.SoftwareVersion == nil) ||
[self.SoftwareVersion isEqualToString:descriptor.SoftwareVersion];
BOOL equalRendezvousWiFiESSID = (self.RendezvousWiFiESSID == nil && descriptor.RendezvousWiFiESSID == nil) ||
[self.RendezvousWiFiESSID isEqualToString:descriptor.RendezvousWiFiESSID];
BOOL equalIsRendezvousWiFiESSIDSuffix = (self.IsRendezvousWiFiESSIDSuffix == descriptor.IsRendezvousWiFiESSIDSuffix);
BOOL equalPairingCode
= (self.PairingCode == nil && descriptor.PairingCode == nil) || [self.PairingCode isEqualToString:descriptor.PairingCode];
BOOL equalPairingCompatibilityVersionMajor
= self.PairingCompatibilityVersionMajor == descriptor.PairingCompatibilityVersionMajor;
BOOL equalPairingCompatibilityVersionMinor
= self.PairingCompatibilityVersionMinor == descriptor.PairingCompatibilityVersionMinor;
return equalDeviceId && equalFabricId && equalDeviceFeatures && equalVendorId && equalProductId && equalProductRevision
&& equalManufacturingDate && equalPrimary802154MACAddress && equalPrimaryWiFiMACAddress && equalSerialNumber
&& equalSoftwareVersion && equalRendezvousWiFiESSID && equalIsRendezvousWiFiESSIDSuffix && equalPairingCode
&& equalPairingCompatibilityVersionMajor && equalPairingCompatibilityVersionMinor;
}
#pragma mark - Protected methods
- (WeaveDeviceDescriptor)toWeaveDeviceDescriptor
{
WeaveDeviceDescriptor deviceDescriptor;
return deviceDescriptor;
}
#pragma mark - Private methods
- (NSString *)debugDescriptionWithDeviceDescriptor:
(nl::Weave::Profiles::DeviceDescription::WeaveDeviceDescriptor *)pDeviceDescriptor
{
BOOL linePowered = (pDeviceDescriptor->DeviceFeatures & WeaveDeviceDescriptor::kFeature_LinePowered)
== WeaveDeviceDescriptor::kFeature_LinePowered;
NSUInteger lenV6 = sizeof(pDeviceDescriptor->Primary802154MACAddress) / sizeof(pDeviceDescriptor->Primary802154MACAddress[0]);
NSUInteger lenV4 = sizeof(pDeviceDescriptor->PrimaryWiFiMACAddress) / sizeof(pDeviceDescriptor->PrimaryWiFiMACAddress[0]);
NSString * descr =
[NSString stringWithFormat:@"(%p), \n"
"\tDeviceId: %llu\n"
"\tFabricId: %qX\n"
"\tDeviceFeatures: %d\n"
"\tVendorId: %lu\n"
"\tProductId: %ld\n"
"\tProductRevision: %lu\n"
"\tManufacturingDate: %ld/%ld/%ld\n"
"\tPrimary802154MACAddress len: %lu\n"
"\tPrimaryWiFiMACAddress len: %lu\n"
"\tSerialNumber: %s\n"
"\tSoftwareVersion: %s\n"
"\tRendezvousWiFiESSID: %s\n"
"\tIsRendezvousWiFiESSIDSuffix: %@\n"
"\tPairingCode: %s\n"
"\tPairingCompatibilityVersionMajor: %d\n"
"\tPairingCompatibilityVersionMinor: %d\n"
"\tRequires Line Power: %d\n",
self, pDeviceDescriptor->DeviceId, pDeviceDescriptor->FabricId, pDeviceDescriptor->DeviceFeatures,
(unsigned long) pDeviceDescriptor->VendorId, (long) pDeviceDescriptor->ProductId,
(unsigned long) pDeviceDescriptor->ProductRevision, (long) pDeviceDescriptor->ManufacturingDate.Month,
(long) pDeviceDescriptor->ManufacturingDate.Day, (long) pDeviceDescriptor->ManufacturingDate.Year,
(unsigned long) lenV6, (unsigned long) lenV4, pDeviceDescriptor->SerialNumber, pDeviceDescriptor->SoftwareVersion,
pDeviceDescriptor->RendezvousWiFiESSID,
pDeviceDescriptor->Flags & WeaveDeviceDescriptor::kFlag_IsRendezvousWiFiESSIDSuffix ? @"YES" : @"NO",
pDeviceDescriptor->PairingCode, pDeviceDescriptor->PairingCompatibilityVersionMajor,
pDeviceDescriptor->PairingCompatibilityVersionMinor, linePowered];
return descr;
}
- (NSString *)debugDescription
{
NSString * descr =
[NSString stringWithFormat:@"(%p), \n"
"\tDeviceId: %llu\n"
"\tFabricId: %qX\n"
"\tDeviceFeatures: %ld\n"
"\tVendorId: %lu\n"
"\tProductId: %ld\n"
"\tProductRevision: %lu\n"
"\tManufacturingDate: %ld/%ld/%ld\n"
"\tPrimary802154MACAddress: %@\n"
"\tPrimaryWiFiMACAddress: %@\n"
"\tSerialNumber: %@\n"
"\tSoftwareVersion: %@\n"
"\tRendezvousWiFiESSID: %@\n"
"\tIsRendezvousWiFiESSIDSuffix: %@\n"
"\tPairingCode: %@\n"
"\tPairingCompatibilityVersionMajor: %ld\n"
"\tPairingCompatibilityVersionMinor: %ld\n"
"\tRequires Line Power: %d\n",
self, [_DeviceId longLongValue], [_FabricId longLongValue], (long) _DeviceFeatures, (unsigned long) _VendorId,
(long) _ProductId, (unsigned long) _ProductRevision, (long) _ManufacturingDate.NLManufacturingDateMonth,
(long) _ManufacturingDate.NLManufacturingDateDay, (long) _ManufacturingDate.NLManufacturingDateYear,
_Primary802154MACAddress, _PrimaryWiFiMACAddress, _SerialNumber, _SoftwareVersion, _RendezvousWiFiESSID,
_IsRendezvousWiFiESSIDSuffix ? @"YES" : @"NO", _PairingCode, (long) _PairingCompatibilityVersionMajor,
(long) _PairingCompatibilityVersionMinor, [self requiresLinePower]];
return descr;
}
@end