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 case UwbUciConstants.REASON_SESSION_STOPPED_DUE_TO_MAX_STS_INDEX_VALUE: 43 rangingChangeReason = RangingChangeReason.REMOTE_REQUEST; 44 break; 45 case UwbUciConstants.REASON_ERROR_INSUFFICIENT_SLOTS_PER_RR: 46 case UwbUciConstants.REASON_ERROR_SLOT_LENGTH_NOT_SUPPORTED: 47 case UwbUciConstants.REASON_ERROR_INVALID_UL_TDOA_RANDOM_WINDOW: 48 case UwbUciConstants.REASON_ERROR_MAC_ADDRESS_MODE_NOT_SUPPORTED: 49 case UwbUciConstants.REASON_ERROR_INVALID_RANGING_INTERVAL: 50 case UwbUciConstants.REASON_ERROR_INVALID_STS_CONFIG: 51 case UwbUciConstants.REASON_ERROR_INVALID_RFRAME_CONFIG: 52 case UwbUciConstants.REASON_ERROR_HUS_NOT_ENOUGH_SLOTS: 53 case UwbUciConstants.REASON_ERROR_HUS_CFP_PHASE_TOO_SHORT: 54 case UwbUciConstants.REASON_ERROR_HUS_CAP_PHASE_TOO_SHORT: 55 case UwbUciConstants.REASON_ERROR_HUS_OTHERS: 56 rangingChangeReason = RangingChangeReason.BAD_PARAMETERS; 57 break; 58 case UwbUciConstants.REASON_ERROR_SESSION_KEY_NOT_FOUND: 59 case UwbUciConstants.REASON_ERROR_SUB_SESSION_KEY_NOT_FOUND: 60 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 61 break; 62 case UwbUciConstants.REASON_REGULATION_UWB_OFF: 63 rangingChangeReason = RangingChangeReason.SYSTEM_REGULATION; 64 break; 65 case UwbUciConstants.REASON_SESSION_RESUMED_DUE_TO_INBAND_SIGNAL: 66 rangingChangeReason = RangingChangeReason.SESSION_RESUMED; 67 break; 68 case UwbUciConstants.REASON_SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL: 69 rangingChangeReason = RangingChangeReason.SESSION_SUSPENDED; 70 break; 71 case UwbUciConstants.REASON_SESSION_STOPPED_DUE_TO_INBAND_SIGNAL: 72 rangingChangeReason = RangingChangeReason.INBAND_SESSION_STOP; 73 break; 74 } 75 return rangingChangeReason; 76 } 77 convertUciStatusToApiReasonCode(int status)78 public static int convertUciStatusToApiReasonCode(int status) { 79 /* set default */ 80 int rangingChangeReason = RangingChangeReason.UNKNOWN; 81 switch (status) { 82 case UwbUciConstants.STATUS_CODE_OK: 83 rangingChangeReason = RangingChangeReason.LOCAL_API; 84 break; 85 case UwbUciConstants.STATUS_CODE_ERROR_MAX_SESSIONS_EXCEEDED: 86 rangingChangeReason = RangingChangeReason.MAX_SESSIONS_REACHED; 87 break; 88 case UwbUciConstants.STATUS_CODE_INVALID_PARAM: 89 case UwbUciConstants.STATUS_CODE_INVALID_RANGE: 90 case UwbUciConstants.STATUS_CODE_INVALID_MESSAGE_SIZE: 91 rangingChangeReason = RangingChangeReason.BAD_PARAMETERS; 92 break; 93 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 94 case UwbUciConstants.STATUS_CODE_CCC_LIFECYCLE: 95 case UwbUciConstants.STATUS_CODE_CCC_SE_BUSY: 96 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 97 break; 98 case UwbUciConstants.REASON_ERROR_INSUFFICIENT_SLOTS_PER_RR: 99 rangingChangeReason = RangingChangeReason.INSUFFICIENT_SLOTS_PER_RR; 100 break; 101 } 102 return rangingChangeReason; 103 } 104 105 /** 106 * Convert UCI status code received in SESSION_DATA_TRANSFER_PHASE_CONFIGURATION_NTF to 107 * an API reason code. 108 */ convertDataTransferPhaseConfigStatusToApiReasonCode( int dataTransferPhaseConfigStatus)109 public static int convertDataTransferPhaseConfigStatusToApiReasonCode( 110 int dataTransferPhaseConfigStatus) { 111 int rangingChangeReason = RangingChangeReason.UNKNOWN; 112 switch (dataTransferPhaseConfigStatus) { 113 case UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_DTPCM_CONFIG_SUCCESS: 114 rangingChangeReason = RangingChangeReason.LOCAL_API; 115 break; 116 case UwbUciConstants.STATUS_CODE_DATA_TRANSFER_PHASE_CONFIG_ERROR_DUPLICATE_SLOT_ASSIGNMENT: 117 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 118 break; 119 } 120 return rangingChangeReason; 121 } 122 123 /** 124 * Convert Multicast list update status codes to an API reason code. 125 */ convertMulticastListUpdateStatusToApiReasonCode( int multicastListUpdateStatus)126 public static int convertMulticastListUpdateStatusToApiReasonCode( 127 int multicastListUpdateStatus) { 128 int rangingChangeReason = RangingChangeReason.UNKNOWN; 129 switch (multicastListUpdateStatus) { 130 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_OK: 131 rangingChangeReason = RangingChangeReason.LOCAL_API; 132 break; 133 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_FULL: 134 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_KEY_FETCH_FAIL: 135 rangingChangeReason = RangingChangeReason.PROTOCOL_SPECIFIC; 136 break; 137 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_SUB_SESSION_ID_NOT_FOUND: 138 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_SUB_SESSION_KEY_NOT_FOUND: 139 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_SUB_SESSION_KEY_NOT_APPLICABLE: 140 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_SESSION_KEY_NOT_FOUND: 141 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_ADDRESS_NOT_FOUND: 142 case UwbUciConstants.MULTICAST_LIST_UPDATE_STATUS_ERROR_ADDRESS_ALREADY_PRESENT: 143 rangingChangeReason = RangingChangeReason.BAD_PARAMETERS; 144 break; 145 } 146 return rangingChangeReason; 147 } 148 149 /** 150 * Convert UCI reason code values to UCI status code, as some of the callbacks expect to get 151 * the latter. 152 */ convertUciReasonCodeToUciStatusCode(int reasonCode)153 public static int convertUciReasonCodeToUciStatusCode(int reasonCode) { 154 int statusCode = UwbUciConstants.STATUS_CODE_FAILED; 155 switch (reasonCode) { 156 case UwbUciConstants.REASON_STATE_CHANGE_WITH_SESSION_MANAGEMENT_COMMANDS: 157 statusCode = UwbUciConstants.STATUS_CODE_OK; 158 break; 159 case UwbUciConstants.REASON_ERROR_SESSION_KEY_NOT_FOUND: 160 case UwbUciConstants.REASON_ERROR_SUB_SESSION_KEY_NOT_FOUND: 161 statusCode = UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST; 162 break; 163 } 164 return statusCode; 165 } 166 convertUciStatusToApiCccProtocolError(int status)167 private static @CccParams.ProtocolError int convertUciStatusToApiCccProtocolError(int status) { 168 switch (status) { 169 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 170 return CccParams.PROTOCOL_ERROR_NOT_FOUND; 171 case UwbUciConstants.STATUS_CODE_CCC_LIFECYCLE: 172 return CccParams.PROTOCOL_ERROR_LIFECYCLE; 173 case UwbUciConstants.STATUS_CODE_CCC_SE_BUSY: 174 return CccParams.PROTOCOL_ERROR_SE_BUSY; 175 default: 176 return CccParams.PROTOCOL_ERROR_UNKNOWN; 177 } 178 } 179 convertUciStatusToApiAliroProtocolError( int status)180 private static @AliroParams.ProtocolError int convertUciStatusToApiAliroProtocolError( 181 int status) { 182 switch (status) { 183 case UwbUciConstants.STATUS_CODE_ERROR_SESSION_NOT_EXIST: 184 return AliroParams.PROTOCOL_ERROR_NOT_FOUND; 185 default: 186 return AliroParams.PROTOCOL_ERROR_UNKNOWN; 187 } 188 } 189 convertUciStatusToParam(String protocolName, int status)190 public static PersistableBundle convertUciStatusToParam(String protocolName, int status) { 191 Params c; 192 if (protocolName.equals(CccParams.PROTOCOL_NAME)) { 193 c = new CccRangingError.Builder() 194 .setError(convertUciStatusToApiCccProtocolError(status)) 195 .build(); 196 } else if (protocolName.equals(AliroParams.PROTOCOL_NAME)) { 197 c = new AliroRangingError.Builder() 198 .setError(convertUciStatusToApiAliroProtocolError(status)) 199 .build(); 200 } else { 201 c = new FiraStatusCode.Builder().setStatusCode(status).build(); 202 } 203 return c.toBundle(); 204 } 205 getSessionStateString(int state)206 static String getSessionStateString(int state) { 207 String ret = ""; 208 switch (state) { 209 case UwbUciConstants.UWB_SESSION_STATE_INIT: 210 ret = "INIT"; 211 break; 212 case UwbUciConstants.UWB_SESSION_STATE_DEINIT: 213 ret = "DEINIT"; 214 break; 215 case UwbUciConstants.UWB_SESSION_STATE_ACTIVE: 216 ret = "ACTIVE"; 217 break; 218 case UwbUciConstants.UWB_SESSION_STATE_IDLE: 219 ret = "IDLE"; 220 break; 221 case UwbUciConstants.UWB_SESSION_STATE_ERROR: 222 ret = "ERROR"; 223 break; 224 } 225 return ret; 226 } 227 } 228