IOBluetooth Sync Reader

I am currently working on a program using IOBluetooth, and I need to have synchronous reads, i.e. I call the method, it writes the specified number of bytes to the port, then reads the given number and returns them. I currently have a complex system of NSThreads, NSLocks, and NSConditions, which, although it works, is very slow. In addition, after certain calls, I need to make sure that there is no extra data, so I would just flush the buffer, but with an asynchronous IOBluetooth callback, which is impossible - any thoughts on how to make sure that regardless of all the data received after Is a specific point the data received after this point?

I really did not deal with synchronization and multithreading of this type, since all the work that I have done so far uses synchronous calls, so I will be grateful for any thoughts on this issue.

Here's the callback for incoming data (the "incomingData" object is NSMutableData):

- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength { [dataLock lock]; NSData *data = [NSData dataWithBytes:dataPointer length:dataLength]; [incomingData appendData:data]; if (dataWaitCondition && [incomingData length] >= bytesToWaitFor) { [dataWaitCondition signal]; } [dataLock unlock]; [delegate bluetoothDataReceived]; } 

And here is a method that waits until a given number of bytes is received before returning a data object (it is called from an alternative stream).

 - (NSData *)waitForBytes:(int)numberOfBytes { bytesToWaitFor = numberOfBytes; [dataLock lock]; dataWaitCondition = [[NSCondition alloc] init]; [dataWaitCondition lock]; [dataLock unlock]; while ([incomingData length] < numberOfBytes) { [dataWaitCondition wait]; } [dataLock lock]; NSData *data = [incomingData copy]; [dataWaitCondition unlock]; dataWaitCondition = NULL; [dataLock unlock]; return data; } 
+4
source share
1 answer

Performing any type of I / O in a synchronous manner will cause you problems.

You can avoid multithreading and blocking by using a simple state machine for your application logic. Whenever data is received, the state machine starts and can process the data. If all the data is there, you can take the next step in your application. You can use synchronous calls to send if you want, as they simply drop data using the Bluetooth system.

0
source

Source: https://habr.com/ru/post/1341409/


All Articles