Network Provisioning: Objective-C Support for wireless regulatory provisioning
diff --git a/src/device-manager/cocoa/Makefile.am b/src/device-manager/cocoa/Makefile.am
index 64ebf32..0f2c976 100644
--- a/src/device-manager/cocoa/Makefile.am
+++ b/src/device-manager/cocoa/Makefile.am
@@ -68,6 +68,7 @@
NLResourceIdentifier.h \
NLWdmClientFlushUpdateError.h \
NLWdmClientFlushUpdateDeviceStatusError.h \
+ NLWirelessRegConfig.h \
$(NULL)
noinst_HEADERS = \
@@ -79,6 +80,7 @@
NLWdmClient_Protected.h \
NLResourceIdentifier_Protected.h \
NLGenericTraitUpdatableDataSink_Protected.h \
+ NLWirelessRegConfig_Protected.h \
$(NULL)
libNLWeaveDeviceManager_a_SOURCES = \
@@ -106,6 +108,7 @@
NLResourceIdentifier.mm \
NLWdmClientFlushUpdateError.mm \
NLWdmClientFlushUpdateDeviceStatusError.mm \
+ NLWirelessRegConfig.mm \
$(NULL)
endif # WEAVE_WITH_COCOA
diff --git a/src/device-manager/cocoa/NLWeaveDeviceManager.h b/src/device-manager/cocoa/NLWeaveDeviceManager.h
index 2a2285b..fc9d54e 100644
--- a/src/device-manager/cocoa/NLWeaveDeviceManager.h
+++ b/src/device-manager/cocoa/NLWeaveDeviceManager.h
@@ -1,6 +1,7 @@
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
+ * Copyright (c) 2018-2020 Google LLC.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,6 +28,7 @@
#import "NLWeaveErrorCodes.h"
#import "NLIdentifyDeviceCriteria.h"
#import "NLNetworkInfo.h"
+#import "NLWirelessRegConfig.h"
#import "NLServiceInfo.h"
typedef void (^WDMCompletionBlock)(id owner, id data);
@@ -187,6 +189,12 @@
@{
*/
+- (void)getWirelessRegulatoryConfig:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock;
+
+- (void)setWirelessRegulatoryConfig:(NLWirelessRegConfig *)nlWirelessRegConfig
+ completion:(WDMCompletionBlock)completionBlock
+ failure:(WDMFailureBlock)failureBlock;
+
- (void)scanNetworks:(NLNetworkType)networkType
completion:(WDMCompletionBlock)completionBlock
failure:(WDMFailureBlock)failureBlock;
diff --git a/src/device-manager/cocoa/NLWeaveDeviceManager.mm b/src/device-manager/cocoa/NLWeaveDeviceManager.mm
index 05bb3e5..bec3ece 100644
--- a/src/device-manager/cocoa/NLWeaveDeviceManager.mm
+++ b/src/device-manager/cocoa/NLWeaveDeviceManager.mm
@@ -1,6 +1,7 @@
/*
*
* Copyright (c) 2013-2017 Nest Labs, Inc.
+ * Copyright (c) 2018-2020 Google LLC.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -43,6 +44,7 @@
#include <Weave/Profiles/device-description/DeviceDescription.h>
#import "NLIdentifyDeviceCriteria_Protected.h"
#import "Base64Encoding.h"
+#import "NLWirelessRegConfig_Protected.h"
static void onIdentifyDeviceComplete(nl::Weave::DeviceManager::WeaveDeviceManager * deviceMgr, void * appReqState,
const nl::Weave::DeviceManager::DeviceDescription::WeaveDeviceDescriptor * devdesc);
@@ -384,11 +386,11 @@
return err;
}
-- (WEAVE_ERROR)GetDeviceMgrPtr:(long long*)deviceMgrPtr
+- (WEAVE_ERROR)GetDeviceMgrPtr:(long long *)deviceMgrPtr
{
__block WEAVE_ERROR err = WEAVE_NO_ERROR;
WDM_LOG_METHOD_SIG();
- *deviceMgrPtr = (long long)_mWeaveCppDM;
+ *deviceMgrPtr = (long long) _mWeaveCppDM;
return err;
}
@@ -472,14 +474,14 @@
errorCode:devStatus->SystemErrorCode
statusReport:[dm statusReportToString:devStatus->StatusProfileId statusCode:devStatus->StatusCode]];
requestError = NLWeaveRequestError_ProfileStatusError;
- userInfo = @{ @"WeaveRequestErrorType" : @(requestError), @"errorInfo" : statusError };
+ userInfo = @{@"WeaveRequestErrorType" : @(requestError), @"errorInfo" : statusError};
WDM_LOG_DEBUG(@"%@: status error: %@", dm.name, userInfo);
} else {
NLWeaveError * weaveError = [[NLWeaveError alloc] initWithWeaveError:code
report:[NSString stringWithUTF8String:nl::ErrorStr(code)]];
requestError = NLWeaveRequestError_WeaveError;
- userInfo = @{ @"WeaveRequestErrorType" : @(requestError), @"errorInfo" : weaveError };
+ userInfo = @{@"WeaveRequestErrorType" : @(requestError), @"errorInfo" : weaveError};
}
error = [NSError errorWithDomain:@"com.nest.error" code:code userInfo:userInfo];
@@ -1082,6 +1084,78 @@
});
}
+static void onGetWirelessRegulatoryConfigComplete(nl::Weave::DeviceManager::WeaveDeviceManager * deviceMgr, void * reqState,
+ const nl::Weave::Profiles::NetworkProvisioning::WirelessRegConfig * regConfig)
+{
+ WDM_LOG_DEBUG(@"onGetWirelessRegulatoryConfigComplete");
+
+ NLWeaveDeviceManager * dm = (__bridge NLWeaveDeviceManager *) reqState;
+ // ignore the pointer to C++ device manager
+ (void) deviceMgr;
+
+ [dm DispatchAsyncCompletionBlock:[NLWirelessRegConfig createUsing:regConfig]];
+}
+
+- (void)getWirelessRegulatoryConfig:(WDMCompletionBlock)completionBlock failure:(WDMFailureBlock)failureBlock
+{
+ WDM_LOG_METHOD_SIG();
+
+ NSString * taskName = @"GetWirelessRegulatoryConfig";
+
+ // we use async for the results are sent back to caller via async means also
+ dispatch_async(_mWeaveWorkQueue, ^() {
+ if (nil == _mRequestName) {
+ _mRequestName = taskName;
+ _mCompletionHandler = completionBlock;
+ _mFailureHandler = failureBlock;
+
+ WEAVE_ERROR err = _mWeaveCppDM->GetWirelessRegulatoryConfig(
+ (__bridge void *) self, onGetWirelessRegulatoryConfigComplete, onWeaveError);
+
+ if (WEAVE_NO_ERROR != err) {
+ [self DispatchAsyncDefaultFailureBlockWithCode:err];
+ }
+ } else {
+ WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);
+
+ // do not change _mRequestName, as we're rejecting this request
+ [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
+ }
+ });
+}
+
+- (void)setWirelessRegulatoryConfig:(NLWirelessRegConfig *)nlWirelessRegConfig
+ completion:(WDMCompletionBlock)completionBlock
+ failure:(WDMFailureBlock)failureBlock
+{
+ WDM_LOG_METHOD_SIG();
+
+ NSString * taskName = @"SetWirelessRegulatoryConfig";
+
+ // we use async for the results are sent back to caller via async means also
+ dispatch_async(_mWeaveWorkQueue, ^() {
+ if (nil == _mRequestName) {
+ _mRequestName = taskName;
+ _mCompletionHandler = completionBlock;
+ _mFailureHandler = failureBlock;
+
+ nl::Weave::Profiles::NetworkProvisioning::WirelessRegConfig wirelessRegConfig =
+ [nlWirelessRegConfig toWirelessRegConfig];
+
+ WEAVE_ERROR err = _mWeaveCppDM->SetWirelessRegulatoryConfig(
+ &wirelessRegConfig, (__bridge void *) self, HandleSimpleOperationComplete, onWeaveError);
+ if (WEAVE_NO_ERROR != err) {
+ [self DispatchAsyncDefaultFailureBlockWithCode:err];
+ }
+ } else {
+ WDM_LOG_ERROR(@"%@: Attemp to %@ while we're still executing %@, ignore", _name, taskName, _mRequestName);
+
+ // do not change _mRequestName, as we're rejecting this request
+ [self DispatchAsyncFailureBlock:WEAVE_ERROR_INCORRECT_STATE taskName:taskName handler:failureBlock];
+ }
+ });
+}
+
static void onNetworkScanComplete(
nl::Weave::DeviceManager::WeaveDeviceManager * deviceMgr, void * reqState, uint16_t netCount, const NetworkInfo * netInfoList)
{
diff --git a/src/device-manager/cocoa/NLWeaveDeviceManagerTypes.h b/src/device-manager/cocoa/NLWeaveDeviceManagerTypes.h
index 66b3aeb..fafd39c 100644
--- a/src/device-manager/cocoa/NLWeaveDeviceManagerTypes.h
+++ b/src/device-manager/cocoa/NLWeaveDeviceManagerTypes.h
@@ -40,6 +40,15 @@
};
+// WiFi WirelessOperatingLocation
+//
+typedef NS_ENUM(NSInteger, NLWirelessOperatingLocation) {
+ kNLWirelessOperatingLocation_NotSpecified = 0x00,
+ kNLWirelessOperatingLocation_Unknown = 0x01,
+ kNLWirelessOperatingLocation_Indoors = 0x02,
+ kNLWirelessOperatingLocation_Outdoors = 0x03
+};
+
// WiFi Operating Modes
//
typedef NS_ENUM(NSInteger, NLWiFiMode) {
diff --git a/src/device-manager/cocoa/NLWirelessRegConfig.h b/src/device-manager/cocoa/NLWirelessRegConfig.h
new file mode 100644
index 0000000..d98e5fa
--- /dev/null
+++ b/src/device-manager/cocoa/NLWirelessRegConfig.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2020 Google LLC
+ * 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 wireless regulatory configuration information.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "NLWeaveDeviceManagerTypes.h"
+
+@interface NLWirelessRegConfig : NSObject
+
+@property (nonatomic, strong) NSString * RegDomain; // The region domain name
+@property (nonatomic) NLWirelessOperatingLocation OpLocation; // The Wireless Operating location.
+@property (nonatomic, strong) NSMutableArray * SupportedRegDomains; // The Supported Wireless reg domain.
+
+- (id)initWithSupportedRegDomains:(NSMutableArray *)supportedRegDomains
+ opLocation:(NLWirelessOperatingLocation)opLocation
+ RegDomain:(NSString *)regDomain;
+
+- (id)initWithRegDomain:(NSString *)regDomain opLocation:(NLWirelessOperatingLocation)opLocation;
+
+- (WEAVE_ERROR)getRegDomain:(NSString **)val;
+
+- (WEAVE_ERROR)getOpLocation:(NLWirelessOperatingLocation *)val;
+
+- (WEAVE_ERROR)getSupportedRegDomain:(NSMutableArray **)val;
+
+@end
diff --git a/src/device-manager/cocoa/NLWirelessRegConfig.mm b/src/device-manager/cocoa/NLWirelessRegConfig.mm
new file mode 100644
index 0000000..54ce393
--- /dev/null
+++ b/src/device-manager/cocoa/NLWirelessRegConfig.mm
@@ -0,0 +1,130 @@
+/*
+ *
+ * Copyright (c) 2020 Google LLC
+ * 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 wireless regulatory configuration information.
+ *
+ */
+
+#import "NLLogging.h"
+#import "NLWeaveErrorCodes.h"
+#import "NLWirelessRegConfig_Protected.h"
+
+using nl::Weave::Profiles::NetworkProvisioning::WirelessOperatingLocation;
+using nl::Weave::Profiles::NetworkProvisioning::WirelessRegDomain;
+
+@implementation NLWirelessRegConfig
+
++ (NLWirelessRegConfig *)createUsing:(const WirelessRegConfig *)pWirelessRegConfig
+{
+ return [[NLWirelessRegConfig alloc] initWith:pWirelessRegConfig];
+}
+
+- (instancetype)initWithRegDomain:(NSString *)regDomain opLocation:(NLWirelessOperatingLocation)opLocation
+{
+ if (self = [self init]) {
+ _RegDomain = regDomain;
+ _OpLocation = opLocation;
+ _SupportedRegDomains = [NSMutableArray arrayWithCapacity:0];
+ }
+ return self;
+}
+
+- (instancetype)initWithSupportedRegDomains:(NSMutableArray *)supportedRegDomains
+ opLocation:(NLWirelessOperatingLocation)opLocation
+ RegDomain:(NSString *)regDomain
+{
+ if (self = [self init]) {
+ _RegDomain = regDomain;
+ _OpLocation = opLocation;
+ _SupportedRegDomains = supportedRegDomains;
+ }
+ return self;
+}
+
+- (instancetype)initWith:(const WirelessRegConfig *)pWirelessRegConfig
+{
+ if (self = [super init]) {
+ _RegDomain = [[NSString alloc] initWithCString:pWirelessRegConfig->RegDomain.Code encoding:NSUTF8StringEncoding];
+ _OpLocation = (NLWirelessOperatingLocation) pWirelessRegConfig->OpLocation;
+ _SupportedRegDomains = [[NSMutableArray alloc] initWithCapacity:pWirelessRegConfig->NumSupportedRegDomains];
+
+ WDM_LOG_DEBUG(@"pWirelessRegConfig->NumSupportedRegDomains = %u\n", pWirelessRegConfig->NumSupportedRegDomains);
+ for (uint32_t i = 0; i < pWirelessRegConfig->NumSupportedRegDomains; i++) {
+ NSMutableString * nlRegDomain = [NSMutableString string];
+ for (NSUInteger j = 0; j < sizeof(WirelessRegDomain::Code); j++) {
+ char ch = pWirelessRegConfig->SupportedRegDomains[i].Code[j];
+ [nlRegDomain appendFormat:@"%c", ch];
+ }
+ [_SupportedRegDomains addObject:nlRegDomain];
+ }
+ NSLog(@"_SupportedRegDomains is: %@", _SupportedRegDomains);
+ }
+ return self;
+}
+
+#pragma mark - Protected methods
+
+- (WirelessRegConfig)toWirelessRegConfig
+{
+ WirelessRegConfig wirelessRegConfig;
+
+ memcpy(wirelessRegConfig.RegDomain.Code, [_RegDomain UTF8String], [_RegDomain length]);
+ wirelessRegConfig.OpLocation = [self toWirelessOperatingLocation:_OpLocation];
+
+ wirelessRegConfig.NumSupportedRegDomains = 0;
+ // NOTE: The SupportRegulatoryDomains field is never sent *to* a device. Thus we ignore the field value here.
+
+ return wirelessRegConfig;
+}
+
+- (nl::Weave::Profiles::NetworkProvisioning::WirelessOperatingLocation)toWirelessOperatingLocation:
+ (NLWirelessOperatingLocation)opLocation
+{
+ switch (opLocation) {
+ case kNLWirelessOperatingLocation_Unknown:
+ return nl::Weave::Profiles::NetworkProvisioning::kWirelessOperatingLocation_Unknown;
+ case kNLWirelessOperatingLocation_Indoors:
+ return nl::Weave::Profiles::NetworkProvisioning::kWirelessOperatingLocation_Indoors;
+ case kNLWirelessOperatingLocation_Outdoors:
+ return nl::Weave::Profiles::NetworkProvisioning::kWirelessOperatingLocation_Outdoors;
+ default:
+ return nl::Weave::Profiles::NetworkProvisioning::kWirelessOperatingLocation_NotSpecified;
+ }
+}
+
+- (WEAVE_ERROR)getRegDomain:(NSString **)val
+{
+ *val = _RegDomain;
+ return WEAVE_NO_ERROR;
+}
+
+- (WEAVE_ERROR)getOpLocation:(NLWirelessOperatingLocation *)val
+{
+ *val = _OpLocation;
+ return WEAVE_NO_ERROR;
+}
+
+- (WEAVE_ERROR)getSupportedRegDomain:(NSMutableArray **)val
+{
+ *val = _SupportedRegDomains;
+ return WEAVE_NO_ERROR;
+}
+
+@end
diff --git a/src/device-manager/cocoa/NLWirelessRegConfig_Protected.h b/src/device-manager/cocoa/NLWirelessRegConfig_Protected.h
new file mode 100644
index 0000000..5c6b643
--- /dev/null
+++ b/src/device-manager/cocoa/NLWirelessRegConfig_Protected.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 2020 Google LLC
+ * 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 wireless regulatory configuration information.
+ *
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "NLWirelessRegConfig.h"
+#include "WeaveDeviceManager.h"
+
+using nl::Weave::Profiles::NetworkProvisioning::WirelessRegConfig;
+
+@interface NLWirelessRegConfig ()
+
+- (instancetype)initWith:(const WirelessRegConfig *)pWirelessRegConfig NS_DESIGNATED_INITIALIZER;
+
++ (NLWirelessRegConfig *)createUsing:(const WirelessRegConfig *)pWirelessRegConfig;
+
+- (WirelessRegConfig)toWirelessRegConfig;
+@end