diff --git a/wifi/java/android/net/wifi/nan/LvBufferUtils.java b/wifi/java/android/net/wifi/nan/LvBufferUtils.java new file mode 100644 index 0000000000000..eb5607052ceb3 --- /dev/null +++ b/wifi/java/android/net/wifi/nan/LvBufferUtils.java @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.nan; + +import android.annotation.Nullable; + +import libcore.io.Memory; + +import java.nio.ByteOrder; +import java.util.Iterator; + +/** + * Utility class to construct and parse byte arrays using the LV format - + * Length/Value format. The utilities accept a configuration of the size of + * the Length field. + * + * @hide PROPOSED_NAN_API + */ +public class LvBufferUtils { + private LvBufferUtils() { + // no reason to ever create this class + } + + /** + * Utility class to construct byte arrays using the LV format - Length/Value. + *
+ * A constructor is created specifying the size of the Length (L) field. + *
+ * The byte array is either provided (using + * {@link LvBufferUtils.LvConstructor#wrap(byte[])}) or allocated (using + * {@link LvBufferUtils.LvConstructor#allocate(int)}). + *
+ * Values are added to the structure using the {@code LvConstructor.put*()} + * methods. + *
+ * The final byte array is obtained using {@link LvBufferUtils.LvConstructor#getArray()}.
+ */
+ public static class LvConstructor {
+ private TlvBufferUtils.TlvConstructor mTlvImpl;
+
+ /**
+ * Define a LV constructor with the specified size of the Length (L) field.
+ *
+ * @param lengthSize Number of bytes used for the Length (L) field.
+ * Values of 1 or 2 bytes are allowed.
+ */
+ public LvConstructor(int lengthSize) {
+ mTlvImpl = new TlvBufferUtils.TlvConstructor(0, lengthSize);
+ }
+
+ /**
+ * Set the byte array to be used to construct the LV.
+ *
+ * @param array Byte array to be formatted.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor wrap(@Nullable byte[] array) {
+ mTlvImpl.wrap(array);
+ return this;
+ }
+
+ /**
+ * Allocates a new byte array to be used ot construct a LV.
+ *
+ * @param capacity The size of the byte array to be allocated.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor allocate(int capacity) {
+ mTlvImpl.allocate(capacity);
+ return this;
+ }
+
+ /**
+ * Copies a byte into the LV array.
+ *
+ * @param b The byte to be inserted into the structure.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putByte(byte b) {
+ mTlvImpl.putByte(0, b);
+ return this;
+ }
+
+ /**
+ * Copies a byte array into the LV.
+ *
+ * @param array The array to be copied into the LV structure.
+ * @param offset Start copying from the array at the specified offset.
+ * @param length Copy the specified number (length) of bytes from the
+ * array.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putByteArray(@Nullable byte[] array, int offset,
+ int length) {
+ mTlvImpl.putByteArray(0, array, offset, length);
+ return this;
+ }
+
+ /**
+ * Copies a byte array into the LV.
+ *
+ * @param array The array to be copied (in full) into the LV structure.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putByteArray(int type, @Nullable byte[] array) {
+ return putByteArray(array, 0, (array == null) ? 0 : array.length);
+ }
+
+ /**
+ * Places a zero length element (i.e. Length field = 0) into the LV.
+ *
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putZeroLengthElement() {
+ mTlvImpl.putZeroLengthElement(0);
+ return this;
+ }
+
+ /**
+ * Copies short into the LV.
+ *
+ * @param data The short to be inserted into the structure.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putShort(short data) {
+ mTlvImpl.putShort(0, data);
+ return this;
+ }
+
+ /**
+ * Copies integer into the LV.
+ *
+ * @param data The integer to be inserted into the structure.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putInt(int data) {
+ mTlvImpl.putInt(0, data);
+ return this;
+ }
+
+ /**
+ * Copies a String's byte representation into the LV.
+ *
+ * @param data The string whose bytes are to be inserted into the
+ * structure.
+ * @return The constructor to facilitate chaining
+ * {@code ctr.putXXX(..).putXXX(..)}.
+ */
+ public LvBufferUtils.LvConstructor putString(@Nullable String data) {
+ mTlvImpl.putString(0, data);
+ return this;
+ }
+
+ /**
+ * Returns the constructed LV formatted byte-array. This array is a copy of the wrapped
+ * or allocated array - truncated to just the significant bytes - i.e. those written into
+ * the LV.
+ *
+ * @return The byte array containing the LV formatted structure.
+ */
+ public byte[] getArray() {
+ return mTlvImpl.getArray();
+ }
+ }
+
+ /**
+ * Utility class used when iterating over an LV formatted byte-array. Use
+ * {@link LvBufferUtils.LvIterable} to iterate over array. A {@link LvBufferUtils.LvElement}
+ * represents each entry in a LV formatted byte-array.
+ */
+ public static class LvElement {
+ /**
+ * The Length (L) field of the current LV element.
+ */
+ public int length;
+
+ /**
+ * The Value (V) field - a raw byte array representing the current LV
+ * element where the entry starts at {@link LvBufferUtils.LvElement#offset}.
+ */
+ public byte[] refArray;
+
+ /**
+ * The offset to be used into {@link LvBufferUtils.LvElement#refArray} to access the
+ * raw data representing the current LV element.
+ */
+ public int offset;
+
+ private LvElement(int length, @Nullable byte[] refArray, int offset) {
+ this.length = length;
+ this.refArray = refArray;
+ this.offset = offset;
+ }
+
+ /**
+ * Utility function to return a byte representation of a LV element of
+ * length 1. Note: an attempt to call this function on a LV item whose
+ * {@link LvBufferUtils.LvElement#length} is != 1 will result in an exception.
+ *
+ * @return byte representation of current LV element.
+ */
+ public byte getByte() {
+ if (length != 1) {
+ throw new IllegalArgumentException(
+ "Accesing a byte from a LV element of length " + length);
+ }
+ return refArray[offset];
+ }
+
+ /**
+ * Utility function to return a short representation of a LV element of
+ * length 2. Note: an attempt to call this function on a LV item whose
+ * {@link LvBufferUtils.LvElement#length} is != 2 will result in an exception.
+ *
+ * @return short representation of current LV element.
+ */
+ public short getShort() {
+ if (length != 2) {
+ throw new IllegalArgumentException(
+ "Accesing a short from a LV element of length " + length);
+ }
+ return Memory.peekShort(refArray, offset, ByteOrder.BIG_ENDIAN);
+ }
+
+ /**
+ * Utility function to return an integer representation of a LV element
+ * of length 4. Note: an attempt to call this function on a LV item
+ * whose {@link LvBufferUtils.LvElement#length} is != 4 will result in an exception.
+ *
+ * @return integer representation of current LV element.
+ */
+ public int getInt() {
+ if (length != 4) {
+ throw new IllegalArgumentException(
+ "Accesing an int from a LV element of length " + length);
+ }
+ return Memory.peekInt(refArray, offset, ByteOrder.BIG_ENDIAN);
+ }
+
+ /**
+ * Utility function to return a String representation of a LV element.
+ *
+ * @return String representation of the current LV element.
+ */
+ public String getString() {
+ return new String(refArray, offset, length);
+ }
+ }
+
+ /**
+ * Utility class to iterate over a LV formatted byte-array.
+ */
+ public static class LvIterable implements Iterable
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * Format is an LV byte array - the {@link LvBufferUtils} utility class
* is available to form and parse.
*
* @param txFilter The byte-array containing the LV formatted transmit
@@ -331,7 +331,7 @@ public class PublishConfig implements Parcelable {
* (active subscribers) - in addition to just relying on the service
* name.
*
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * Format is an LV byte array - the {@link LvBufferUtils} utility class
* is available to form and parse.
*
* @param rxFilter The byte-array containing the LV formatted receive
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
index 4e53073c7cb00..fd19ddbb7f242 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -140,8 +140,8 @@ public class SubscribeConfig implements Parcelable {
public String toString() {
return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
- + ", mTxFilter=" + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter)).toString()
- + ", mRxFilter=" + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter)).toString()
+ + ", mTxFilter=" + (new LvBufferUtils.LvIterable(1, mTxFilter)).toString()
+ + ", mRxFilter=" + (new LvBufferUtils.LvIterable(1, mRxFilter)).toString()
+ ", mSubscribeType=" + mSubscribeType + ", mSubscribeCount=" + mSubscribeCount
+ ", mTtlSec=" + mTtlSec + ", mMatchType=" + mMatchStyle
+ ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
@@ -234,11 +234,11 @@ public class SubscribeConfig implements Parcelable {
public void validate() throws IllegalArgumentException {
WifiNanUtils.validateServiceName(mServiceName);
- if (!TlvBufferUtils.isValid(mTxFilter, 0, 1)) {
+ if (!LvBufferUtils.isValid(mTxFilter, 1)) {
throw new IllegalArgumentException(
"Invalid txFilter configuration - LV fields do not match up to length");
}
- if (!TlvBufferUtils.isValid(mRxFilter, 0, 1)) {
+ if (!LvBufferUtils.isValid(mRxFilter, 1)) {
throw new IllegalArgumentException(
"Invalid rxFilter configuration - LV fields do not match up to length");
}
@@ -344,7 +344,7 @@ public class SubscribeConfig implements Parcelable {
* publishers) to determine whether they match - in addition to just
* relying on the service name.
*
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * Format is an LV byte array - the {@link LvBufferUtils} utility class
* is available to form and parse.
*
* @param txFilter The byte-array containing the LV formatted transmit
@@ -364,7 +364,7 @@ public class SubscribeConfig implements Parcelable {
* subscriber to determine whether they match transmitted publish
* packets - in addition to just relying on the service name.
*
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * Format is an LV byte array - the {@link LvBufferUtils} utility class
* is available to form and parse.
*
* @param rxFilter The byte-array containing the LV formatted receive