Amount of data to be sent to peripheral using bluetooth in ios 8 - swift

I am working in data transferring using bluetooth from BLE device to peripheral hardware. I want to write data from binary file in chunks as total data length is 143233. I found one line "Maximal MTU was 132 bytes for iOS 7 devices and 20 B for iOS 6" but what about iOS 8?
What will be maximum size of chunks for iOS 8? This is the code which I have used, I dont know whether i am going right way or not so help me and guide me if i am going wrong. Thanks in advance.
var count:Int = 0
var counter:Int = 0
var str:NSString = NSBundle.mainBundle().pathForResource("spp", ofType: "bin")!
println("string value is \(str)")
var dataFile:NSString = NSString.stringWithContentsOfFile(str, encoding: NSASCIIStringEncoding, error: nil)
data = dataFile.dataUsingEncoding(NSUTF8StringEncoding)
println(data!.length)
println(dataFile.length)
var dataLen:Int = data!.length
if (dataLen > 132)
{
while(count < dataLen && dataLen - count > 132)
{
peripheral.writeValue(data!.subdataWithRange(NSMakeRange(count, 132)), forCharacteristic: arrCharacteristics!.objectAtIndex(1) as CBCharacteristic , type: CBCharacteristicWriteType.WithResponse)
NSThread.sleepForTimeInterval(0.005)
println("Write performed \(counter++ )")
count += 132
}
} if (count < dataLen)
{
peripheral.writeValue(data!.subdataWithRange(NSMakeRange(count, dataLen - count)), forCharacteristic: arrCharacteristics!.objectAtIndex(1) as CBCharacteristic , type: CBCharacteristicWriteType.WithResponse)
}

I'm guessing Jalek found his answer but for anyone else seeking the figures.
iOS 7 requests a 135 byte MTU (132 bytes data + 3 overhead).
iOS 8 requests a 158 byte MTU (155 bytes data + 3 overhead).
Obviously, it will depend on the other device whether these values are accepted or a lower value returned.

Related

Packetsize in Gamepsparks Realtime

My packet in gamesparks contains:
Two vector2: 8bytes x 2 = 16bytes
key values with vector 2 = 8bytes
peerid present in packet = 4bytes
opCode present in packet = 4bytes
Total = 32bytes.
However my packet size is a little big bigger than this. Am i missing something in the packet that i should account for ?

Find most significant bit in Swift

