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; 17 18 import android.os.PersistableBundle; 19 import android.uwb.RangingChangeReason; 20 21 import com.android.server.uwb.data.UwbUciConstants; 22 23 import com.google.uwb.support.aliro.AliroParams; 24 import com.google.uwb.support.aliro.AliroRangingError; 25 import com.google.uwb.support.base.Params; 26 import com.google.uwb.support.ccc.CccParams; 27 import com.google.uwb.support.ccc.CccRangingError; 28 import com.google.uwb.support.fira.FiraStatusCode; 29 30 public class UwbSessionNotificationHelper { convertUciReasonCodeToApiReasonCode(int reasonCode)31 public static int convertUciReasonCodeToApiReasonCode(int reasonCode) { 32 /* set default */ 33 int rangingChangeReason = RangingChangeReason.UNKNOWN; 34 switch (reasonCode) { 35 case UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS: 36 rangingChangeReason = RangingChangeReason.LOCAL_API; 37 break; 38 case UwbUciConstants.REASON_MAX_RANGING_ROUND_RETRY_COUNT_REACHED: 39 rangingChangeReason = RangingChangeReason.MAX_RR_RETRY_REACHED; 40 break; 41 case UwbUciConstants.REASON_MAX_NUMBER_OF_MEASUREMENTS_REACHED: 42 rangingChangeReason = RangingChangeReason.REMOTE_REQUEST; 43 break; 44 case UwbUciConstants.REASON_ERROR_INSUFFICIENT_SLOTS_PER_RR: 45 case UwbUciConstants.REASON_ERROR_SLOT_LENGTH_NOT_SUPPORTED: 46 case UwbUciConstants.REASON_ERROR_INVALID_UL_TDOA_RANDOM_WINDOW: 47 case UwbUciConstants.REASON_ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED: 48 case UwbUciConstants.REASON_ERROR_INVALID_RANGING_INTERVAL: 49 case UwbUciConstants.REASON_ERROR_INVALID_STS_CONFIG: 50 case UwbUciConstants.REASON_ERROR_INVALID_RFRAME_CONFIG: 51 case UwbUciConstants.REASON_ERROR_HUS_NOT_ENOUGH_SLOTS: 52 case UwbUciConstants.REASON_ERROR_HUS_CFP_PHASE_TOO_SHORT: 53 case UwbUciConstants.REASON_ERROR_HUS_CAP_PHASE_TOO_SHORT: 54 case UwbUciConstants.REASON_ERROR_HUS_OTHERS: 55 rangingChangeReason = RangingChangeReason.BAD_PARAMETERS; 56 break; 57 case UwbUciConstants.REASON_ERROR_SESSION_KEY_NOT_FOUND: 58 case UwbUciConstants.REASON_ERROR_SUB_SESSION_KEY_NOT_FOUND: 59 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 60 break; 61 case UwbUciConstants.REASON_REGULATION_UWB_OFF: 62 rangingChangeReason = RangingChangeReason.SYSTEM_REGULATION; 63 break; 64 case UwbUciConstants.REASON_SESSION_RESUMED_DUE_TO_INBAND_SIGNAL: 65 rangingChangeReason = RangingChangeReason.SESSION_RESUMED; 66 break; 67 case UwbUciConstants.REASON_SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL: 68 rangingChangeReason = RangingChangeReason.SESSION_SUSPENDED; 69 break; 70 case UwbUciConstants.REASON_SESSION_STOPPED_DUE_TO_INBAND_SIGNAL: 71 rangingChangeReason = RangingChangeReason.INBAND_SESSION_STOP; 72 break; 73 } 74 return rangingChangeReason; 75 } 76 convertUciStatusToApiReasonCode(int status)77 public static int convertUciStatusToApiReasonCode(int status) { 78 /* set default */ 79 int rangingChangeReason = RangingChangeReason.UNKNOWN; 80 switch (status) { 81 case UwbUciConstants.STATUS_CODE_OK: 82 rangingChangeReason = RangingChangeReason.LOCAL_API; 83 break; 84 case UwbUciConstants.STATUS_CODE_ERROR_MAX_SESSIONS_EXCEEDED: 85 rangingChangeReason = RangingChangeReason.MAX_SESSIONS_REACHED; 86 break; 87 case UwbUciConstants.STATUS_CODE_INVALID_PARAM: 88 case UwbUciConstants.STATUS_CODE_INVALID_RANGE: 89 case UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE: 90 rangingChangeReason = RangingChangeReason.BAD_PARAMETERS; 91 break; 92 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 93 case UwbUciConstants.STATUS_CODE_CCC_LIFECYCLE: 94 case UwbUciConstants.STATUS_CODE_CCC_SE_BUSY: 95 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 96 break; 97 case UwbUciConstants.REASON_ERROR_INSUFFICIENT_SLOTS_PER_RR: 98 rangingChangeReason = RangingChangeReason.INSUFFICIENT_SLOTS_PER_RR; 99 break; 100 } 101 return rangingChangeReason; 102 } 103 104 /** 105 * Convert UCI status code received in SESSION_DATA_TRANSFER_PHASE_CONFIGURATION_NTF to 106 * an API reason code. 107 */ convertDataTransferPhaseConfigStatusToApiReasonCode( int dataTransferPhaseConfigStatus)108 public static int convertDataTransferPhaseConfigStatusToApiReasonCode( 109 int dataTransferPhaseConfigStatus) { 110 int rangingChangeReason = RangingChangeReason.UNKNOWN; 111 switch (dataTransferPhaseConfigStatus) { 112 case UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_DTPCM_CONFIG_SUCCESS: 113 rangingChangeReason = RangingChangeReason.LOCAL_API; 114 break; 115 case UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_ERROR_DUPLICATE_SLOT_ASSIGNMENT: 116 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 117 break; 118 } 119 return rangingChangeReason; 120 } 121 122 /** 123 * Convert UCI reason code values to UCI status code, as some of the callbacks expect to get 124 * the latter. 125 */ convertUciReasonCodeToUciStatusCode(int reasonCode)126 public static int convertUciReasonCodeToUciStatusCode(int reasonCode) { 127 int statusCode = UwbUciConstants.STATUS_CODE_FAILED; 128 switch (reasonCode) { 129 case UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS: 130 statusCode = UwbUciConstants.STATUS_CODE_OK; 131 break; 132 case UwbUciConstants.REASON_ERROR_SESSION_KEY_NOT_FOUND: 133 case UwbUciConstants.REASON_ERROR_SUB_SESSION_KEY_NOT_FOUND: 134 statusCode = UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST; 135 break; 136 } 137 return statusCode; 138 } 139 convertUciStatusToApiCccProtocolError(int status)140 private static @CccParams.ProtocolError int convertUciStatusToApiCccProtocolError(int status) { 141 switch (status) { 142 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 143 return CccParams.PROTOCOL_ERROR_NOT_FOUND; 144 case UwbUciConstants.STATUS_CODE_CCC_LIFECYCLE: 145 return CccParams.PROTOCOL_ERROR_LIFECYCLE; 146 case UwbUciConstants.STATUS_CODE_CCC_SE_BUSY: 147 return CccParams.PROTOCOL_ERROR_SE_BUSY; 148 default: 149 return CccParams.PROTOCOL_ERROR_UNKNOWN; 150 } 151 } 152 convertUciStatusToApiAliroProtocolError( int status)153 private static @AliroParams.ProtocolError int convertUciStatusToApiAliroProtocolError( 154 int status) { 155 switch (status) { 156 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 157 return AliroParams.PROTOCOL_ERROR_NOT_FOUND; 158 default: 159 return AliroParams.PROTOCOL_ERROR_UNKNOWN; 160 } 161 } 162 convertUciStatusToParam(String protocolName, int status)163 public static PersistableBundle convertUciStatusToParam(String protocolName, int status) { 164 Params c; 165 if (protocolName.equals(CccParams.PROTOCOL_NAME)) { 166 c = new CccRangingError.Builder() 167 .setError(convertUciStatusToApiCccProtocolError(status)) 168 .build(); 169 } else if (protocolName.equals(AliroParams.PROTOCOL_NAME)) { 170 c = new AliroRangingError.Builder() 171 .setError(convertUciStatusToApiAliroProtocolError(status)) 172 .build(); 173 } else { 174 c = new FiraStatusCode.Builder().setStatusCode(status).build(); 175 } 176 return c.toBundle(); 177 } 178 getSessionStateString(int state)179 static String getSessionStateString(int state) { 180 String ret = ""; 181 switch (state) { 182 case UwbUciConstants.UWB_SESSION_STATE_INIT: 183 ret = "INIT"; 184 break; 185 case UwbUciConstants.UWB_SESSION_STATE_DEINIT: 186 ret = "DEINIT"; 187 break; 188 case UwbUciConstants.UWB_SESSION_STATE_ACTIVE: 189 ret = "ACTIVE"; 190 break; 191 case UwbUciConstants.UWB_SESSION_STATE_IDLE: 192 ret = "IDLE"; 193 break; 194 case UwbUciConstants.UWB_SESSION_STATE_ERROR: 195 ret = "ERROR"; 196 break; 197 } 198 return ret; 199 } 200 } 201