Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / darwin / Framework / CHIP / CHIPDevice.mm
1 /**
2  *
3  *    Copyright (c) 2020-2021 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 #import "CHIPDevice_Internal.h"
19 #import "CHIPLogging.h"
20 #import <CHIP/CHIPError.h>
21 #import <setup_payload/ManualSetupPayloadGenerator.h>
22 #import <setup_payload/SetupPayload.h>
23
24 @interface CHIPDevice ()
25
26 @property (nonatomic, readonly, strong, nonnull) NSRecursiveLock * lock;
27 @property (readonly) chip::Controller::Device * cppDevice;
28
29 @end
30
31 @implementation CHIPDevice
32
33 - (instancetype)init
34 {
35     if (self = [super init]) {
36         _lock = [[NSRecursiveLock alloc] init];
37     }
38     return self;
39 }
40
41 - (instancetype)initWithDevice:(chip::Controller::Device *)device
42 {
43     if (self = [super init]) {
44         _cppDevice = device;
45     }
46     return self;
47 }
48
49 - (chip::Controller::Device *)internalDevice
50 {
51     return _cppDevice;
52 }
53
54 - (BOOL)openPairingWindow:(NSUInteger)duration error:(NSError * __autoreleasing *)error
55 {
56     CHIP_ERROR err = CHIP_NO_ERROR;
57
58     chip::SetupPayload setupPayload;
59
60     if (duration > UINT32_MAX) {
61         CHIP_LOG_ERROR("Error: Duration %tu is too large. Max value %d", duration, UINT32_MAX);
62         if (error) {
63             *error = [CHIPError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE];
64         }
65         return NO;
66     }
67
68     [self.lock lock];
69     err = self.cppDevice->OpenPairingWindow(
70         (uint32_t) duration, chip::Controller::Device::PairingWindowOption::kOriginalSetupCode, setupPayload);
71     [self.lock unlock];
72
73     if (err != CHIP_NO_ERROR) {
74         CHIP_LOG_ERROR("Error(%d): %@, Open Pairing Window failed", err, [CHIPError errorForCHIPErrorCode:err]);
75         if (error) {
76             *error = [CHIPError errorForCHIPErrorCode:err];
77         }
78         return NO;
79     }
80
81     return YES;
82 }
83
84 - (NSString *)openPairingWindowWithPIN:(NSUInteger)duration
85                          discriminator:(NSUInteger)discriminator
86                               setupPIN:(NSUInteger)setupPIN
87                                  error:(NSError * __autoreleasing *)error
88 {
89     CHIP_ERROR err = CHIP_NO_ERROR;
90
91     chip::SetupPayload setupPayload;
92
93     if (duration > UINT32_MAX) {
94         CHIP_LOG_ERROR("Error: Duration %tu is too large. Max value %d", duration, UINT32_MAX);
95         if (error) {
96             *error = [CHIPError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE];
97         }
98         return nil;
99     }
100
101     if (discriminator > 0xfff) {
102         CHIP_LOG_ERROR("Error: Discriminator %tu is too large. Max value %d", discriminator, 0xfff);
103         if (error) {
104             *error = [CHIPError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE];
105         }
106         return nil;
107     } else {
108         setupPayload.discriminator = (uint16_t) discriminator;
109     }
110
111     setupPIN &= ((1 << chip::kSetupPINCodeFieldLengthInBits) - 1);
112     setupPayload.setUpPINCode = (uint32_t) setupPIN;
113
114     [self.lock lock];
115     err = self.cppDevice->OpenPairingWindow(
116         (uint32_t) duration, chip::Controller::Device::PairingWindowOption::kTokenWithProvidedPIN, setupPayload);
117     [self.lock unlock];
118
119     if (err != CHIP_NO_ERROR) {
120         CHIP_LOG_ERROR("Error(%d): %@, Open Pairing Window failed", err, [CHIPError errorForCHIPErrorCode:err]);
121         if (error) {
122             *error = [CHIPError errorForCHIPErrorCode:err];
123         }
124         return nil;
125     }
126
127     chip::ManualSetupPayloadGenerator generator(setupPayload);
128     std::string outCode;
129
130     if (generator.payloadDecimalStringRepresentation(outCode) == CHIP_NO_ERROR) {
131         CHIP_LOG_ERROR("Setup code is %s", outCode.c_str());
132     } else {
133         CHIP_LOG_ERROR("Failed to get decimal setup code");
134         return nil;
135     }
136
137     return [NSString stringWithCString:outCode.c_str() encoding:[NSString defaultCStringEncoding]];
138 }
139
140 - (BOOL)isActive
141 {
142     bool isActive = false;
143
144     [self.lock lock];
145     isActive = self.cppDevice->IsActive();
146     [self.lock unlock];
147
148     return isActive ? YES : NO;
149 }
150 @end