Extract data from kCBAdvDataManufacturerData on Swift - ios

I have a TI sensor Tag as a peripheral that broadcasts BLE data in the form of kCBAdvDataManufacturerData. I would like to extract different values from this data in iOS.
I am executing the following in Swift:
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
for (index, foundPeripheral) in peripherals.enumerated(){
if foundPeripheral.peripheral?.identifier == peripheral.identifier{
peripherals[index].lastRSSI = RSSI
print("AdvertisementData:\(advertisementData)")
return
}
}
let isConnectable = advertisementData["kCBAdvDataIsConnectable"] as! Bool
let displayPeripheral = DisplayPeripheral(peripheral: peripheral, lastRSSI: RSSI, isConnectable: isConnectable)
peripherals.append(displayPeripheral)
tableView.reloadData()
}
}
And this is what I see in the console:
AdvertisementData:["kCBAdvDataIsConnectable": 0, "kCBAdvDataManufacturerData": <0d00fe05 0c6f32>, "kCBAdvDataLocalName": CLIMBC]
The data that I am interested in decoding is kCBAdvDataManufacturerData : <0d00fe05 0c6f32> and displaying each field on the screen.
Specifically, this is what the numbers represent in my case:
0d00 - TI manufacturer ID
fe - the node ID that I have given
05 - state of the node (something that remains constant
c6f - is the sensor tag battery voltage
32- is the BLE packet counter.
In Android I am able to decode as following:
private static String getNodeIdFromRawPacket(byte[] manufSpecField) {
if(manufSpecField != null && manufSpecField.length > 1) {
return String.format("%02X", manufSpecField[0]);
}else{
return null;
}
}
private static int getNodeBatteryVoltageFromRawPacket(byte[] manufSpecField){
if(manufSpecField != null && manufSpecField.length > 4) {
return (((((int) manufSpecField[manufSpecField.length - 3]) << 24) >>> 24) << 8) + ((((int) manufSpecField[manufSpecField.length - 2]) << 24) >>> 24);
}else{
return 0;
}
}
private byte[] extractManufacturerSpecificData(byte[] scanRecord, int manufacturer_id){
if(scanRecord != null) {
int ptr = 0;
while (ptr < scanRecord.length && scanRecord[ptr] != 0) {
int field_length = scanRecord[ptr];
if (scanRecord[ptr + 1] == (byte) (0xFF)) { //this is true when the manufacturer specific data field has been found
if (((scanRecord[ptr + 3] << 8) + scanRecord[ptr + 2]) == manufacturer_id) {
byte[] manufacturerSpecificData = new byte[field_length - 3];
System.arraycopy(scanRecord, ptr + 4, manufacturerSpecificData, 0, field_length - 3);
return manufacturerSpecificData;
}
}
ptr += (field_length + 1);
}
return null;
}else{
return null;
}
}
};
How exactly can I achieve this? I am new to Swift that is why I am finding some difficulties. Any code snippet will be most welcome.

Seeing the output of your console, advertisementData["kCBAdvDataManufacturerData"] seems to be an NSData containing 7 bytes. You can easily access it as a Swift Data, and each byte in a Data can be accessed with subscript:
if let manufacturerData = advertisementData["kCBAdvDataManufacturerData"] as? Data {
assert(manufacturerData.count >= 7)
//0d00 - TI manufacturer ID
//Constructing 2-byte data as little endian (as TI's manufacturer ID is 000D)
let manufactureID = UInt16(manufacturerData[0]) + UInt16(manufacturerData[1]) << 8
print(String(format: "%04X", manufactureID)) //->000D
//fe - the node ID that I have given
let nodeID = manufacturerData[2]
print(String(format: "%02X", nodeID)) //->FE
//05 - state of the node (something that remains constant
let state = manufacturerData[3]
print(String(format: "%02X", state)) //->05
//c6f - is the sensor tag battery voltage
//Constructing 2-byte data as big endian (as shown in the Java code)
let batteryVoltage = UInt16(manufacturerData[4]) << 8 + UInt16(manufacturerData[5])
print(String(format: "%04X", batteryVoltage)) //->0C6F
//32- is the BLE packet counter.
let packetCounter = manufacturerData[6]
print(String(format: "%02X", packetCounter)) //->32
}

