content: package dev.alt236.bluetoothlelib.device.adrecord;
  
  import android.os.Bundle;
  import android.os.Parcel;
  import android.os.Parcelable;
  
  import java.util.Arrays;
  
  import androidx.annotation.Nullable;
  
  /**
   * Created by Dave Smith
   * Double Encore, Inc.
   * <p>
   * Expanded by Alexandros Schillings
   */
  public final class AdRecord implements Parcelable {
      //	02 # Number of bytes that follow in first AD structure
      //	01 # Flags AD type
      //	1A # Flags value 0x1A = 000011010
      //	   bit 0 (OFF) LE Limited Discoverable Mode
      //	   bit 1 (ON) LE General Discoverable Mode
      //	   bit 2 (OFF) BR/EDR Not Supported
      //	   bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
      //	   bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
      //	1A # Number of bytes that follow in second (and last) AD structure
      //	FF # Manufacturer specific data AD type
      //	4C 00 # Company identifier code (0x004C == Apple)
      //	02 # Byte 0 of iBeacon advertisement indicator
      //	15 # Byte 1 of iBeacon advertisement indicator
      //	e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
      //	00 00 # major
      //	00 00 # minor
      //	c5 # The 2's complement of the calibrated Tx Power
  
  
      /**
       * General FLAGS
       * <p>
       * Description: Flags
       * <p>
       * Information:
       * Bit 0: LE Limited Discoverable Mode
       * Bit 1: LE General Discoverable Mode
       * Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
       * Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
       * Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
       * Bits 5-7 Reserved
       */
      public static final int TYPE_FLAGS = 0x01;
      // SERVICE
      public static final int TYPE_UUID16_INC = 0x02;
      public static final int TYPE_UUID16 = 0x03;
      public static final int TYPE_UUID32_INC = 0x04;
      public static final int TYPE_UUID32 = 0x05;
      public static final int TYPE_UUID128_INC = 0x06;
      public static final int TYPE_UUID128 = 0x07;
      // Local name
      public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
      public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
      // TX Power Level
      public static final int TYPE_TX_POWER_LEVEL = 0x0A;
      // SIMPLE PAIRING OPTIONAL OOB TAGS
      public static final int TYPE_DEVICE_CLASS = 0x0D;
      public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
      public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
      // SECURITY MANAGER TK VALUE
      public static final int TYPE_TK_VALUE = 0x10;
      /* SECURITY MANAGER OOB FLAGS
       *
       * Description: Flag (1 octet)
       *
       * Information:
       * Bit 0: OOB Flags Field: (0 = OOB data not present, 1 = OOB data present)
       * Bit 1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1
       * Bit 2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
       * Bit 3: Address type (0 = Public Address, 1 = Random Address)
       * Bits 4-7 Reserved
       */
      public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
      /* SLAVE CONNECTION INTERVAL RANGE
       *
       * Description: Slave Connection Interval Range
       *
       * Information:
       * The first 2 octets defines the minimum value for the connection interval in the following manner:
       *	connInterval min = Conn_Interval_Min * 1.25 ms
       *	Conn_Interval_Min range: 0x0006 to 0x0C80
       *	Value of 0xFFFF indicates no specific minimum.
       *	Values outside the range are reserved. (excluding 0xFFFF)
       *
       * The second 2 octets defines the maximum value for the connection interval in the following manner:
       *  connInterval max = Conn_Interval_Max * 1.25 ms
       *  Conn_Interval_Max range: 0x0006 to 0x0C80
       *  Conn_Interval_Max shall be equal to or greater
       *  than the Conn_Interval_Min.
       *  Value of 0xFFFF indicates no specific maximum.
       *  Values outside the range are reserved (excluding 0xFFFF)
       */
      public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
      // SERVICE SOLICITATION
      public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
      public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
      /* SERVICE DATA
       *
       * Description: Service Data (2 or more octets)
       * Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
       */
      public static final int TYPE_SERVICE_DATA = 0x16;
      /* MANUFACTURER SPECIFIC DATA
       *
       * Description: Manufacturer Specific Data (2 or more octets)
       * Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
       */
      public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
      public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
          public AdRecord createFromParcel(final Parcel in) {
              return new AdRecord(in);
          }
  
          public AdRecord[] newArray(final int size) {
              return new AdRecord[size];
          }
      };
      private static final String PARCEL_RECORD_DATA = "record_data";
      private static final String PARCEL_RECORD_TYPE = "record_type";
      private static final String PARCEL_RECORD_LENGTH = "record_length";
      /* Model Object Definition */
      private final int mLength;
      private final int mType;
      private final byte[] mData;
  
      public AdRecord(final int length, final int type, final byte[] data) {
          mLength = length;
          mType = type;
          mData = data;
      }
  
      public AdRecord(final Parcel in) {
          final Bundle b = in.readBundle(getClass().getClassLoader());
          mLength = b.getInt(PARCEL_RECORD_LENGTH);
          mType = b.getInt(PARCEL_RECORD_TYPE);
          mData = b.getByteArray(PARCEL_RECORD_DATA);
      }
  
      @Override
      public int describeContents() {
          return 0;
      }
  
      @Nullable
      public byte[] getData() {
          return mData;
      }
  
      public String getHumanReadableType() {
          return getHumanReadableAdType(mType);
      }
  
      public int getLength() {
          return mLength;
      }
  
      public int getType() {
          return mType;
      }
  
      @Override
      public String toString() {
          return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" + getHumanReadableType() + "]";
      }
  
      @Override
      public void writeToParcel(final Parcel parcel, final int arg1) {
          final Bundle b = new Bundle(getClass().getClassLoader());
  
          b.putInt(PARCEL_RECORD_LENGTH, mLength);
          b.putInt(PARCEL_RECORD_TYPE, mType);
          b.putByteArray(PARCEL_RECORD_DATA, mData);
  
          parcel.writeBundle(b);
      }
  
      private static String getHumanReadableAdType(final int type) {
          switch (type) {
              case TYPE_CONNECTION_INTERVAL_RANGE:
                  return "Slave Connection Interval Range";
              case TYPE_DEVICE_CLASS:
                  return "Class of device";
              case TYPE_FLAGS:
                  return "Flags";
              case TYPE_MANUFACTURER_SPECIFIC_DATA:
                  return "Manufacturer Specific Data";
              case TYPE_LOCAL_NAME_COMPLETE:
                  return "Name (Complete)";
              case TYPE_LOCAL_NAME_SHORT:
                  return "Name (Short)";
              case TYPE_SECURITY_MANAGER_OOB_FLAGS:
                  return "Security Manager OOB Flags";
              case TYPE_SERVICE_UUIDS_LIST_128BIT:
                  return "Service UUIDs (128bit)";
              case TYPE_SERVICE_UUIDS_LIST_16BIT:
                  return "Service UUIDs (16bit)";
              case TYPE_SERVICE_DATA:
                  return "Service Data";
              case TYPE_SIMPLE_PAIRING_HASH_C:
                  return "Simple Pairing Hash C";
              case TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
                  return "Simple Pairing Randomizer R";
              case TYPE_TK_VALUE:
                  return "TK Value";
              case TYPE_TX_POWER_LEVEL:
                  return "Transmission Power Level";
              case TYPE_UUID128:
                  return "Complete list of 128-bit UUIDs available";
              case TYPE_UUID128_INC:
                  return "More 128-bit UUIDs available";
              case TYPE_UUID16:
                  return "Complete list of 16-bit UUIDs available";
              case TYPE_UUID16_INC:
                  return "More 16-bit UUIDs available";
              case TYPE_UUID32:
                  return "Complete list of 32-bit UUIDs available";
              case TYPE_UUID32_INC:
                  return "More 32-bit UUIDs available";
              default:
                  return "Unknown AdRecord Structure: " + type;
          }
      }
  }