Skip to content

Commit

Permalink
Merge pull request #1 from sagar-apple/02_multi_session_support
Browse files Browse the repository at this point in the history
Fix Darwin Builds for 02 multi session support
  • Loading branch information
andy31415 authored Jun 23, 2020
2 parents eda9174 + 4bebc11 commit d70f74f
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ - (void)viewDidLoad
dispatch_queue_t callbackQueue = dispatch_queue_create("com.zigbee.chip.example.callback", DISPATCH_QUEUE_SERIAL);
self.chipController = [CHIPDeviceController sharedController];
[self.chipController registerCallbacks:callbackQueue
onMessage:^(NSData * _Nonnull message, NSString * _Nonnull ipAddress, UInt16 port) {
onMessage:^(NSData * _Nonnull message) {
typeof(self) strongSelf = weakSelf;
NSString * strMessage = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];
[strongSelf postResult:[@"Echo Response: " stringByAppendingFormat:@"%@", strMessage]];
Expand Down
2 changes: 1 addition & 1 deletion src/darwin/Framework/CHIP/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

NS_ASSUME_NONNULL_BEGIN

typedef void (^ControllerOnMessageBlock)(NSData * message, NSString * ipAddress, UInt16 port);
typedef void (^ControllerOnMessageBlock)(NSData * message);
typedef void (^ControllerOnErrorBlock)(NSError * error);

@interface AddressInfo : NSObject
Expand Down
61 changes: 33 additions & 28 deletions src/darwin/Framework/CHIP/CHIPDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ @interface CHIPDeviceController ()
@property (readwrite) ControllerOnMessageBlock onMessageHandler;
@property (readwrite) ControllerOnErrorBlock onErrorHandler;
@property (readonly) chip::DeviceController::ChipDeviceController * cppController;
@property (readwrite) NSData* localKey;
@property (readwrite) NSData* peerKey;

@end

Expand Down Expand Up @@ -105,17 +107,20 @@ - (instancetype)init
return self;
}

static void onMessageReceived(chip::DeviceController::ChipDeviceController * deviceController, void * appReqState,
chip::System::PacketBuffer * buffer, const chip::IPPacketInfo * packet_info)
static void doKeyExchange(chip::DeviceController::ChipDeviceController * cppController, chip::Transport::PeerConnectionState * state,
void * appReqState)
{
CHIPDeviceController * controller = (__bridge CHIPDeviceController *) appReqState;
[controller _manualKeyExchange:state];
}

char src_addr[INET_ADDRSTRLEN];
size_t data_len = buffer->DataLength();

packet_info->SrcAddress.ToString(src_addr, sizeof(src_addr));
NSString * ipAddress = [[NSString alloc] initWithUTF8String:src_addr];
static void onMessageReceived(chip::DeviceController::ChipDeviceController * deviceController, void * appReqState,
chip::System::PacketBuffer * buffer)
{
CHIPDeviceController * controller = (__bridge CHIPDeviceController *) appReqState;

size_t data_len = buffer->DataLength();
// convert to NSData and pass back to the application
NSMutableData * dataBuffer = [[NSMutableData alloc] initWithBytes:buffer->Start() length:data_len];
buffer = buffer->Next();
Expand All @@ -126,7 +131,7 @@ static void onMessageReceived(chip::DeviceController::ChipDeviceController * dev
buffer = buffer->Next();
}

[controller _dispatchAsyncMessageBlock:dataBuffer ipAddress:ipAddress port:packet_info->SrcPort];
[controller _dispatchAsyncMessageBlock:dataBuffer];

// ignore unused variable
(void) deviceController;
Expand All @@ -151,34 +156,47 @@ - (void)_dispatchAsyncErrorBlock:(NSError *)error
});
}

- (void)_dispatchAsyncMessageBlock:(NSData *)data ipAddress:(NSString *)ipAddress port:(UInt16)port
- (void)_dispatchAsyncMessageBlock:(NSData *)data
{
CHIP_LOG_METHOD_ENTRY();
// to avoid retaining "self"
ControllerOnMessageBlock onMessageHandler = self.onMessageHandler;

dispatch_async(_appCallbackQueue, ^() {
onMessageHandler(data, ipAddress, port);
onMessageHandler(data);
});
}

- (void)_manualKeyExchange:(chip::Transport::PeerConnectionState *)state {
[self.lock lock];
const unsigned char * local_key_bytes = (const unsigned char *) [self.localKey bytes];
const unsigned char * peer_key_bytes = (const unsigned char *) [self.peerKey bytes];

CHIP_ERROR err = self.cppController->ManualKeyExchange(state, peer_key_bytes, self.peerKey.length, local_key_bytes,
self.localKey.length);
[self.lock unlock];

if (err != CHIP_NO_ERROR) {
CHIP_LOG_ERROR("Failed to exchange keys");
[self _dispatchAsyncErrorBlock:[CHIPError errorForCHIPErrorCode:err]];
}
}