Here is an implementation of swift 3 Data method subdata with an example of a string converted to data and then split out to bytes that you can convert back to strings:
let input = "505450578"
let data = input.data(using: .utf8)
let manufacturerId:Range<Int> = 0..<2
let nodeId:Range<Int> = 2..<4
let nodeState:Range<Int> = 4..<5
let voltage:Range<Int> = 5..<6
let packetCounter:Range<Int> = 6..<9
let subdata1 = data?.subdata(in: manufacturerId)
let subdata2 = data?.subdata(in: nodeId)
let subdata3 = data?.subdata(in: nodeState)
let subdata4 = data?.subdata(in: voltage)
let subdata5 = data?.subdata(in: packetCounter)
//Results from original given string
let str1 = String(data: subdata1!, encoding:.utf8) //50
let str2 = String(data: subdata2!, encoding:.utf8) //54
let str3 = String(data: subdata3!, encoding:.utf8) //5
let str4 = String(data: subdata4!, encoding:.utf8) //0
let str5 = String(data: subdata5!, encoding:.utf8) //578

Updated for Swift:
let yourServiceUUIDString = "FFF0"
if let mAdvData = advertisementData["kCBAdvDataServiceUUIDs"] as? [AnyObject], (mAdvData.contains { ($0 as? CBUUID)?.uuidString == yourServiceUUIDString}) {
print("BLE device found..!")
}

Related

Apple in app provisioning 'Could not add card'