I need to find the value (or position) of the most significant bit (MSB) of an integer in Swift.
Eg:
Input number: 9
Input as binary: 1001
MS value as binary: 1000 -> (which is 8 in decimal)
MS position as decimal: 3 (because 1<<3 == 1000)
Many processors (Intel, AMD, ARM) have instructions for this. In c, these are exposed. Are these instructions similarly available in Swift through a library function, or would I need to implement some bit twiddling?
The value is more useful in my case.
If a position is returned, then the value can be easily derived by a single shift.
Conversely, computing position from value is not so easy unless a fast Hamming Weight / pop count function is available.
You can use the flsl() function ("find last set bit, long"):
let x = 9
let p = flsl(x)
print(p) // 4
The result is 4 because flsl() and the related functions number the bits starting at 1, the least significant bit.
On Intel platforms you can use the _bit_scan_reverse intrinsic,
in my test in a macOS application this translated to a BSR
instruction.
import _Builtin_intrinsics.intel
let x: Int32 = 9
let p = _bit_scan_reverse(x)
print(p) // 3
You can use the the properties leadingZeroBitCount and trailingZeroBitCount to find the Most Significant Bit and Least Significant Bit.
For example,
let i: Int = 95
let lsb = i.trailingZeroBitCount
let msb = Int.bitWidth - 1 - i.leadingZeroBitCount
print("i: \(i) = \(String(i, radix: 2))") // i: 95 = 1011111
print("lsb: \(lsb) = \(String(1 << lsb, radix: 2))") // lsb: 0 = 1
print("msb: \(msb) = \(String(1 << msb, radix: 2))") // msb: 6 = 1000000
If you look at the disassembly(ARM Mac) in LLDB for the Least Significant Bit code, it uses a single instruction, clz, to count the zeroed bits. (ARM Reference)
** 15 let lsb = i.trailingZeroBitCount
0x100ed947c <+188>: rbit x9, x8
0x100ed9480 <+192>: clz x9, x9
0x100ed9484 <+196>: mov x10, x9
0x100ed9488 <+200>: str x10, [sp, #0x2d8]

Swift Sensortag 2.0 Write Bits to BLE

Pretty basic question here:
I'm currently trying to control a sensortag 2.0 via Swift 3.0.
I'm trying to simultaneously turn on the acc, gyro, and magnetometer.
According to Texas Instruments documentation, the following applies for the IMU:
Axis enable bits:gyro-z=0,gyro-y,gyro-x,acc-z=3,acc-y,acc-x,mag=6 Range: bit 8,9
I have written "0x023F" in the following manner, which turns on the gyro and the accelerometer with great success.
let value = OperationDataHolder(data:[0x023F])
var parameter = 0x023F
let data = NSData(bytes: &parameter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
However, I'm not able to figure out the value to write to turn turn on all 3 units simultaneously. Would someone be able to provide me with this value?
Thanks!
When you convert the current value you are using (0x023F) to binary, you get 0b1000111111. Each of the bits represents the on/off (on=1/off=0) state of a given sensor component.
If you read the binary number from right to left, and map each bit by referencing the table below, you will see that the gyro z/y/x and accelerometer z/y/x are all enabled. If you want to enable the magnetometer, simply change 'bit 6' to a '1' and convert that binary number to a hexadecimal number.
So, Google says: 0b1001111111 is 0x027F in hexadecimal
Mapping:
bit 0 => gyro z-axis
bit 1 => gyro y-axis
bit 2 => gyro x-axis
bit 3 => acc z-axis
bit 4 => acc y-axis
bit 5 => acc x-axis
bit 6 => mag (enables all axes)
bit 7 => Wake-on-motion enable
bits 8 & 9 => Accelerometer range
bits 10-15 => not used
For more info about the mapping (i.e. what bits 8 & 9 do), see the Sensor Tag Wiki Page
Building on peters answer, the swifty way to do this is with an option set, which is admittedly more work up front, but much more readable than hex:
struct SensorOptions: OptionSet {
let rawValue: Int32
static let gyroZ = SensorOptions(rawValue: 1 << 0)
static let gyroY = SensorOptions(rawValue: 1 << 1)
static let gyroX = SensorOptions(rawValue: 1 << 2)
static let accZ = SensorOptions(rawValue: 1 << 3)
static let accY = SensorOptions(rawValue: 1 << 4)
static let accX = SensorOptions(rawValue: 1 << 5)
static let mag = SensorOptions(rawValue: 1 << 6)
static let wakeOnMotion = SensorOptions(rawValue: 1 << 7)
static let accelerometerRange1 = SensorOptions(rawValue: 1 << 8)
static let accelerometerRange2 = SensorOptions(rawValue: 1 << 9)
}
let options: SensorOptions = [.gyroZ, .gyroY, .gyroX, .accZ, .accY, .accX, .mag, .accelerometerRange2]
var parameter = options.rawValue
let data = NSData(bytes: &parameter, length: 2)
self.sensorTagPeripheral.writeValue(data as Data, for: thisCharacteristic, type: CBCharacteristicWriteType.withResponse)
Also if you don't like the option set swift has binary literals so you can write var parameter = 0b1001111111 in your code instead of 0x027F

SecKeyEncrypt returns error -50 and 0 cipherSize

I am porting a PKI api to Swift 2.2 and found the following error. Everything works fine in Objective-C.
The data object to be encrypted is 32 bytes in size. This is the code I am using.
let buflen = 64
var cipherBuffer = UnsafeMutablePointer<UInt8>.alloc(buflen)
cipherBuffer[buflen] = 0 // zero terminate
var cipherLength: Int = 0
var statusCode: OSStatus?
let dataPointer = UnsafePointer<UInt8>(data.bytes)
statusCode = SecKeyEncrypt(publicKey, SecPadding.PKCS1, dataPointer, data.length, cipherBuffer, &cipherLength)
This results in an error -50 and 0 cipher length.
I am doing an hexdump of the public key and the dataPointer to ensure they are OK, but canĀ“t find the problem with the SecKeyEncrypt call
Any help will be appreciated
After some research I found a solution to the problem
I was creating the cipherBuffer using alloc and zero terminating the array, as follows:
let buflen = 64
var cipherBuffer = UnsafeMutablePointer<UInt8>.alloc(buflen)
cipherBuffer[buflen] = 0 // zero terminate
I tried the following approach and it works fine.
let blockSize = SecKeyGetBlockSize(publicKey) //64
var cipherBuffer = [UInt8](count: Int(blockSize), repeatedValue: 0)
Given that both approaches reported a block of 64 bytes with 0x00 using hexDump, I did a quick test and reviewed the previous code and found that removing the line with "cipherBuffer[buflen] = 0" fixes the problem.
It seems that it has to do with the zero termination of the array, or I may have done something weird.

Bluetooth in SWIFT: Get 19 bytes data and convert to UInt

I would like to connect the Concept2 rower to my iPhone.
The corresponding Bluetooth data sheet can be found here : http://www.concept2.com/files/pdf/us/monitors/PM5_BluetoothSmartInterfaceDefinition.pdf
I would like to get back the different data: ElapsedTime, Distance, Split/interval, etc..
From the UUID adress 0X0031 I get a 19 bytes data in the following order:Elapsed Time Lo (0.01 sec lsb), Elapsed Time Mid, Elapsed Time High, Distance Lo (0.1 m lsb), Distance Mid, Distance Hi, ...
So 1 byte corresponds to 1 attribute.
I need to extract the bytes corresponding to the attribute and convert them.
I think all bytes data are unsigned types (for extraction).
The ElapsedTime variable is on 3 bytes. SO to build the ElapsedTime variable I was computing like this:
class func dataToUnsignedBytes8(value:NSData) -> [UInt8]{
let count = value.length
var array = [UInt8](count: count, repeatedValue: 0)
value.getBytes(&array, length: count * sizeof(UInt8))
return array
}
class func getElapsedTime(value : NSData) -> Double {
let dataFromSensor = dataToSignedBytes8(value)
let elapsedTime = Double(dataFromSensor[2] * 65536 + dataFromSensor[1]*256 + dataFromSensor[0])
return elapsedTime
}
But I'm not sure about what I'm doing.
Does the ElapsedTime_Hi byte is at index 3 of dataFromSensor, ElapsedTime_Mid is at index 2 of dataFromSensor and ElapsedTime_Lo at index 0 dataFromSensor ?
What is the best way to extract the corresponding byte for other attributes ?
Thank you in advance
Regards