mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Add request data connection before data transmission for L2CAP.
PiperOrigin-RevId: 753434675
This commit is contained in:
committed by
Copybara-Service
parent
fc0768f2c4
commit
e9aef7153a
@@ -47,6 +47,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (void)sendData:(NSData *)payload completion:(void (^)(BOOL))completion;
|
||||
|
||||
/**
|
||||
* Requests data connection from the remote device.
|
||||
*
|
||||
* @param completion A block that is called when the data connection is ready. The block takes a
|
||||
* BOOL parameter indicating whether the data connection is ready.
|
||||
*/
|
||||
- (void)requestDataConnectionWithCompletion:(void (^)(BOOL))completion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#import "GoogleToolboxForMac/GTMLogger.h"
|
||||
|
||||
enum { kL2CAPPacketLength = 4 };
|
||||
static const CGFloat kRequestDataConnectionDelayInSeconds = 0.0;
|
||||
static const UInt8 kRequestDataConnectionTimeoutInSeconds = 5;
|
||||
|
||||
static char *const kGNCBLEL2CAPConnectionQueueLabel = "com.google.nearby.GNCBLEL2CAPConnection";
|
||||
|
||||
@@ -60,6 +62,7 @@ static NSData *PrefixLengthData(NSData *data) {
|
||||
@property(nonatomic) NSUInteger expectedDataLength;
|
||||
@property(nonatomic) NSMutableData *undeliveredData;
|
||||
@property(nonatomic) BOOL verboseLoggingEnabled;
|
||||
@property(nonatomic) NSCondition *requestDataConnectionCondition;
|
||||
@end
|
||||
|
||||
@implementation GNCBLEL2CAPConnection
|
||||
@@ -80,6 +83,7 @@ static NSData *PrefixLengthData(NSData *data) {
|
||||
[connection setIncomingConnection:incomingConnection];
|
||||
[connection setUndeliveredData:[NSMutableData data]];
|
||||
[connection setExpectedDataLength:0];
|
||||
[connection setRequestDataConnectionCondition:[[NSCondition alloc] init]];
|
||||
return connection;
|
||||
}
|
||||
|
||||
@@ -108,6 +112,31 @@ static NSData *PrefixLengthData(NSData *data) {
|
||||
});
|
||||
}
|
||||
|
||||
- (void)requestDataConnectionWithCompletion:(void (^)(BOOL))completion {
|
||||
GTMLoggerInfo(@"[NEARBY] Sending l2cap packet request data connection");
|
||||
// TODO b/399815436 - A bug is causing channel has written to the socket but the remote does not
|
||||
// receive it. Add a delay to make sure the data is written to the socket. Remove the delay once
|
||||
// the bug is fixed.
|
||||
dispatch_time_t requestTime =
|
||||
dispatch_time(DISPATCH_TIME_NOW, kRequestDataConnectionDelayInSeconds * NSEC_PER_SEC);
|
||||
dispatch_after(requestTime, _selfQueue, ^(void) {
|
||||
[_requestDataConnectionCondition lock];
|
||||
NSData *requestDataConnectionPacket =
|
||||
GNCMGenerateBLEL2CAPPacket(GNCMBLEL2CAPCommandRequestDataConnection, nil);
|
||||
[_stream sendData:PrefixLengthData(requestDataConnectionPacket)
|
||||
completionBlock:^(BOOL result){
|
||||
|
||||
}];
|
||||
dispatch_async(_callbackQueue, ^{
|
||||
NSDate *requestDataConnectionTimeout =
|
||||
[NSDate dateWithTimeIntervalSinceNow:kRequestDataConnectionTimeoutInSeconds];
|
||||
BOOL result = [_requestDataConnectionCondition waitUntilDate:requestDataConnectionTimeout];
|
||||
completion(result);
|
||||
[_requestDataConnectionCondition unlock];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark GNCBLEL2CAPStreamDelegate
|
||||
|
||||
- (void)stream:(GNCBLEL2CAPStream *)stream didReceiveData:(NSData *)data {
|
||||
@@ -263,12 +292,15 @@ static NSData *PrefixLengthData(NSData *data) {
|
||||
}
|
||||
switch (l2capPacket.command) {
|
||||
case GNCMBLEL2CAPCommandResponseDataConnectionReady: {
|
||||
_handledReceivedL2CAPResponseDataConnectionReadyPacket = YES;
|
||||
[_requestDataConnectionCondition lock];
|
||||
dispatch_async(_selfQueue, ^{
|
||||
[_stream sendData:PrefixLengthData(GNCMGenerateBLEFramesIntroductionPacket(_serviceIDHash))
|
||||
completionBlock:^(BOOL result){
|
||||
completionBlock:^(BOOL result) {
|
||||
[_requestDataConnectionCondition broadcast];
|
||||
[_requestDataConnectionCondition unlock];
|
||||
}];
|
||||
});
|
||||
_handledReceivedL2CAPResponseDataConnectionReadyPacket = YES;
|
||||
} break;
|
||||
case GNCMBLEL2CAPCommandRequestAdvertisement:
|
||||
case GNCMBLEL2CAPCommandRequestDataConnection:
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#import "GoogleToolboxForMac/GTMLogger.h"
|
||||
|
||||
static NSString *const kWeaveServiceUUID = @"FEF3";
|
||||
static const UInt8 kRequestConnectionTimeoutInSeconds = 10;
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
@@ -492,8 +493,10 @@ std::unique_ptr<api::ble_v2::BleL2capSocket> BleMedium::ConnectOverL2cap(
|
||||
}
|
||||
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
dispatch_time_t timeout =
|
||||
dispatch_time(DISPATCH_TIME_NOW, kRequestConnectionTimeoutInSeconds * NSEC_PER_SEC);
|
||||
__block std::unique_ptr<BleL2capSocket> socket;
|
||||
std::string service_id_str = service_id;
|
||||
const std::string &service_id_str = service_id;
|
||||
[medium_ openL2CAPChannelWithPSM:psm
|
||||
peripheral:non_empty_peripheral->GetPeripheral()
|
||||
completionHandler:^(GNCBLEL2CAPStream *stream, NSError *error) {
|
||||
@@ -506,10 +509,22 @@ std::unique_ptr<api::ble_v2::BleL2capSocket> BleMedium::ConnectOverL2cap(
|
||||
serviceID:@(service_id_str.c_str())
|
||||
incomingConnection:NO
|
||||
callbackQueue:dispatch_get_main_queue()];
|
||||
socket = std::make_unique<BleL2capSocket>(connection, non_empty_peripheral);
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
// Blocked call to wait for the packet validation result.
|
||||
// TODO: b/399815436 - Remove this once the packet validation is moved to the
|
||||
// Connections layer.
|
||||
[connection requestDataConnectionWithCompletion:^(BOOL result) {
|
||||
if (result) {
|
||||
socket = std::make_unique<BleL2capSocket>(connection, non_empty_peripheral);
|
||||
}
|
||||
GTMLoggerInfo(result ? @"[NEARBY] Request data connection is ok"
|
||||
: @"[NEARBY] Request data connection is not ok");
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
}];
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
if (dispatch_semaphore_wait(semaphore, timeout) != 0) {
|
||||
GTMLoggerError(@"[NEARBY] Failed to connect over L2CAP: timeout.");
|
||||
return nullptr;
|
||||
}
|
||||
if (socket == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user