Skip to content

Commit

Permalink
4.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Aug 10, 2022
1 parent 01f6985 commit 5e8fb3a
Show file tree
Hide file tree
Showing 23 changed files with 204 additions and 72 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Release Notes

## 4.0.1 (2022-08-10)

Features:
- Added support for two new Identiv USB readers
- Identive CLOUD 4700 F Dual Interface Reader
- Identiv uTrust 4701 F Dual Interface Reader
- Added error message for unknown USB readers

## 4.0.0 (2022-06-24)

Initial release for distribution.
52 changes: 32 additions & 20 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
# THE SOURCE CODE AND ITS RELATED DOCUMENTATION IS PROVIDED "AS IS". INFINEON
# TECHNOLOGIES MAKES NO OTHER WARRANTY OF ANY KIND,WHETHER EXPRESS,IMPLIED OR,
# STATUTORY AND DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
# SATISFACTORY QUALITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
#
# THE SOURCE CODE AND DOCUMENTATION MAY INCLUDE ERRORS. INFINEON TECHNOLOGIES
# RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE SOURCE CODE IN LATER
# REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE DOCUMENTATION OR
# THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
#
# INFINEON TECHNOLOGIES SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
# CONSEQUENTIAL DAMAGE OR LIABILITY ARISING FROM YOUR USE OF THE SOURCE CODE OR
# ANY DOCUMENTATION, INCLUDING BUT NOT LIMITED TO, LOST REVENUES, DATA OR
# PROFITS, DAMAGES OF ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL NATURE, PUNITIVE
# DAMAGES, LOSS OF PROPERTY OR LOSS OF PROFITS ARISING OUT OF OR IN CONNECTION
# WITH THIS AGREEMENT, OR BEING UNUSABLE, EVEN IF ADVISED OF THE POSSIBILITY OR
# PROBABILITY OF SUCH DAMAGES AND WHETHER A CLAIM FOR SUCH DAMAGE IS BASED UPON
# WARRANTY, CONTRACT, TORT, NEGLIGENCE OR OTHERWISE.
#
# (C)Copyright INFINEON TECHNOLOGIES All rights reserved
MIT License

Copyright (c) 2022 Infineon Technologies AG

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOURCE CODE AND ITS RELATED DOCUMENTATION IS PROVIDED "AS IS". INFINEON
TECHNOLOGIES MAKES NO OTHER WARRANTY OF ANY KIND,WHETHER EXPRESS,IMPLIED OR,
STATUTORY AND DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
SATISFACTORY QUALITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.

THE SOURCE CODE AND DOCUMENTATION MAY INCLUDE ERRORS. INFINEON TECHNOLOGIES
RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE SOURCE CODE IN LATER
REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE DOCUMENTATION OR
THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.

