Merge "[NAN] Use NAN capability information to validate configurations"
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.java b/wifi/java/android/net/wifi/nan/PublishConfig.java
index 4b67f9a..30c5bc0 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.java
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.java
@@ -182,7 +182,7 @@
      *
      * @hide
      */
-    public void validate() throws IllegalArgumentException {
+    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
         WifiNanUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
@@ -198,6 +198,26 @@
         if (mTtlSec < 0) {
             throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
         }
+
+        if (characteristics != null) {
+            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
+            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
+                throw new IllegalArgumentException(
+                        "Service name longer than supported by device characteristics");
+            }
+            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
+            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
+                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
+                throw new IllegalArgumentException(
+                        "Service specific info longer than supported by device characteristics");
+            }
+            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
+            if (maxMatchFilterLength != 0 && mMatchFilter != null
+                    && mMatchFilter.length > maxMatchFilterLength) {
+                throw new IllegalArgumentException(
+                        "Match filter longer than supported by device characteristics");
+            }
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
index 4352fcf..ea7b8e4 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -209,7 +209,7 @@
      *
      * @hide
      */
-    public void validate() throws IllegalArgumentException {
+    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
         WifiNanUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
@@ -229,6 +229,26 @@
             throw new IllegalArgumentException(
                     "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
         }
+
+        if (characteristics != null) {
+            int maxServiceNameLength = characteristics.getMaxServiceNameLength();
+            if (maxServiceNameLength != 0 && mServiceName.length > maxServiceNameLength) {
+                throw new IllegalArgumentException(
+                        "Service name longer than supported by device characteristics");
+            }
+            int maxServiceSpecificInfoLength = characteristics.getMaxServiceSpecificInfoLength();
+            if (maxServiceSpecificInfoLength != 0 && mServiceSpecificInfo != null
+                    && mServiceSpecificInfo.length > maxServiceSpecificInfoLength) {
+                throw new IllegalArgumentException(
+                        "Service specific info longer than supported by device characteristics");
+            }
+            int maxMatchFilterLength = characteristics.getMaxMatchFilterLength();
+            if (maxMatchFilterLength != 0 && mMatchFilter != null
+                    && mMatchFilter.length > maxMatchFilterLength) {
+                throw new IllegalArgumentException(
+                        "Match filter longer than supported by device characteristics");
+            }
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
new file mode 100644
index 0000000..32c4258
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
@@ -0,0 +1,103 @@
+/*
+ * 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.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The characteristics of the Wi-Fi NAN implementation.
+ *
+ * @hide
+ */
+public class WifiNanCharacteristics implements Parcelable {
+    /** @hide */
+    public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
+    /** @hide */
+    public static final String KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH =
+            "key_max_service_specific_info_length";
+    /** @hide */
+    public static final String KEY_MAX_MATCH_FILTER_LENGTH = "key_max_match_filter_length";
+
+    private Bundle mCharacteristics = new Bundle();
+
+    /** @hide : should not be created by apps */
+    public WifiNanCharacteristics(Bundle characteristics) {
+        mCharacteristics = characteristics;
+    }
+
+    /**
+     * Returns the maximum string length that can be used to specify a NAN service name. Restricts
+     * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
+     * {@link SubscribeConfig.Builder#setServiceName(String)}.
+     *
+     * @return A positive integer, maximum string length of NAN service name.
+     */
+    public int getMaxServiceNameLength() {
+        return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
+    }
+
+    /**
+     * Returns the maximum length of byte array that can be used to specify a NAN service specific
+     * information field: the arbitrary load used in discovery or the message length of NAN
+     * message exchange. Restricts the parameters of the
+     * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
+     * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
+     * {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants.
+     *
+     * @return A positive integer, maximum length of byte array for NAN messaging.
+     */
+    public int getMaxServiceSpecificInfoLength() {
+        return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
+    }
+
+    /**
+     * Returns the maximum length of byte array that can be used to specify a NAN match filter.
+     * Restricts the parameters of the {@link PublishConfig.Builder#setMatchFilter(byte[])} and
+     * {@link SubscribeConfig.Builder#setMatchFilter(byte[])}.
+     *
+     * @return A positive integer, maximum legngth of byte array for NAN discovery match filter.
+     */
+    public int getMaxMatchFilterLength() {
+        return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mCharacteristics);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<WifiNanCharacteristics> CREATOR =
+            new Creator<WifiNanCharacteristics>() {
+                @Override
+                public WifiNanCharacteristics createFromParcel(Parcel in) {
+                    WifiNanCharacteristics c = new WifiNanCharacteristics(in.readBundle());
+                    return c;
+                }
+
+                @Override
+                public WifiNanCharacteristics[] newArray(int size) {
+                    return new WifiNanCharacteristics[size];
+                }
+            };
+}