/******************************************************************************* * Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. * * The information contained herein is property of Nordic Semiconductor ASA. * Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. * Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided. * This heading must NOT be removed from the file. ******************************************************************************/ package no.nordicsemi.android.mcp.ble.parser.gap; import no.nordicsemi.android.mcp.adapter.Device; import no.nordicsemi.android.mcp.ble.AppearanceLibrary; public class ServicesParser { public static void parseCompleteList16UUID(final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 2) builder.append(String.format("0x%04X", decodeUuid16(data, start + i)) + ", "); builder.setLength(builder.length() - 2); union.addData("Services Complete List UUID 16", builder.toString()); } public static void parseMoreAvailable16UUID(final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 2) builder.append(String.format("0x%04X", decodeUuid16(data, start + i)) + ", "); builder.setLength(builder.length() - 2); union.addData("Services More Available UUID 16", builder.toString()); } public static void parseSolicitation16UUID(final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 2) builder.append(String.format("0x%04X", decodeUuid16(data, start + i)) + ", "); builder.setLength(builder.length() - 2); union.addData("Services Solicitation UUID 16", builder.toString()); } public static void parseCompleteList32UUID(final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 4) builder.append(String.format("0x%08X", decodeUuid32(data, start + i)) + ", "); builder.setLength(builder.length() - 2); union.addData("Services Complete List UUID 32", builder.toString()); } public static void parseMoreAvailable32UUID(final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 4) builder.append(String.format("0x%08X", decodeUuid32(data, start + i)) + ", "); builder.setLength(builder.length() - 2); union.addData("Services More Available UUID 32", builder.toString()); } public static void parseCompleteList128UUID(final Device device, final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 16) { final int part0 = decodeUuid32(data, start + i + 12); final int part1 = decodeUuid32(data, start + i + 8); final int part2 = decodeUuid32(data, start + i + 4); final int part3 = decodeUuid32(data, start + i + 0); updateAppearance(device, part0, part1, part2, part3); builder.append(String.format("0x%08X%08X%08X%08X", part0, part1, part2, part3) + ", "); } builder.setLength(builder.length() - 2); union.addData("Services Complete List UUID 128", builder.toString()); } public static void parseMoreAvailable128UUID(final Device device, final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 16) { final int part0 = decodeUuid32(data, start + i + 12); final int part1 = decodeUuid32(data, start + i + 8); final int part2 = decodeUuid32(data, start + i + 4); final int part3 = decodeUuid32(data, start + i + 0); updateAppearance(device, part0, part1, part2, part3); builder.append(String.format("0x%08X%08X%08X%08X", part0, part1, part2, part3) + ", "); } builder.setLength(builder.length() - 2); union.addData("Services More Available UUID 128", builder.toString()); } public static void parseSolicitation128UUID(final Device device, final Device.DataUnion union, final byte[] data, final int start, final int length) { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i += 16) { final int part0 = decodeUuid32(data, start + i + 12); final int part1 = decodeUuid32(data, start + i + 8); final int part2 = decodeUuid32(data, start + i + 4); final int part3 = decodeUuid32(data, start + i + 0); updateAppearance(device, part0, part1, part2, part3); builder.append(String.format("0x%08X%08X%08X%08X", part0, part1, part2, part3) + ", "); } builder.setLength(builder.length() - 2); union.addData("Services Solicitation UUID 128", builder.toString()); } private static void updateAppearance(final Device device, final int part0, final int part1, final int part2, final int part3) { if (part0 == 0x00001530 && part1 == 0x1212EFDE && part2 == 0x1523785F && part3 == 0xEABCD123) device.setAppearance(AppearanceLibrary.APPEARANCE_DFU); if (part1 == 0x6E7D4601 && part2 == 0xBDA2BFFA && part3 == 0xA68956BA) // part 0 is not fixed device.setAppearance(AppearanceLibrary.APPEARANCE_FITBIT); } private static short decodeUuid16(final byte[] data, final int start) { final int b1 = data[start] & 0xff; final int b2 = data[start + 1] & 0xff; return (short) (b2 << 8 | b1 << 0); } private static int decodeUuid32(final byte[] data, final int start) { final int b1 = data[start + 0] & 0xff; final int b2 = data[start + 1] & 0xff; final int b3 = data[start + 2] & 0xff; final int b4 = data[start + 3] & 0xff; return b4 << 24 | b3 << 16 | b2 << 8 | b1 << 0; } }