- (BOOL)connect:(NSString *)ipAddress
local_key:(NSData *)local_key
peer_key:(NSData *)peer_key
error:(NSError * __autoreleasing *)error
{
CHIP_ERROR err = CHIP_NO_ERROR;

// TODO maybe refactor
// the work queue is being used for atomic access to chip's cpp controller
// this could be done async but the error we care about is sync. However, I think this could be restructured such that
// the request is fired async and that Block can then return an error to the caller. This function would then never error out.
// the only drawback is that it complicates the api where the user must handle async errors on every function
// cache the keys before calling connect (because connect invokes the manual key exchange)
self.localKey = local_key.copy;
self.peerKey = peer_key.copy;

[self.lock lock];
chip::Inet::IPAddress addr;
chip::Inet::IPAddress::FromString([ipAddress UTF8String], addr);
err = self.cppController->ConnectDevice(0, addr, NULL, onMessageReceived, onInternalError, CHIP_PORT);
err = self.cppController->ConnectDevice(kRemoteDeviceId, addr, (__bridge void *) self, doKeyExchange, onMessageReceived, onInternalError, CHIP_PORT);
[self.lock unlock];

if (err != CHIP_NO_ERROR) {
Expand All @@ -188,19 +206,6 @@ - (BOOL)connect:(NSString *)ipAddress
}
return NO;
}
[self.lock lock];
const unsigned char * local_key_bytes = (const unsigned char *) [local_key bytes];
const unsigned char * peer_key_bytes = (const unsigned char *) [peer_key bytes];
err = self.cppController->ManualKeyExchange(peer_key_bytes, peer_key.length, local_key_bytes, local_key.length);
[self.lock unlock];

if (err != CHIP_NO_ERROR) {
CHIP_LOG_ERROR("Error(%d): %@, key exchange failed", err, [CHIPError errorForCHIPErrorCode:err]);
if (error) {
*error = [CHIPError errorForCHIPErrorCode:err];
}
return NO;
}

// Start the IO pump
[self _serviceEvents];
Expand Down
5 changes: 4 additions & 1 deletion src/system/TimeSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define TIME_SOURCE_H_

#include <system/SystemClock.h>
#include <stdlib.h>

namespace chip {
namespace Time {
Expand Down Expand Up @@ -76,7 +77,9 @@ class TimeSource<Source::kTest>

void SetCurrentMonotonicTimeMs(uint64_t value)
{
VerifyOrDie(value >= mCurrentTimeMs); // required contract
if (value < mCurrentTimeMs) {
abort();
}
mCurrentTimeMs = value;
}

Expand Down
2 changes: 2 additions & 0 deletions src/transport/PeerConnections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include <transport/PeerConnections.h>

#include <support/CodeUtils.h>

namespace chip {
namespace Transport {

Expand Down
6 changes: 1 addition & 5 deletions src/transport/PeerConnections.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include <core/CHIPConfig.h>
#include <core/CHIPError.h>
#include <support/CodeUtils.h>
#include <system/TimeSource.h>
#include <transport/PeerConnectionState.h>

Expand Down Expand Up @@ -55,7 +54,6 @@ class PeerConnectionsBase
* @returns CHIP_NO_ERROR if state could be initialized. May fail if maximum connection count
* has been reached (with CHIP_ERROR_NO_MEMORY).
*/
CHECK_RETURN_VALUE
CHIP_ERROR CreateNewPeerConnectionState(const PeerAddress & address, PeerConnectionState ** state);

/**
Expand All @@ -66,7 +64,6 @@ class PeerConnectionsBase
*
* @return true if a corresponding state was found.
*/
CHECK_RETURN_VALUE
bool FindPeerConnectionState(const PeerAddress & address, PeerConnectionState ** state);

/**
Expand All @@ -78,7 +75,6 @@ class PeerConnectionsBase
*
* @return true if a corresponding state was found.
*/
CHECK_RETURN_VALUE
bool FindPeerConnectionState(NodeId nodeId, PeerConnectionState ** state);

/// Convenience method to mark a peer connection state as active
Expand Down Expand Up @@ -126,7 +122,7 @@ class PeerConnectionsBase
class PeerConnections : public PeerConnectionsBase
{
public:
PeerConnections() : PeerConnectionsBase(mState, ArraySize(mState)) {}
PeerConnections() : PeerConnectionsBase(mState, sizeof(mState) / sizeof((mState)[0])) {}

protected:
uint64_t GetCurrentMonotonicTimeMs() override { return mTimeSource.GetCurrentMonotonicTimeMs(); }
Expand Down

0 comments on commit d70f74f

Please sign in to comment.