blob: 54463a59f99a65cd34e794acf354fdda9e8a1493 [file] [log] [blame]
/**
*
* Copyright (c) 2022 Project CHIP Authors
*
* 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.
*/
#import "MTRDeviceControllerOverXPC_Internal.h"
#import "MTRDeviceController+XPC.h"
#import "MTRDeviceControllerXPCConnection.h"
#import "MTRDeviceOverXPC.h"
#import "MTRError.h"
#import "MTRLogging.h"
#import <Foundation/Foundation.h>
static dispatch_once_t workQueueInitOnceToken;
static dispatch_queue_t globalWorkQueue;
static void SetupXPCQueue(void)
{
dispatch_once(&workQueueInitOnceToken, ^{
globalWorkQueue = dispatch_queue_create("com.apple.matter.framework.xpc.workqueue", DISPATCH_QUEUE_SERIAL);
});
}
@implementation MTRDeviceControllerOverXPC
+ (MTRDeviceControllerOverXPC *)sharedControllerWithId:(id<NSCopying> _Nullable)controllerId
xpcConnectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
SetupXPCQueue();
return [[MTRDeviceControllerOverXPC alloc] initWithControllerId:controllerId
workQueue:globalWorkQueue
connectBlock:connectBlock];
}
- (BOOL)pairDevice:(uint64_t)deviceID
discriminator:(uint16_t)discriminator
setupPINCode:(uint32_t)setupPINCode
error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
return NO;
}
- (BOOL)pairDevice:(uint64_t)deviceID
address:(NSString *)address
port:(uint16_t)port
discriminator:(uint16_t)discriminator
setupPINCode:(uint32_t)setupPINCode
error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
return NO;
}
- (BOOL)pairDevice:(uint64_t)deviceID onboardingPayload:(NSString *)onboardingPayload error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
return NO;
}
- (BOOL)commissionDevice:(uint64_t)deviceId
commissioningParams:(MTRCommissioningParameters *)commissioningParams
error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support pairDevice over XPC");
return NO;
}
- (void)setListenPort:(uint16_t)port
{
MTR_LOG_ERROR("MTRDevice doesn't support setListenPort over XPC");
}
- (BOOL)stopDevicePairing:(uint64_t)deviceID error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support stopDevicePairing over XPC");
return NO;
}
- (nullable MTRBaseDevice *)getDeviceBeingCommissioned:(uint64_t)deviceId error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support getDeviceBeingCommissioned over XPC");
return nil;
}
- (BOOL)getBaseDevice:(uint64_t)deviceID
queue:(dispatch_queue_t)queue
completionHandler:(MTRDeviceConnectionCallback)completionHandler
{
dispatch_async(_workQueue, ^{
dispatch_group_t group = dispatch_group_create();
if (!self.controllerId) {
dispatch_group_enter(group);
[self.xpcConnection getProxyHandleWithCompletion:^(
dispatch_queue_t _Nonnull queue, MTRDeviceControllerXPCProxyHandle * _Nullable handle) {
if (handle) {
[handle.proxy getAnyDeviceControllerWithCompletion:^(id _Nullable controller, NSError * _Nullable error) {
if (error) {
MTR_LOG_ERROR("Failed to fetch any shared remote controller");
} else {
self.controllerId = controller;
}
dispatch_group_leave(group);
__auto_type handleRetainer = handle;
(void) handleRetainer;
}];
} else {
MTR_LOG_ERROR("XPC disconnected while retrieving any shared remote controller");
dispatch_group_leave(group);
}
}];
}
dispatch_group_notify(group, queue, ^{
if (self.controllerId) {
MTRDeviceOverXPC * device = [[MTRDeviceOverXPC alloc] initWithController:self.controllerId
deviceId:deviceID
xpcConnection:self.xpcConnection];
completionHandler(device, nil);
} else {
completionHandler(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]);
}
});
});
return YES;
}
- (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support openPairingWindow over XPC");
return NO;
}
- (nullable NSString *)openPairingWindowWithPIN:(uint64_t)deviceID
duration:(NSUInteger)duration
discriminator:(NSUInteger)discriminator
setupPIN:(NSUInteger)setupPIN
error:(NSError * __autoreleasing *)error
{
MTR_LOG_ERROR("MTRDevice doesn't support openPairingWindow over XPC");
return nil;
}
- (instancetype)initWithControllerId:(id)controllerId
workQueue:(dispatch_queue_t)queue
xpcConnection:(MTRDeviceControllerXPCConnection *)connection
{
_controllerId = controllerId;
_workQueue = queue;
_xpcConnection = connection;
return self;
}
// This is interface for unit testing
- (instancetype)initWithControllerId:(id)controllerId
workQueue:(dispatch_queue_t)queue
connectBlock:(NSXPCConnection * (^)(void) )connectBlock
{
return [self initWithControllerId:controllerId
workQueue:queue
xpcConnection:[MTRDeviceControllerXPCConnection connectionWithWorkQueue:queue connectBlock:connectBlock]];
}
@end