public static List<AdvertisementRecord> ParseScanRecord(byte[] scanRecord) { var records = new List<AdvertisementRecord>(); if (scanRecord == null) return records; int index = 0; while (index < scanRecord.Length) { byte length = scanRecord[index++]; //Done once we run out of records // 1 byte for type and length-1 bytes for data if (length == 0) break; int type = scanRecord[index]; //Done if our record isn't a valid type if (type == 0) break; if (!Enum.IsDefined(typeof(AdvertisementRecordType), type)) { Trace.Message("Advertisment record type not defined: {0}", type); break; } //data length is length -1 because type takes the first byte byte[] data = new byte[length - 1]; Array.Copy(scanRecord, index + 1, data, 0, length - 1); // don't forget that data is little endian so reverse // Supplement to Bluetooth Core Specification 1 // NOTE: all relevant devices are already little endian, so this is not necessary for any type except UUIDs //var record = new AdvertisementRecord((AdvertisementRecordType)type, data.Reverse().ToArray()); switch ((AdvertisementRecordType)type) { case AdvertisementRecordType.ServiceDataUuid32Bit: case AdvertisementRecordType.SsUuids128Bit: case AdvertisementRecordType.SsUuids16Bit: case AdvertisementRecordType.SsUuids32Bit: case AdvertisementRecordType.UuidCom32Bit: case AdvertisementRecordType.UuidsComplete128Bit: case AdvertisementRecordType.UuidsComplete16Bit: case AdvertisementRecordType.UuidsIncomple16Bit: case AdvertisementRecordType.UuidsIncomplete128Bit: Array.Reverse(data); break; } var record = new AdvertisementRecord((AdvertisementRecordType)type, data); Trace.Message(record.ToString()); records.Add(record); //Advance index += length; } return records; }
public byte[] this[AdvertisementRecord record] { get { switch (record) { case AdvertisementRecord.CompleteLocalName: return(_localName); case AdvertisementRecord.ManufacturerData: return(_manufacturerData); default: return(null); } } }
public byte[] this[AdvertisementRecord record] { get { int i = 0; while (i < _data.Length) { int len = _data[i]; if (len == 0 || i + len >= _data.Length) { break; } if ((AdvertisementRecord)_data[i + 1] == record) { byte[] res = new byte[len - 1]; Array.Copy(_data, i + 2, res, 0, len - 1); return(res); } i += 1 + len; } return(null); } }
static public String DecodeAdvertisement(AdvertisementRecord adv) { switch (adv.Type) { case AdvertisementRecordType.Flags: var x = new String[] { "LE Limited Discoverable Mode", "LE General Discoverable Mode", "BR/EDR Not Supported", "Simultaneous LE and BR/EDR (Controller)", "Simultaneous LE and BR/EDR (Host)" }; return(String.Join(", ", x.Where((_, i) => (adv.Data[0] & (1 << i)) != 0))); case AdvertisementRecordType.UuidsComplete16Bit: case AdvertisementRecordType.UuidsIncomple16Bit: var list = ConvertFromUUID16(adv.Data); return(String.Join(", ", list.Select((guid) => guid.ToString()))); case AdvertisementRecordType.UuidsComplete128Bit: var j = 0; string s = ""; for (; j <= adv.Data.Length - 16; j += 16) { s += fromBleBytes(adv.Data, j).ToString() + "\n"; } s.TrimEnd(new char [] { '\n' }); return(s); case AdvertisementRecordType.ShortLocalName: case AdvertisementRecordType.CompleteLocalName: return(Encoding.UTF8.GetString(adv.Data)); default: return(ByteArrayToString(adv.Data)); } }