I am implementing apple in-app provisioning and I follow all steps in the apple guide but in the end, I get a message 'Could not add card' but don't have any error throw this process.
This is how I create PKAddPaymentPassViewController
let cardInfoPass = PKAddPaymentPassRequestConfiguration.init(encryptionScheme: PKEncryptionScheme.ECC_V2);
cardInfoPass?.cardholderName = cardholderName as? String; //The name of the person as shown on the card.
cardInfoPass?.primaryAccountSuffix = primaryAccountSuffix as? String; //The last four or five digits of the card’s number.
cardInfoPass?.localizedDescription = localizedDescription as? String; //A short description of the card.
cardInfoPass?.paymentNetwork = PKPaymentNetwork.masterCard;
cardInfoPass?.primaryAccountIdentifier = primaryAccountIdentifier as? String; // A primary account identifier, used to filter out pass libraries.
cardholderName is the name written on the card
primaryAccountSuffix last 4 digit written on the card
localizedDescription bank name
paymentNetwork we are using master card
primaryAccountIdentifier it is number from iTunes something light this 1MNJDDA667.com.bank.package.name
I think this part is correct I can open the apple wallet modal and all this data are there but when I continue in a modal on the end I need to get certificate and send this certificate to our BE and be should send me back 3 values and they send it to me
...
let certificateLeaf = certificates[0].base64EncodedString();
let certificateSubCA = certificates[1].base64EncodedString();
let nonceString = nonce.base64EncodedString();
let nonceSignature = nonceSignature.base64EncodedString();
...
let reqDataDic: [String: Any] = [
"cardId": cardId,
"applePublicCertificate": certificateSubCA,
"nonce": nonceString,
"nonceSignature": nonceSignature,
"customerId": customerId,
"deviceId": deviceId,
]
....
var request = URLRequest(url: url)
request.httpMethod = "POST"
....
request.httpBody = try? JSONSerialization.data(withJSONObject: reqDataDic, options: .prettyPrinted)
UPDATE2: we are now sending nonce and nonceSignature as HEX like this
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
return self.map { String(format: format, $0) }.joined()
}
}
...
let nonceData = Data(bytes: nonce)
let nonceHex = nonceData.hexEncodedString();
let nonceSignatureData = Data(bytes: nonceSignature)
let nonceSignatureHex = nonceSignatureData.hexEncodedString();
BE send me back all values that I need: activationData, ephemeralPublicKey, encryptedPassData it returns it as a JSON object so I need to convert it to Data and all these values put into handler
this is how I am putting data to handler:
if let dictionaryJson = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] {
let activationDataString = dictionaryJson["activationData"] as! String;
let ephemeralPublicKeyString = dictionaryJson["ephemeralPublicKey"] as! String;
let encryptedPassDataString = dictionaryJson["encryptedPassData"] as! String;
let activationData = activationDataString.data(using: .utf8)
let ephemeralPublicKey = Data(base64Encoded: ephemeralPublicKeyString)
let encryptedPassData = Data(base64Encoded: encryptedPassDataString)
let paymentPassRequest = PKAddPaymentPassRequest.init()
paymentPassRequest.activationData = activationData;
paymentPassRequest.encryptedPassData = encryptedPassData;
paymentPassRequest.ephemeralPublicKey = ephemeralPublicKey;
handler(paymentPassRequest)
}
I fill all data into paymentPassRequest and all looks ok xCode is not complaining.
And at this moment apple wallet shows an alert dialog with Could not add a card with 2 buttons try it later or try it again ....
I have a card whitelisted on the MasterCard side
I tried it on simulators, real devices, and also on app in TestFlight
UPDATE:
We found an error from the Apple
Response:
https://nc-pod4-smp-device.apple.com:443/broker/v4/devices/042D1xxxxxxxxxxxxx2C52/cards 500
{
Connection = close;
"Content-Length" = 81;
"Content-Type" = "application/json";
Date = "Thu, 08 Jul 2021 08:35:25 GMT";
Vary = "accept-language";
"X-Pod" = "nc-pod4";
"X-Pod-Region" = "paymentpass.com.apple";
"x-conversation-id" = b2axxxxxxxxxxx9e6a4d;
}
{
statusCode = 500;
statusMessage = "Broker Service Response exception";
}
you are encoding nonce, nonce signature with Hex format for sending it to your server, and after getting the response back, you are trying to convert them with base64 and utf8. Try with Hex, it should work.
We are using the below conversions
- (NSData *)dataFromHexString:(NSString *)string
{
string = [string lowercaseString];
NSMutableData *data= [NSMutableData new];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i = 0;
int length = string.length;
while (i < length-1) {
char c = [string characterAtIndex:i++];
if (c < '0' || (c > '9' && c < 'a') || c > 'f')
continue;
byte_chars[0] = c;
byte_chars[1] = [string characterAtIndex:i++];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
return data;
}
-(NSMutableString *) convertToString:(NSData *)data{
NSUInteger capacity = data.length * 2;
NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity];
const unsigned char *buf = data.bytes;
NSInteger i;
for (i=0; i<data.length; ++i) {
[sbuf appendFormat:#"%02x", (NSUInteger)buf[i]];
}
return sbuf;
}
let activationData = activationDataString.data(using: .utf8)
I think this encoded is only for VISA.
For MasterCard it has to be base64:
let activationData = Data(base64Encoded: activationDataString)
I ran into this exact issue implementing our Card Provisioning. In our case we had to do both of the following:
Make sure our PKAddPaymentPassRequest fields were all set properly. All three of the fields we were provided by our API (activationData, encryptedPassData, ephemeralPublicKey) were base64 encoded so they all had to be converted to Data's as such: paymentPassRequest.ephemeralPublicKey = Data(base64Encoded: <YOUR EPHEMERAL PUBLIC KEY STRING>, options: [])
We had to create new TestFlight builds in order to fully test this workflow. I ran into that exact same 500 response from Apple anytime I tried profiling or running the app from Xcode directly, even if it was on a physical device. It wasn't until I ran the TestFlight build that it finally worked properly.

Deserialize BinaryData and mapping to an object

I have a small project where I have a list with questions (96 questions).
I try to serialize that list of questions into a BinaryData and to save that result in CoreData.
After I want to deserialize that BinaryData from CoreData and to map the values to an object.
The problem is that my serialization I think is working, but the deserialization is not working for some reason.
This line of code is not called when I run the code and I don't know why:
https://github.com/tygruletz/AddTagsForRows/blob/master/PreloadQuestions/Controller/Communication/TTable.swift#L457
To generate a report in CoreData just click Next-> Next-> Finish.
Here is the code for deserialization:
func deStreamBin(stream: InputStream, format: EStreamFormat){
var protocolByte: UInt8 = 0
var columns: UInt16 = 0
var rows: UInt32 = 0
var tableFlag: ETableFlags
//We should scroll through 0's until we find '1' indicating the start of a table
while protocolByte != 0x01 {
protocolByte = deserializeByte(stream: stream)
}
// Header
_ = deserializeUInt32(stream: stream)
columns = deserializeUInt16(stream: stream)
rows = deserializeUInt32(stream: stream)
print("Number of rows in TTable: \(rows)")
tableFlag = ETableFlags(rawValue: UInt(deserializeUInt16(stream: stream))) ?? ETableFlags.none // 0x0001 = Exception, 0x002 = Interrupt
_ = deserializeByte(stream: stream) // Flags (0x01 = Meta, 0x02 = Last Row, 0x00 = The rest)
// Read the Meta Details
var tMeta: [TMeta] = []
for _ in 0..<columns {
guard let type = EMeta(rawValue: deserializeString(stream: stream, length: 1)) else {return}
var name = ""
if format == EStreamFormat.bin1 {
let nameLength = Int(deserializeByte(stream: stream))
name = deserializeString(stream: stream, length: nameLength)
}
else{
// No names for the bin2
}
tMeta.append(TMeta(type: type, name: name))
}
self.tMeta = tMeta
self.flags = tableFlag
for _ in 0..<rows {
let row: TRow = TRow(tMeta: tMeta)
_ = deserializeUInt32(stream: stream) // Row Number
_ = deserializeByte(stream: stream) // Flags (0x01 = Meta, 0x02 = Last Row, 0x00 = The rest)
for i in 0..<tMeta.count {
let m: TMeta = tMeta[i]
switch m.type {
// Integer (Int32)
case EMeta.i:
row.cell[i] = TCell(i: Int(deserializeInt32(stream: stream)))
// Boolean
case EMeta.b:
row.cell[i] = TCell(b: deserializeBoolean(stream: stream))
// String (length as UInt32, followed by array of chars)
case EMeta.s:
let nLenString = Int(deserializeUInt32(stream: stream))
row.cell[i] = TCell(s: deserializeString(stream: stream, length: nLenString))
// DateTime (BCD Array: YY YY MM DD hh mm ss)
case EMeta.t:
row.cell[i] = TCell(date: deserializeDateTime(stream: stream) ?? Date())
// Database Bytes (Length as Int32, followed by array of bytes)
case EMeta.z:
let nLenBytes = Int(deserializeUInt32(stream: stream))
row.cell[i] = TCell(data: deserializeByteArray(stream: stream, lenght: Int32(nLenBytes)))
// Double (IEEE 8-byte double)
case EMeta.d:
row.cell[i] = TCell(d: deserializeDouble(stream: stream))
// Single Byte
case EMeta.u:
row.cell[i] = TCell(b: deserializeByte(stream: stream))
}
}
do {
try add(row: row)
} catch{
print("deStreamBin: Can't add the row in tMeta: \(error)")
}
}
}
Please help me to deserialize my BinaryData to be able to map the values to an object.
Thanks in advance !

iOS - VialerSIP - Send DTMF via Inband

I'm using VialerSIP for my iOS VOIP app.
I'm trying to send DTMF via inband instead of the method:
- (BOOL)sendDTMF:(NSString * _Nonnull)character error:(NSError * _Nullable * _Nullable)error;
in VSLCall class.
Because, it seems some of countries (include mine) does not support :
PJMEDIA_RTP_PT_TELEPHONE_EVENTS 101
So, I decide to send DTMF via inband with this solution:
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwibuKSeg4HgAhUM6LwKHT33DOAQygQwAHoECAQQCA&url=https%3A%2F%2Ftrac.pjsip.org%2Frepos%2Fwiki%2FFAQ%23inband-dtmf&usg=AOvVaw3fYXthR0Z6btU2yOWovNIF
like this (in swift):
private func generateTone(_ callId: pjsua_call_id) -> UnsafeMutableRawPointer {
var ci = pjsua_call_info()
let pool = pjsua_pool_create("MyCall", 512, 512)!
let cd = pj_pool_zalloc(pool, MemoryLayout<MyCallData>.size)!
cd.storeBytes(of: pool.pointee, as: pj_pool_t.self)
let aPool = cd.assumingMemoryBound(to: pj_pool_t.self)
var aTonegen: UnsafeMutablePointer<pjmedia_port>? = cd.assumingMemoryBound(to: pjmedia_port.self)
let aToneslot = cd.assumingMemoryBound(to: pjsua_conf_port_id.self)
pjmedia_tonegen_create(aPool, 8000, 1, 160, 16, 0, &aTonegen)
pjsua_conf_add_port(aPool, aTonegen!, aToneslot)
pjsua_call_get_info(callId, &ci)
pjsua_conf_connect(aToneslot.pointee, ci.conf_slot)
pjsua_call_set_user_data(callId, cd)
return cd
}
private func play(callId: pjsua_call_id, digits: String) {
let cString = digits.cString(using: String.defaultCStringEncoding)!
let newString: String = NSString(bytes: cString, length: Int(digits.count), encoding:String.Encoding.ascii.rawValue)! as String
let key2Pointer = UnsafePointer<Int8>(newString)
let cd = pjsua_call_get_user_data(callId) ?? generateTone(callId)
let tonegen = cd.assumingMemoryBound(to: pjmedia_port.self)
var tone = pjmedia_tone_digit(digit: key2Pointer.pointee, on_msec: 100, off_msec: 200, volume: 0)
pjmedia_tonegen_play_digits(tonegen, 1, &tone, 0)
}
private func deinitTone(callId: pjsua_call_id) {
guard let cd = pjsua_call_get_user_data(callId) else { return }
let aPool = cd.assumingMemoryBound(to: pj_pool_t.self)
let aTonegen = cd.assumingMemoryBound(to: pjmedia_port.self)
let aToneslot = cd.assumingMemoryBound(to: pjsua_conf_port_id.self)
pjsua_conf_remove_port(aToneslot.pointee)
pjmedia_port_destroy(aTonegen)
pj_pool_release(aPool)
pjsua_call_set_user_data(callId, nil)
}
then, I tried to send DTMF using:
self.play(callId: pjsua_call_id(self.activeCall.callId), digits: numberString)
But, when I call this function, the CPU is overflowed. I don't know why :(.
Please give me any advice, it will be huge help to solve my problem.
Thank you.

Generate UUID from name space?

Trying to generate a client Id, based on 2 unique strings.
This should end up being the same UUID as generated in the server, from same I'ds.
With Javascript it looks something like this:
uuidv5(id1 + id2 , uuidv5.DNS);
Can't seem to find a way of generating this on Swift, NSUUID only can generate a UUID from nothing
NSUUID().uuidString
I am looking for something like this:
NSUUID(namespace: id1 + id2).uuidString
Edit
Example:
let sorted = ["5a23dbfb2626b400190998fc", "5pCAvA7h8k9JuErRn"]
let appended = sorted.seperaredStringBy("-")
let result = uuidv5(appended , uuidv5.DNS)
//results:
2522b097-8532-548e-a18b-9366c6511b5e
The Swift standard library or the Foundation framework have no built-in method for version 5 UUIDs, as far as I know.
Here is a possible implementation for version 3 and version 5 UUIDs, taken from the description at Generating v5 UUID. What is name and namespace? and the reference implementation in RFC 4122.
(Updated for Swift 4 and later.)
import Foundation
import CommonCrypto
extension UUID {
enum UUIDVersion: Int {
case v3 = 3
case v5 = 5
}
enum UUIDv5NameSpace: String {
case dns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
case url = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
case oid = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
case x500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
}
init(version: UUIDVersion, name: String, nameSpace: UUIDv5NameSpace) {
// Get UUID bytes from name space:
var spaceUID = UUID(uuidString: nameSpace.rawValue)!.uuid
var data = withUnsafePointer(to: &spaceUID) { [count = MemoryLayout.size(ofValue: spaceUID)] in
Data(bytes: $0, count: count)
}
// Append name string in UTF-8 encoding:
data.append(contentsOf: name.utf8)
// Compute digest (MD5 or SHA1, depending on the version):
var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> Void in
switch version {
case .v3:
_ = CC_MD5(ptr.baseAddress, CC_LONG(data.count), &digest)
case .v5:
_ = CC_SHA1(ptr.baseAddress, CC_LONG(data.count), &digest)
}
}
// Set version bits:
digest[6] &= 0x0F
digest[6] |= UInt8(version.rawValue) << 4
// Set variant bits:
digest[8] &= 0x3F
digest[8] |= 0x80
// Create UUID from digest:
self = NSUUID(uuidBytes: digest) as UUID
}
}
Example 1 (Your case):
let uuid = UUID(version: .v5, name: "5a23dbfb2626b400190998fc-5pCAvA7h8k9JuErRn", nameSpace: .dns)
print(uuid) // 2522B097-8532-548E-A18B-9366C6511B5E
Example 2 (From Appendix B in RFC 4122, as corrected in the Errata):
let uuid = UUID(version: .v3, name: "www.widgets.com", nameSpace: .dns)
print(uuid) //3D813CBB-47FB-32BA-91DF-831E1593AC29
the objc version, in case someone need it.
+ (CBUUID *)UUIDWithNamespace:(NSString *)namespace name:(NSString *)name version:(int)version
{
if (namespace.length <= 0 || name == nil ) { return nil; }
if (!(version == 3 || version == 5)) { return nil; }
CBUUID *namespaceUUID = [CBUUID UUIDWithString:namespace];
if (namespaceUUID == nil) { return nil; }
NSMutableData *data = [[NSMutableData alloc] init];
[data appendData:namespaceUUID.data];
[data appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];
unsigned char hash[CC_SHA1_DIGEST_LENGTH];
if (version == 3) {
CC_MD5(data.bytes, (int)data.length, hash);
} else if (version == 5) {
CC_SHA1(data.bytes, (int)data.length, hash);
}
unsigned char result[16];
memcpy(result, hash, 16);
result[6] &= 0x0F;
result[6] |= (((unsigned char)version) << 4);
result[8] &= 0x3F;
result[8] |= 0x80;
return [CBUUID UUIDWithData:[NSData dataWithBytes:result length:16]];
}

