• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.ranging.rtt;
18 
19 import android.ranging.RangingDevice;
20 import android.ranging.SessionConfig;
21 import android.ranging.wifi.rtt.RttRangingParams;
22 
23 import com.android.server.ranging.RangingTechnology;
24 import com.android.server.ranging.oob.SetConfigurationMessage;
25 import com.android.server.ranging.oob.TechnologyHeader;
26 
27 import com.google.auto.value.AutoValue;
28 import com.google.common.collect.ImmutableList;
29 
30 import java.nio.ByteBuffer;
31 import java.util.Arrays;
32 
33 @AutoValue
34 public abstract class RttOobConfig implements SetConfigurationMessage.TechnologyOobConfig {
35 
36     private static final int MIN_SIZE_BYTES = 6;
37 
38     public enum RttSupportedFeatures {
39         RTT_11_MC(1),
40         RTT_11_AZ(2),
41         RTT_UNKNOWN(255);
42 
43         public static final ImmutableList<RttSupportedFeatures> FEATURES =
44                 ImmutableList.copyOf(RttSupportedFeatures.values());
45 
46         private final int mValue;
47 
RttSupportedFeatures(int value)48         RttSupportedFeatures(int value) {
49             this.mValue = value;
50         }
51 
getValue()52         public int getValue() {
53             return mValue;
54         }
55 
fromValue(int value)56         public static RttSupportedFeatures fromValue(int value) {
57             return value < RTT_11_MC.mValue || value > RTT_11_AZ.mValue ? RTT_UNKNOWN :
58                     RttSupportedFeatures.values()[value];
59         }
60     }
61 
62     public enum Bandwidth {
63         BANDWIDTH_20MHZ(0),
64         BANDWIDTH_40MHZ(1),
65         BANDWIDTH_80MHZ(2),
66         BANDWIDTH_160MHZ(3),
67         BANDWIDTH_80MHZ_PLUS_MHZ(4),
68         BANDWIDTH_320MHZ(5),
69         BANDWIDTH_UNDEFINED(255);
70 
71         private final int mValue;
72 
Bandwidth(int value)73         Bandwidth(int value) {
74             this.mValue = value;
75         }
76 
getValue()77         public int getValue() {
78             return mValue;
79         }
80     }
81 
parseBytes(byte[] rttConfigBytes)82     public static RttOobConfig parseBytes(byte[] rttConfigBytes) {
83         TechnologyHeader header = TechnologyHeader.parseBytes(rttConfigBytes);
84 
85         if (rttConfigBytes.length < MIN_SIZE_BYTES) {
86             throw new IllegalArgumentException(
87                     String.format("RttConfig size is %d, expected at least %d",
88                             rttConfigBytes.length, MIN_SIZE_BYTES));
89         }
90 
91         if (rttConfigBytes.length < header.getSize()) {
92             throw new IllegalArgumentException(
93                     String.format(
94                             "RttConfig header size field is %d, but the size of the array is %d",
95                             header.getSize(), rttConfigBytes.length));
96         }
97 
98         if (header.getRangingTechnology() != RangingTechnology.RTT) {
99             throw new IllegalArgumentException(
100                     String.format(
101                             "RttConfig header technology field is %s, expected %s",
102                             header.getRangingTechnology(), RangingTechnology.RTT));
103         }
104 
105         int parseCursor = header.getHeaderSize();
106         int serviceNameSize = rttConfigBytes[parseCursor++];
107         byte[] serviceNameBytes = Arrays.copyOfRange(rttConfigBytes, parseCursor,
108                 parseCursor + serviceNameSize);
109         String serviceName = new String(serviceNameBytes);
110         parseCursor += serviceNameSize;
111 
112         int deviceRole = rttConfigBytes[parseCursor++];
113         boolean usePeriodicRanging = rttConfigBytes[parseCursor++] != 0;
114 
115         return builder()
116                 .setDeviceRole(deviceRole)
117                 .setServiceName(serviceName)
118                 .setUsePeriodicRanging(usePeriodicRanging)
119                 .build();
120     }
121 
toBytes()122     public final byte[] toBytes() {
123         int size = MIN_SIZE_BYTES + serviceName().length() - 1;
124         return ByteBuffer.allocate(size)
125                 .put(RangingTechnology.RTT.toByte())
126                 .put((byte) size)
127                 .put((byte) serviceName().length())
128                 .put(serviceName().getBytes())
129                 .put((byte) deviceRole())
130                 .put((byte) (usePeriodicRanging() ? 1 : 0))
131                 .array();
132     }
133 
getSize()134     public int getSize() {
135         return toBytes().length;
136     }
137 
toTechnologyConfig(RangingDevice peer, int deviceRole)138     public RttConfig toTechnologyConfig(RangingDevice peer, int deviceRole) {
139         return new RttConfig(
140                 deviceRole,
141                 new RttRangingParams.Builder(serviceName()).build(),
142                 new SessionConfig.Builder().build(),
143                 peer);
144     }
145 
serviceName()146     public abstract String serviceName();
147 
148     @OobDeviceRole
deviceRole()149     public abstract int deviceRole();
150 
usePeriodicRanging()151     public abstract boolean usePeriodicRanging();
152 
153     public @interface OobDeviceRole {
154         int RESPONDER = 0;
155         int INITIATOR = 1;
156     }
157 
builder()158     public static Builder builder() {
159         return new AutoValue_RttOobConfig.Builder();
160     }
161 
162     @AutoValue.Builder
163     public abstract static class Builder {
setServiceName(String value)164         public abstract Builder setServiceName(String value);
165 
setDeviceRole(int value)166         public abstract Builder setDeviceRole(int value);
167 
setUsePeriodicRanging(boolean value)168         public abstract Builder setUsePeriodicRanging(boolean value);
169 
autoBuild()170         abstract RttOobConfig autoBuild();
171 
build()172         public RttOobConfig build() {
173             return autoBuild();
174         }
175 
176     }
177 }
178