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 package com.android.server.uwb.secure.csml; 17 18 import static com.android.server.uwb.secure.iso7816.Iso7816Constants.CLA_PROPRIETARY; 19 20 import android.annotation.NonNull; 21 22 import com.android.server.uwb.secure.iso7816.CommandApdu; 23 import com.android.server.uwb.secure.iso7816.StatusWord; 24 import com.android.server.uwb.secure.iso7816.TlvDatum; 25 import com.android.server.uwb.secure.iso7816.TlvDatum.Tag; 26 27 import java.io.ByteArrayOutputStream; 28 import java.io.DataOutputStream; 29 import java.io.IOException; 30 import java.util.List; 31 32 /** 33 * The base class of all C-APDU defined by FiRa. 34 */ 35 public abstract class FiRaCommand { 36 public static final Tag FIRA_PROPRIETARY_COMMAND_TEMP_TAG = 37 new Tag((byte) 0x71); 38 FiRaCommand()39 protected FiRaCommand(){ 40 } 41 getCla()42 protected byte getCla() { 43 // logical channel number is not available. Use the default value. 44 return CLA_PROPRIETARY; 45 } 46 getIns()47 protected abstract byte getIns(); 48 getP1()49 protected byte getP1() { 50 return (byte) 0x00; 51 } 52 getP2()53 protected byte getP2() { 54 return (byte) 0x00; 55 } 56 getLe()57 protected byte getLe() { 58 return (byte) 0x00; 59 } 60 getExpectedSw()61 protected abstract StatusWord[] getExpectedSw(); 62 63 @NonNull getTlvPayload()64 protected abstract List<TlvDatum> getTlvPayload(); 65 66 @NonNull buildPayload(@onNull List<TlvDatum> tlvData)67 private byte[] buildPayload(@NonNull List<TlvDatum> tlvData) { 68 if (tlvData.size() == 0) { 69 return new byte[0]; 70 } 71 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 72 DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); 73 try { 74 for (TlvDatum tlv : tlvData) { 75 dataOutputStream.write(tlv.toBytes()); 76 } 77 78 dataOutputStream.flush(); 79 } catch (IOException e) { 80 return new byte[0]; 81 } 82 return byteArrayOutputStream.toByteArray(); 83 } 84 85 /** 86 * Converts the FiRa command to the CommandApdu of ISO7816-4. 87 */ 88 @NonNull getCommandApdu()89 public CommandApdu getCommandApdu() { 90 CommandApdu commandApdu = CommandApdu.builder(getCla(), getIns(), getP1(), getP2()) 91 .setCdata(buildPayload(getTlvPayload())) 92 .setLe(getLe()) 93 .setExpected(getExpectedSw()) 94 .build(); 95 return commandApdu; 96 } 97 } 98