// // ALTWiredConnection.m // AltServer // // Created by Riley Testut on 1/10/20. // Copyright © 2020 Riley Testut. All rights reserved. // #import "ALTWiredConnection+Private.h" #import "AltKit.h" @implementation ALTWiredConnection - (instancetype)initWithDevice:(ALTDevice *)device connection:(idevice_connection_t)connection { self = [super init]; if (self) { _device = [device copy]; _connection = connection; } return self; } - (void)dealloc { [self disconnect]; } - (void)disconnect { idevice_disconnect(self.connection); _connection = nil; } - (void)sendData:(NSData *)data completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler { void (^finish)(NSError *error) = ^(NSError *error) { if (error != nil) { NSLog(@"Send Error: %@", error); completionHandler(NO, error); } else { completionHandler(YES, nil); } }; dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ NSMutableData *mutableData = [data mutableCopy]; while (mutableData.length > 0) { uint32_t sentBytes = 0; if (idevice_connection_send(self.connection, (const char *)mutableData.bytes, (int32_t)mutableData.length, &sentBytes) != IDEVICE_E_SUCCESS) { return finish([NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); } [mutableData replaceBytesInRange:NSMakeRange(0, sentBytes) withBytes:NULL length:0]; } finish(nil); }); } - (void)receiveDataWithExpectedSize:(NSInteger)expectedSize completionHandler:(void (^)(NSData * _Nullable, NSError * _Nullable))completionHandler { void (^finish)(NSData *data, NSError *error) = ^(NSData *data, NSError *error) { if (error != nil) { NSLog(@"Receive Data Error: %@", error); } completionHandler(data, error); }; dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ char bytes[4096]; NSMutableData *receivedData = [NSMutableData dataWithCapacity:expectedSize]; while (receivedData.length < expectedSize) { uint32_t size = MIN(4096, (uint32_t)expectedSize - (uint32_t)receivedData.length); uint32_t receivedBytes = 0; if (idevice_connection_receive_timeout(self.connection, bytes, size, &receivedBytes, 0) != IDEVICE_E_SUCCESS) { return finish(nil, [NSError errorWithDomain:AltServerErrorDomain code:ALTServerErrorLostConnection userInfo:nil]); } NSData *data = [NSData dataWithBytesNoCopy:bytes length:receivedBytes freeWhenDone:NO]; [receivedData appendData:data]; } finish(receivedData, nil); }); } @end