• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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.uwb;
18 
19 import static android.ranging.RangingPreference.DEVICE_ROLE_RESPONDER;
20 
21 import android.ranging.DataNotificationConfig;
22 import android.ranging.RangingDevice;
23 import android.ranging.RangingPreference;
24 import android.ranging.SessionConfig;
25 import android.ranging.uwb.UwbAddress;
26 import android.ranging.uwb.UwbComplexChannel;
27 import android.ranging.uwb.UwbRangingParams;
28 
29 import androidx.annotation.NonNull;
30 
31 import com.android.ranging.uwb.backend.internal.RangingParameters;
32 import com.android.ranging.uwb.backend.internal.UwbRangeDataNtfConfig;
33 import com.android.ranging.uwb.backend.internal.UwbRangeLimitsConfig;
34 import com.android.server.ranging.RangingTechnology;
35 import com.android.server.ranging.session.RangingSessionConfig.MulticastTechnologyConfig;
36 
37 import com.google.common.collect.ImmutableBiMap;
38 import com.google.common.collect.ImmutableSet;
39 import com.google.uwb.support.base.RequiredParam;
40 
41 import java.util.List;
42 import java.util.Objects;
43 import java.util.stream.Collectors;
44 
45 /**
46  * A complete configuration for UWB ranging. This encapsulates all information contained in a
47  * configuration message sent over OOB and everything required to start a session in the underlying
48  * UWB system API.
49  */
50 public class UwbConfig implements MulticastTechnologyConfig {
51     private static final String TAG = UwbConfig.class.getSimpleName();
52 
53     private final SessionConfig mSessionConfig;
54     private final UwbRangingParams mParameters;
55     private final int mDeviceRole;
56     private final ImmutableBiMap<RangingDevice, UwbAddress> mPeerAddresses;
57 
UwbConfig(Builder builder)58     private UwbConfig(Builder builder) {
59         mParameters = builder.mParameters;
60         mSessionConfig = builder.mSessionConfig;
61         mDeviceRole = builder.mDeviceRole;
62         mPeerAddresses = builder.mPeerAddresses.get();
63     }
64 
65     @Override
getTechnology()66     public @NonNull RangingTechnology getTechnology() {
67         return RangingTechnology.UWB;
68     }
69 
70     @Override
getPeerDevices()71     public @NonNull ImmutableSet<RangingDevice> getPeerDevices() {
72         return mPeerAddresses.keySet();
73     }
74 
75     /** Returns the length of the session key. */
getSessionKeyInfoLength()76     public final int getSessionKeyInfoLength() {
77         if (mParameters.getSessionKeyInfo() == null) {
78             return 0;
79         } else {
80             return mParameters.getSessionKeyInfo().length;
81         }
82     }
83 
getParameters()84     public @NonNull UwbRangingParams getParameters() {
85         return mParameters;
86     }
87 
88     @Override
getDeviceRole()89     public @RangingPreference.DeviceRole int getDeviceRole() {
90         return mDeviceRole;
91     }
92 
getSessionConfig()93     public SessionConfig getSessionConfig() {
94         return mSessionConfig;
95     }
96 
getPeerAddresses()97     public @NonNull ImmutableBiMap<RangingDevice, UwbAddress> getPeerAddresses() {
98         return mPeerAddresses;
99     }
100 
101 
102     /**
103      * @return the configuration converted to a
104      * {@link androidx.core.uwb.backend.impl.internal.RangingParameters} accepted by the UWB
105      * backend.
106      */
asBackendParameters(DataNotificationConfig dataNotificationConfig)107     public RangingParameters asBackendParameters(DataNotificationConfig dataNotificationConfig) {
108         List<com.android.ranging.uwb.backend.internal.UwbAddress> peerAddresses = mPeerAddresses
109                 .values()
110                 .stream()
111                 .map((address) ->
112                         com.android.ranging.uwb.backend.internal.UwbAddress.fromBytes(
113                                 address.getAddressBytes()))
114                 .collect(Collectors.toList());
115         return new RangingParameters(
116                 (int) mParameters.getConfigId(),
117                 mParameters.getSessionId(),
118                 mParameters.getSubSessionId(),
119                 mParameters.getSessionKeyInfo(),
120                 mParameters.getSubSessionKeyInfo(),
121                 toBackend(mParameters.getComplexChannel()),
122                 peerAddresses,
123                 (int) mParameters.getRangingUpdateRate(),
124                 toBackend(dataNotificationConfig),
125                 (int) mParameters.getSlotDuration(),
126                 // RangingParameters has isAoaDisabled field, Inverting here.
127                 !mSessionConfig.isAngleOfArrivalNeeded(),
128                 new UwbRangeLimitsConfig.Builder().setRangeMaxNumberOfMeasurements(
129                         mSessionConfig.getRangingMeasurementsLimit()
130                 ).build()
131         );
132     }
133 
toBackend( @onNull DataNotificationConfig rangeDataNtfConfig )134     public static @NonNull UwbRangeDataNtfConfig toBackend(
135             @NonNull DataNotificationConfig rangeDataNtfConfig
136     ) {
137         return new UwbRangeDataNtfConfig.Builder()
138                 .setRangeDataConfigType((int) rangeDataNtfConfig.getNotificationConfigType())
139                 .setNtfProximityNear(rangeDataNtfConfig.getProximityNearCm())
140                 .setNtfProximityFar(rangeDataNtfConfig.getProximityFarCm())
141                 .build();
142     }
143 
toBackend( @onNull UwbComplexChannel complexChannel )144     public static @NonNull com.android.ranging.uwb.backend.internal.UwbComplexChannel toBackend(
145             @NonNull UwbComplexChannel complexChannel
146     ) {
147         return new com.android.ranging.uwb.backend.internal.UwbComplexChannel(
148                 (int) complexChannel.getChannel(), (int) complexChannel.getPreambleIndex());
149     }
150 
toBackend( @onNull UwbAddress address )151     public static @NonNull com.android.ranging.uwb.backend.internal.UwbAddress toBackend(
152             @NonNull UwbAddress address
153     ) {
154         return com.android.ranging.uwb.backend.internal.UwbAddress.fromBytes(
155                 address.getAddressBytes());
156     }
157 
158 
159     /** Builder for {@link UwbConfig}. */
160     public static class Builder {
161         private final UwbRangingParams mParameters;
162         private final RequiredParam<ImmutableBiMap<RangingDevice, UwbAddress>> mPeerAddresses =
163                 new RequiredParam<>();
164         private SessionConfig mSessionConfig = new SessionConfig.Builder().build();
165 
166         private int mDeviceRole = DEVICE_ROLE_RESPONDER;
167         private boolean mIsAoaNeeded = false;
168 
Builder(@onNull UwbRangingParams parameters)169         public Builder(@NonNull UwbRangingParams parameters) {
170             mParameters = parameters;
171         }
172 
build()173         public @NonNull UwbConfig build() {
174             return new UwbConfig(this);
175         }
176 
setPeerAddresses( @onNull ImmutableBiMap<RangingDevice, UwbAddress> addresses )177         public Builder setPeerAddresses(
178                 @NonNull ImmutableBiMap<RangingDevice, UwbAddress> addresses
179         ) {
180             mPeerAddresses.set(addresses);
181             return this;
182         }
183 
setDeviceRole(@angingPreference.DeviceRole int deviceRole)184         public Builder setDeviceRole(@RangingPreference.DeviceRole int deviceRole) {
185             mDeviceRole = deviceRole;
186             return this;
187         }
188 
setSessionConfig(SessionConfig sessionConfig)189         public Builder setSessionConfig(SessionConfig sessionConfig) {
190             mSessionConfig = sessionConfig;
191             return this;
192         }
193     }
194 
195     @Override
toString()196     public String toString() {
197         return "UwbConfig{"
198                 + "mParameters="
199                 + mParameters
200                 + ", mSessionConfig="
201                 + mSessionConfig
202                 + ", mDeviceRole="
203                 + mDeviceRole
204                 + ", mPeerAddresses="
205                 + mPeerAddresses
206                 + " }";
207     }
208 
209     @Override
equals(Object o)210     public boolean equals(Object o) {
211         if (this == o) return true;
212         if (!(o instanceof UwbConfig uwbConfig)) return false;
213         return mDeviceRole == uwbConfig.mDeviceRole && Objects.equals(mSessionConfig,
214                 uwbConfig.mSessionConfig) && Objects.equals(mParameters,
215                 uwbConfig.mParameters) && Objects.equals(mPeerAddresses,
216                 uwbConfig.mPeerAddresses);
217     }
218 
219     @Override
hashCode()220     public int hashCode() {
221         return Objects.hash(mSessionConfig, mParameters, mDeviceRole, mPeerAddresses);
222     }
223 }
224