Skip to content

Commit

Permalink
Wow tethering works
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisballinger committed Dec 2, 2013
1 parent 32620f6 commit 18a7a0f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
5 changes: 3 additions & 2 deletions Tether/CBDeviceWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,17 @@ - (void) socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newS
if (!self.selectedDevice.isVisible) {
NSLog(@"selected device no longer visible, aborting connection");
[sock disconnect];
[newSocket disconnect];
return;
}
NSLog(@"new local connection accepted on %@:%d", [sock localHost], [sock localPort]);
NSLog(@"new local connection accepted on %@:%d", [newSocket localHost], [newSocket localPort]);
uint16_t remotePort = [self customOrDefaultRemotePort];
NSString *deviceUUID = [self.selectedDevice.udid copy];

[USBMuxClient connectDevice:self.selectedDevice port:remotePort completionCallback:^(USBMuxDeviceConnection *connection, NSError *error) {
if (connection) {
NSLog(@"New device connection to %@ on port %d", deviceUUID, remotePort);
CBDeviceConnection *deviceConnection = [[CBDeviceConnection alloc] initWithDeviceConnection:connection socket:sock];
CBDeviceConnection *deviceConnection = [[CBDeviceConnection alloc] initWithDeviceConnection:connection socket:newSocket];
NSMutableSet *connections = [self connectionsForDevice:connection.device];
[connections addObject:deviceConnection];
} else {
Expand Down
3 changes: 2 additions & 1 deletion Tether/USBMuxDeviceConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
@property (nonatomic) int socketFileDescriptor;
@property (nonatomic, strong) NSFileHandle *fileHandle;
@property (nonatomic, weak) id<USBMuxDeviceConnectionDelegate> delegate;
@property (nonatomic) dispatch_queue_t networkQueue;
@property (nonatomic) dispatch_queue_t networkReadQueue;
@property (nonatomic) dispatch_queue_t networkWriteQueue;
@property (nonatomic) dispatch_queue_t callbackQueue;
@property (nonatomic) uint16_t port;

Expand Down
57 changes: 52 additions & 5 deletions Tether/USBMuxDeviceConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//

#import "USBMuxDeviceConnection.h"
#import "usbmuxd.h"
#import <sys/ioctl.h>

@implementation USBMuxDeviceConnection

Expand All @@ -17,7 +19,8 @@ - (void) dealloc {
- (id) init {
if (self = [super init]) {
_socketFileDescriptor = 0;
_networkQueue = dispatch_queue_create("USBMuxDevice Network Queue", 0);
_networkReadQueue = dispatch_queue_create("USBMuxDevice Network Read Queue", 0);
_networkWriteQueue = dispatch_queue_create("USBMuxDevice Network Write Queue", 0);
_callbackQueue = dispatch_queue_create("USBMuxDevice Callback Queue", 0);
}
return self;
Expand All @@ -28,9 +31,52 @@ - (void) sendData:(NSData *)data {
NSLog(@"file handle is nil!");
return;
}
dispatch_async(_networkQueue, ^{
dispatch_async(_networkWriteQueue, ^{
NSLog(@"Writing data to device socket %d: %@", _socketFileDescriptor, data);
[_fileHandle writeData:data];
uint32_t sentBytes = 0;
uint32_t totalBytes = (uint32_t)data.length;
int sendValue = usbmuxd_send(_socketFileDescriptor, [data bytes], totalBytes, &sentBytes);
if (sendValue == 0) {
NSLog(@"Wrote %d / %d of %@", sentBytes, totalBytes, data);
} else {
NSLog(@"Error %d occurred while writing %d / %d of %@", sendValue, sentBytes, totalBytes, data);
}
[self readDataFromDeviceWithTimeout:-1];
});
}

- (void) readDataFromDeviceWithTimeout:(NSTimeInterval)timeout {
if (_socketFileDescriptor == 0) {
NSLog(@"read canceled, socket is 0");
return;
}
dispatch_async(_networkReadQueue, ^{
uint32_t bytesAvailable = 0;
uint32_t totalBytesReceived = 0;
ioctl(_socketFileDescriptor, FIONREAD, &bytesAvailable);
if (bytesAvailable == 0) {
NSLog(@"no bytes available for read");
bytesAvailable = 4096;
}
uint8_t *buffer = malloc(bytesAvailable * sizeof(uint8_t));
int readValue = -1;
if (timeout == -1) {
readValue = usbmuxd_recv(_socketFileDescriptor, (char*)buffer, bytesAvailable, &totalBytesReceived);
} else {
readValue = usbmuxd_recv_timeout(_socketFileDescriptor, (char*)buffer, bytesAvailable, &totalBytesReceived, (int)(timeout * 1000));
}
if (readValue != 0) {
NSLog(@"Error reading on socket %d: %d", _socketFileDescriptor, readValue);
free(buffer);
return;
}
NSData *receivedData = [[NSData alloc] initWithBytesNoCopy:buffer length:totalBytesReceived freeWhenDone:YES];
if (_delegate) {
dispatch_async(_callbackQueue, ^{
[_delegate connection:self didReceiveData:receivedData];
});
}
[self readDataFromDeviceWithTimeout:timeout];
});
}

Expand All @@ -39,8 +85,8 @@ - (void) setSocketFileDescriptor:(int)newSocketFileDescriptor {

self.fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:_socketFileDescriptor closeOnDealloc:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataAvailableNotification:) name:NSFileHandleDataAvailableNotification object:_fileHandle];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readCompleteNotification:) name:NSFileHandleReadCompletionNotification object:_fileHandle];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataAvailableNotification:) name:NSFileHandleDataAvailableNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readCompleteNotification:) name:NSFileHandleReadCompletionNotification object:nil];
[_fileHandle waitForDataInBackgroundAndNotify];
}

Expand Down Expand Up @@ -68,6 +114,7 @@ - (void) dataAvailableNotification:(NSNotification*)notification {
- (void) disconnect {
[[NSNotificationCenter defaultCenter] removeObserver:self];
self.device = nil;
self.delegate = nil;
_socketFileDescriptor = 0;
}

Expand Down

0 comments on commit 18a7a0f

Please sign in to comment.