INFINEON TECHNOLOGIES SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
CONSEQUENTIAL DAMAGE OR LIABILITY ARISING FROM YOUR USE OF THE SOURCE CODE OR
ANY DOCUMENTATION, INCLUDING BUT NOT LIMITED TO, LOST REVENUES, DATA OR
PROFITS, DAMAGES OF ANY SPECIAL, INCIDENTAL OR CONSEQUENTIAL NATURE, PUNITIVE
DAMAGES, LOSS OF PROPERTY OR LOSS OF PROFITS ARISING OUT OF OR IN CONNECTION
WITH THIS AGREEMENT, OR BEING UNUSABLE, EVEN IF ADVISED OF THE POSSIBILITY OR
PROBABILITY OF SUCH DAMAGES AND WHETHER A CLAIM FOR SUCH DAMAGE IS BASED UPON
WARRANTY, CONTRACT, TORT, NEGLIGENCE OR OTHERWISE.
13 changes: 6 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ android {
applicationId "com.infineon.esim.lpa"
minSdkVersion 28
targetSdkVersion 32
versionCode 40000
versionName "4.0.0"
versionCode 40001
versionName "4.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
signingConfig signingConfigs.debug
}
Expand Down Expand Up @@ -110,7 +110,7 @@ dependencies {
// ---------------------------------------------------------------------------------------------
// CameraX library
// ---------------------------------------------------------------------------------------------
def cameraVersion = "1.2.0-alpha02"
def cameraVersion = "1.2.0-alpha04"
// Camera2 library
implementation "androidx.camera:camera-camera2:$cameraVersion"
// Camera core
Expand All @@ -128,10 +128,10 @@ dependencies {
// AppCompat
implementation "androidx.appcompat:appcompat:1.4.2"
// Activity (for permission handling)
implementation "androidx.activity:activity:1.4.0"
implementation "androidx.activity:activity:1.5.1"
// Fragment is needed for ActivityResult API to work properly (needs 1.3.0-rc01, 1.2.5 is not supporting ActivityResult)
// see: https://stackoverflow.com/questions/62771948/new-result-api-error-can-only-use-lower-16-bits-for-requestcode
implementation "androidx.fragment:fragment:1.4.1"
implementation "androidx.fragment:fragment:1.5.1"
// ConstraintLayout for profile list
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
// SwiperefreshLayout for profile list
Expand All @@ -144,7 +144,7 @@ dependencies {
// ---------------------------------------------------------------------------------------------
// Lifecycle management
// ---------------------------------------------------------------------------------------------
def lifecycle_version = "2.4.1"
def lifecycle_version = "2.5.1"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
Expand All @@ -171,7 +171,6 @@ dependencies {
// Testing
////////////////////////////////////////////////////////////////////////////////////////////////
testImplementation "androidx.arch.core:core-testing:2.1.0"
// testImplementation "junit:junit:4.13.2"
testImplementation "org.junit.jupiter:junit-jupiter-params:5.8.1"

androidTestImplementation "androidx.test:rules:1.4.1-alpha07"
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/infineon/esim/lpa/data/DataModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public LiveData<OneTimeEvent<Error>> getErrorEventLiveData() {

// region eUICC interface methods

public void refreshEuiccs() {
Log.debug(TAG, "Refreshing eUICC list...");
euiccManager.startRefreshingEuiccList();
}

public void selectEuicc(String euiccName) {
Log.debug(TAG, "Selecting euicc " + euiccName + "...");
euiccManager.selectEuicc(euiccName);
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/infineon/esim/lpa/euicc/EuiccManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public void onEuiccListRefreshed(List<String> euiccList) {

if(switchEuiccInterface != null) {
String euiccName = getDefaultEuiccNameFromTag(switchEuiccInterface);
startEuiccInitialization(euiccName);
selectEuicc(euiccName);

switchEuiccInterface = null;
}
Expand All @@ -308,23 +308,23 @@ public void onEuiccListRefreshed(List<String> euiccList) {
// Private methods

private String getDefaultEuiccNameFromTag(String interfaceTag) {
String defaultEuiccName = Preferences.getNoEuiccName();

try {
EuiccInterface euiccInterface = getEuiccInterfaceFromTag(interfaceTag);
List<String> euiccNames = euiccInterface.getEuiccNames();
String defaultEuiccName = null;

for (String readerName : euiccNames) {
defaultEuiccName = readerName;
break;
}

Log.debug(TAG, "Getting default reader name for reader tag \"" + interfaceTag + "\": \"" + defaultEuiccName + "\".");
return defaultEuiccName;
} catch (Exception e) {
statusAndEventHandler.onError(new Error("Error getting default reader name for reader " + interfaceTag + ".", e.getMessage()));
}

return null;
Log.debug(TAG, "Getting default reader name for reader tag \"" + interfaceTag + "\": \"" + defaultEuiccName + "\".");
return defaultEuiccName;
}

private String getFallbackEuicc() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class IdentiveConnectionBroadcastReceiver extends BroadcastReceiver {
private final OnDisconnectCallback onDisconnectCallback;

private static boolean hasBeenFreshlyAttached = false;
private static String lastReaderName;

public IdentiveConnectionBroadcastReceiver(Context context, OnDisconnectCallback onDisconnectCallback) {
this.context = context;
Expand All @@ -55,10 +56,15 @@ public void onReceive(Context context, Intent intent) {

switch (intent.getAction()) {
case UsbManager.ACTION_USB_DEVICE_ATTACHED:
UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
lastReaderName = usbDevice.getProductName();

Log.info(TAG,"USB reader \"" + lastReaderName + "\" attached.");
hasBeenFreshlyAttached = true;
// /* Do not directly initialize because of user prompt. Only in onResume method in the
// activity (e.g. ProfileListActivity).
// */

/* Do not directly initialize because of user prompt. Only in onResume method in the
activity (e.g. ProfileListActivity).
*/
break;
case UsbManager.ACTION_USB_DEVICE_DETACHED:
onDisconnectCallback.onDisconnect();
Expand All @@ -75,10 +81,14 @@ public void registerReceiver() {
context.registerReceiver(this, filter);
}

public static Boolean hasBeenFreshlyAttached() {
public static Boolean hasBeenFreshlyAttached() throws Exception {
if(hasBeenFreshlyAttached) {
hasBeenFreshlyAttached = false;
return true;
if(isValidReaderName(lastReaderName)) {
return true;
} else {
throw new Exception("Reader \"" + lastReaderName + "\" not supported.");
}
} else {
return false;
}
Expand All @@ -91,9 +101,7 @@ public static boolean isDeviceAttached() {
for (UsbDevice device : deviceList.values()) {
Log.debug(TAG, "USB device attached: " + device.getProductName());

if (device.getProductName().equals(IdentiveEuiccInterface.READER_NAME)) {
return true;
}
return isValidReaderName(device.getProductName());
}

return false;
Expand All @@ -102,4 +110,14 @@ public static boolean isDeviceAttached() {
public interface OnDisconnectCallback {
void onDisconnect();
}

private static boolean isValidReaderName(String readerName) {
for(String validReaderName : IdentiveEuiccInterface.READER_NAMES) {
if (readerName.equals(validReaderName)) {
return true;
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@
import com.infineon.esim.util.Log;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

final public class IdentiveEuiccInterface implements EuiccInterface {
private static final String TAG = IdentiveEuiccInterface.class.getName();

public static final String INTERFACE_TAG = "USB";
public static final String READER_NAME = "SCR3500 A Contact Reader";

public static final List<String> READER_NAMES = new ArrayList<>(Arrays.asList(
"SCR3500 A Contact Reader",
"Identive CLOUD 4700 F Dual Interface Reader",
"Identiv uTrust 4701 F Dual Interface Reader"
));

private final EuiccInterfaceStatusChangeHandler euiccInterfaceStatusChangeHandler;
private final IdentiveService identiveService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,17 @@ public String getEuiccName() {
public boolean resetEuicc() throws Exception {
Log.debug(TAG, "Resetting the eUICC.");

// Close the connection first
close();

// Wait for the phone to detect the profile change
try {
Thread.sleep(euiccConnectionSettings.getProfileInitializationTime());
} catch (Exception e) {
Log.error(Log.getFileLineNumber() + " " + e.getMessage());
}

// Open the connection again
return open();
}

Expand All @@ -81,24 +85,37 @@ public boolean open() throws Exception {
Log.debug(TAG, "Opening connection for eUICC " + reader.getName());
try {
if (session == null || session.isClosed()) {
Log.debug(TAG, "Opening a new session...");
session = reader.openSession();
if(session != null) {
Log.debug(TAG, "Successfully opened a new session.");
} else {
Log.error(TAG, "Failed to open a new session.");
return false;
}

if(!Atr.isAtrValid(session.getATR())) {
Log.error(TAG, "eUICC not allowed!");
close();
throw new Exception("eUICC not allowed!");
}
}

if (channel == null || !channel.isOpen()) {
Log.debug(TAG, "Opening a new logical channel...");
channel = session.openLogicalChannel(Bytes.decodeHexString(Definitions.ISDR_AID));

Log.debug(TAG, "Opened logical channel: " + Bytes.encodeHexString(channel.getSelectResponse()));
}
} catch (IOException e) {
Log.error(TAG, "Opening eUICC connection failed.", e);
throw new Exception("Opening eUICC connection failed.", e);
}

return channel.isOpen();
if(channel != null) {
return channel.isOpen();
} else {
return false;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;

import com.infineon.esim.lpa.Application;
import com.infineon.esim.lpa.euicc.base.EuiccConnection;
Expand Down Expand Up @@ -63,7 +64,11 @@ public boolean isAvailable() {
boolean isAvailable = false;

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
// Starting with Android R the existence of OMAPI can be checked
isAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_SE_OMAPI_UICC);
} else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
// Starting with Android P the OMAPI is part of Android but cannot be checked (yet).
isAvailable = true;
}

Log.debug(TAG, "Checking if SE eUICC interface is available: " + isAvailable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void dismissProgressDialog() {
switch (actionStatus.getActionStatus()) {
case REFRESHING_EUICC_LIST_STARTED:
Log.debug(TAG, "Show progress dialog for refreshing the eUICC list.");
progressDialog = DialogHelper.showProgressDialog(this, R.string.pref_progress_refreshing_reader_list);
progressDialog = DialogHelper.showProgressDialog(this, R.string.pref_progress_refreshing_euicc_list);
break;
case REFRESHING_EUICC_LIST_FINISHED:
Log.debug(TAG, "Refreshing eUICC list finished.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ public boolean onOptionsItemSelected(MenuItem item) {
// Clear all eUICC notifications
viewModel.clearAllNotifications();
return true;
} else if(id == R.id.action_refresh) {
} else if(id == R.id.action_refresh_esims) {
// Start eUICC info intent
viewModel.refreshEuiccs();
return true;
} else if(id == R.id.action_refresh_profile_list) {
// Start eUICC info intent
viewModel.refreshProfileList();
return true;
Expand Down Expand Up @@ -281,6 +285,11 @@ private void showAppVersionPopup() {
dismissProgressDialog();

switch (actionStatus.getActionStatus()) {
case REFRESHING_EUICC_LIST_STARTED: {
progressDialog = DialogHelper.showProgressDialog(this, R.string.pref_progress_refreshing_euicc_list);
disallowBackButtonPress();
break;
}
case OPENING_EUICC_CONNECTION_STARTED: {
String euiccName = (String) actionStatus.getExtras();
if(euiccName != null) {
Expand All @@ -305,6 +314,7 @@ private void showAppVersionPopup() {
disallowBackButtonPress();
break;
}
case REFRESHING_EUICC_LIST_FINISHED:
case OPENING_EUICC_CONNECTION_FINISHED:
case GET_PROFILE_LIST_FINISHED:
case ENABLE_PROFILE_FINISHED:
Expand Down
Loading

0 comments on commit 5e8fb3a

Please sign in to comment.