• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.uwb.params;
18 
19 import static com.android.server.uwb.config.CapabilityParam.CCC_CHANNEL_5;
20 import static com.android.server.uwb.config.CapabilityParam.CCC_CHANNEL_9;
21 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_12;
22 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_24;
23 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_3;
24 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_4;
25 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_6;
26 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_8;
27 import static com.android.server.uwb.config.CapabilityParam.CCC_CHAPS_PER_SLOT_9;
28 import static com.android.server.uwb.config.CapabilityParam.CCC_HOPPING_CONFIG_MODE_ADAPTIVE;
29 import static com.android.server.uwb.config.CapabilityParam.CCC_HOPPING_CONFIG_MODE_CONTINUOUS;
30 import static com.android.server.uwb.config.CapabilityParam.CCC_HOPPING_CONFIG_MODE_NONE;
31 import static com.android.server.uwb.config.CapabilityParam.CCC_HOPPING_SEQUENCE_AES;
32 import static com.android.server.uwb.config.CapabilityParam.CCC_HOPPING_SEQUENCE_DEFAULT;
33 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_CHANNELS;
34 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_CHAPS_PER_SLOT;
35 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES;
36 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_PULSE_SHAPE_COMBOS;
37 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_RAN_MULTIPLIER;
38 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_SYNC_CODES;
39 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_UWB_CONFIGS;
40 import static com.android.server.uwb.config.CapabilityParam.CCC_SUPPORTED_VERSIONS;
41 
42 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_12;
43 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_24;
44 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_3;
45 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_4;
46 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_6;
47 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_8;
48 import static com.google.uwb.support.ccc.CccParams.CHAPS_PER_SLOT_9;
49 import static com.google.uwb.support.ccc.CccParams.HOPPING_CONFIG_MODE_ADAPTIVE;
50 import static com.google.uwb.support.ccc.CccParams.HOPPING_CONFIG_MODE_CONTINUOUS;
51 import static com.google.uwb.support.ccc.CccParams.HOPPING_CONFIG_MODE_NONE;
52 import static com.google.uwb.support.ccc.CccParams.HOPPING_SEQUENCE_AES;
53 import static com.google.uwb.support.ccc.CccParams.HOPPING_SEQUENCE_DEFAULT;
54 import static com.google.uwb.support.ccc.CccParams.UWB_CHANNEL_5;
55 import static com.google.uwb.support.ccc.CccParams.UWB_CHANNEL_9;
56 
57 import com.android.server.uwb.config.ConfigParam;
58 
59 import com.google.uwb.support.base.Params;
60 import com.google.uwb.support.ccc.CccProtocolVersion;
61 import com.google.uwb.support.ccc.CccPulseShapeCombo;
62 import com.google.uwb.support.ccc.CccRangingStartedParams;
63 import com.google.uwb.support.ccc.CccSpecificationParams;
64 
65 import java.nio.ByteBuffer;
66 import java.nio.ByteOrder;
67 
68 /**
69  * CCC decoder
70  */
71 public class CccDecoder extends TlvDecoder {
72     @Override
getParams(TlvDecoderBuffer tlvs, Class<T> paramsType)73     public <T extends Params> T getParams(TlvDecoderBuffer tlvs, Class<T> paramsType)
74             throws IllegalArgumentException {
75         if (CccRangingStartedParams.class.equals(paramsType)) {
76             return (T) getCccRangingStartedParamsFromTlvBuffer(tlvs);
77         }
78         if (CccSpecificationParams.class.equals(paramsType)) {
79             return (T) getCccSpecificationParamsFromTlvBuffer(tlvs);
80         }
81         return null;
82     }
83 
isBitSet(int flags, int mask)84     private static boolean isBitSet(int flags, int mask) {
85         return (flags & mask) != 0;
86     }
87 
getCccRangingStartedParamsFromTlvBuffer(TlvDecoderBuffer tlvs)88     private CccRangingStartedParams getCccRangingStartedParamsFromTlvBuffer(TlvDecoderBuffer tlvs) {
89         byte[] hopModeKey = tlvs.getByteArray(ConfigParam.HOP_MODE_KEY);
90         int hopModeKeyInt = ByteBuffer.wrap(hopModeKey).order(ByteOrder.LITTLE_ENDIAN).getInt();
91         return new CccRangingStartedParams.Builder()
92                 // STS_Index0  0 - 0x3FFFFFFFF
93                 .setStartingStsIndex(tlvs.getInt(ConfigParam.STS_INDEX))
94                 .setHopModeKey(hopModeKeyInt)
95                 //  UWB_Time0 0 - 0xFFFFFFFFFFFFFFFF  UWB_INITIATION_TIME
96                 .setUwbTime0(tlvs.getLong(ConfigParam.UWB_TIME0))
97                 // RANGING_INTERVAL = RAN_Multiplier * 96
98                 .setRanMultiplier(tlvs.getInt(ConfigParam.RANGING_INTERVAL) / 96)
99                 .setSyncCodeIndex(tlvs.getByte(ConfigParam.PREAMBLE_CODE_INDEX))
100                 .build();
101     }
102 
getCccSpecificationParamsFromTlvBuffer(TlvDecoderBuffer tlvs)103     private CccSpecificationParams getCccSpecificationParamsFromTlvBuffer(TlvDecoderBuffer tlvs) {
104         CccSpecificationParams.Builder builder = new CccSpecificationParams.Builder();
105         byte[] versions = tlvs.getByteArray(CCC_SUPPORTED_VERSIONS);
106         if (versions.length % 2 != 0) {
107             throw new IllegalArgumentException("Invalid supported protocol versions len "
108                     + versions.length);
109         }
110         for (int i = 0; i < versions.length; i += 2) {
111             builder.addProtocolVersion(CccProtocolVersion.fromBytes(versions, i));
112         }
113         byte[] configs = tlvs.getByteArray(CCC_SUPPORTED_UWB_CONFIGS);
114         for (int i = 0; i < configs.length; i++) {
115             builder.addUwbConfig(configs[i]);
116         }
117         byte[] pulse_shape_combos = tlvs.getByteArray(CCC_SUPPORTED_PULSE_SHAPE_COMBOS);
118         for (int i = 0; i < pulse_shape_combos.length; i++) {
119             builder.addPulseShapeCombo(CccPulseShapeCombo.fromBytes(pulse_shape_combos, i));
120         }
121         builder.setRanMultiplier(tlvs.getInt(CCC_SUPPORTED_RAN_MULTIPLIER));
122         byte chapsPerslot = tlvs.getByte(CCC_SUPPORTED_CHAPS_PER_SLOT);
123         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_3)) {
124             builder.addChapsPerSlot(CHAPS_PER_SLOT_3);
125         }
126         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_4)) {
127             builder.addChapsPerSlot(CHAPS_PER_SLOT_4);
128         }
129         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_6)) {
130             builder.addChapsPerSlot(CHAPS_PER_SLOT_6);
131         }
132         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_8)) {
133             builder.addChapsPerSlot(CHAPS_PER_SLOT_8);
134         }
135         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_9)) {
136             builder.addChapsPerSlot(CHAPS_PER_SLOT_9);
137         }
138         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_12)) {
139             builder.addChapsPerSlot(CHAPS_PER_SLOT_12);
140         }
141         if (isBitSet(chapsPerslot, CCC_CHAPS_PER_SLOT_24)) {
142             builder.addChapsPerSlot(CHAPS_PER_SLOT_24);
143         }
144         // Don't use TlvDecodeBuffer#getInt() to avoid conversion to little endian.
145         int syncCodes = ByteBuffer.wrap(tlvs.getByteArray(CCC_SUPPORTED_SYNC_CODES)).getInt();
146         for (int i = 0; i < 32; i++) {
147             if (isBitSet(syncCodes, 1 << i)) {
148                 builder.addSyncCode(i + 1);
149             }
150         }
151         byte channels = tlvs.getByte(CCC_SUPPORTED_CHANNELS);
152         if (isBitSet(channels, CCC_CHANNEL_5)) {
153             builder.addChannel(UWB_CHANNEL_5);
154         }
155         if (isBitSet(channels, CCC_CHANNEL_9)) {
156             builder.addChannel(UWB_CHANNEL_9);
157         }
158         byte hoppingConfigModesAndSequences =
159                 tlvs.getByte(CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES);
160         if (isBitSet(hoppingConfigModesAndSequences, CCC_HOPPING_CONFIG_MODE_NONE)) {
161             builder.addHoppingConfigMode(HOPPING_CONFIG_MODE_NONE);
162         }
163         if (isBitSet(hoppingConfigModesAndSequences, CCC_HOPPING_CONFIG_MODE_CONTINUOUS)) {
164             builder.addHoppingConfigMode(HOPPING_CONFIG_MODE_CONTINUOUS);
165         }
166         if (isBitSet(hoppingConfigModesAndSequences, CCC_HOPPING_CONFIG_MODE_ADAPTIVE)) {
167             builder.addHoppingConfigMode(HOPPING_CONFIG_MODE_ADAPTIVE);
168         }
169         if (isBitSet(hoppingConfigModesAndSequences, CCC_HOPPING_SEQUENCE_AES)) {
170             builder.addHoppingSequence(HOPPING_SEQUENCE_AES);
171         }
172         if (isBitSet(hoppingConfigModesAndSequences, CCC_HOPPING_SEQUENCE_DEFAULT)) {
173             builder.addHoppingSequence(HOPPING_SEQUENCE_DEFAULT);
174         }
175         return builder.build();
176     }
177 }
178