How can i parse MIDIRawData (SysEx) out of a midiEvent in Swift 3? (under iOS)

i have big trouble parsing MIDIRawData (SysEx Data) out of a midi-event of a MusicTrack (XCode8.1, iOS10.1)
I managed to parse MidiNoteMessages and MidiChannelMessages with the following code (Swift3):
(eventType and eventData was extracted with MusicEventIteratorGetEventInfo…)
switch eventType {
case kMusicEventType_MIDINoteMessage:
let temp = eventData?.bindMemory(to: MIDINoteMessage.self, capacity: 5)
let channel = temp!.pointee.channel
let note = temp!.pointee.note
let vel = temp!.pointee.velocity
let relVel = temp!.pointee.releaseVelocity
let duration = temp!.pointee.duration
case kMusicEventType_MIDIChannelMessage:
let temp = eventData?.bindMemory(to: MIDIChannelMessage.self, capacity: 4)
let status = temp!.pointee.status & 0b11110000
let channel = temp!.pointee.status & 0b0000111
let data1 = temp!.pointee.data1
let data2 = temp!.pointee.data2
let reserved = temp!.pointee.reserved
In the following case i get the right length of the data, but data itself just consists of the first entry of the SysEx Message
case kMusicEventType_MIDIRawData:
debug.printDebugText(text: "kMusicEventType_MIDIRawData", ToConsole: debugViewGlobal)
let raw = eventData?.bindMemory(to: MIDIRawData.self, capacity: 2)
let length = raw!.pointee.length
let data = raw!.pointee.data // (should be of Type (UInt8)… but is just one UInt8 Value
How can i get the rest of the SysEs Message ?
How do i have to handle (UInt8) ?
Thank You,
Sebastian

Resources