Skip to content

Commit

Permalink
[DO NOT REVIEW][epskc] demo version impl for epskc
Browse files Browse the repository at this point in the history
  • Loading branch information
wgtdkp committed May 26, 2024
1 parent 86e37dd commit f3d2398
Show file tree
Hide file tree
Showing 30 changed files with 1,545 additions and 645 deletions.
2 changes: 1 addition & 1 deletion android/build-commissioner-libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ cmake -GNinja \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_TYPE=Debug \
-DOT_COMM_ANDROID=ON \
-DOT_COMM_JAVA_BINDING=ON \
-DOT_COMM_APP=OFF \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,29 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import io.openthread.commissioner.service.BorderAgentInfo;
import io.openthread.commissioner.service.FragmentCallback;
import io.openthread.commissioner.service.GetAdminPasscodeFragment;
import io.openthread.commissioner.service.JoinerDeviceInfo;
import io.openthread.commissioner.service.MeshcopFragment;
import io.openthread.commissioner.service.RetrieveDatasetFragment;
import io.openthread.commissioner.service.SetDatasetFragment;
import io.openthread.commissioner.service.ScanQrCodeFragment;
import io.openthread.commissioner.service.SelectNetworkFragment;
import io.openthread.commissioner.service.SelectBorderRouterFragment;
import io.openthread.commissioner.service.ThreadNetworkInfoHolder;

public class MainActivity extends AppCompatActivity implements FragmentCallback {

private static final String TAG = MainActivity.class.getSimpleName();

@Nullable private ThreadNetworkInfoHolder selectedNetwork;
@Nullable
private ThreadNetworkInfoHolder selectedNetwork;

@Nullable private byte[] pskc;
@Nullable
private byte[] pskc;

@Nullable private JoinerDeviceInfo joinerDeviceInfo;
@Nullable
private JoinerDeviceInfo joinerDeviceInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -69,7 +76,7 @@ protected void onCreate(Bundle savedInstanceState) {
gitHash.setText(BuildConfig.GIT_HASH);

if (savedInstanceState == null) {
showFragment(new SelectNetworkFragment(this, null), false);
showFragment(new SelectBorderRouterFragment(this), false);
}
}

Expand Down Expand Up @@ -154,4 +161,31 @@ public void onJoinerInfoReceived(@Nullable JoinerDeviceInfo joinerDeviceInfo) {
public void onMeshcopResult(int result) {
finishCommissioning(result);
}

@Override
public void onGetAdminPasscodeStarted(BorderAgentInfo borderAgentInfo, int adminPasscodeFlow) {
showFragment(new GetAdminPasscodeFragment(this, borderAgentInfo, adminPasscodeFlow), /* addToBackStack= */ true);
}

@Override
public void onAdminPasscodeReceived(BorderAgentInfo borderAgentInfo, int adminPasscodeFlow, String passcode,
int epskcPort) {
if (adminPasscodeFlow == GetAdminPasscodeFragment.FLOW_RETRIEVE_DATASET) {
showFragment(new RetrieveDatasetFragment(this, borderAgentInfo, passcode,
epskcPort), /* addToBackStack= */ true);
} else if (adminPasscodeFlow == GetAdminPasscodeFragment.FLOW_SET_DATASET) {
showFragment(new SetDatasetFragment(this, borderAgentInfo, passcode,
epskcPort), /* addToBackStack= */ true);
} else {
throw new AssertionError("Unknown Admin Passcode flow: " + adminPasscodeFlow);
}
}

@Override
public void onCredentialsRetrieved() {
selectedNetwork = null;
pskc = null;
joinerDeviceInfo = null;
clearFragmentsInBackStack();
}
}
6 changes: 5 additions & 1 deletion android/openthread_commissioner/service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ dependencies {

implementation fileTree(dir: "libs", include: ["*.jar"])

// Fix Duplicate class
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))

implementation 'com.google.guava:guava:31.1-jre'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.activity:activity:1.8.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation "androidx.concurrent:concurrent-futures:1.1.0"
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package io.openthread.commissioner.service;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import androidx.annotation.Nullable;
import io.openthread.commissioner.service.BorderAgentDiscoverer.BorderAgentListener;
import java.net.Inet6Address;
import java.util.Map;
import java.util.Vector;

public class BorderAgentAdapter extends BaseAdapter implements BorderAgentListener {

private final Vector<BorderAgentInfo> borderAgentServices = new Vector<>();
private final Map<String, BorderAgentInfo> epskcServices = new ArrayMap<>();

private final LayoutInflater inflater;

BorderAgentAdapter(Context context) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public void addBorderAgent(BorderAgentInfo serviceInfo) {
if (serviceInfo.isEpskcService) {
epskcServices.put(serviceInfo.instanceName, serviceInfo);
notifyDataSetChanged();
return;
}

boolean hasExistingBorderRouter = false;
for (int i = 0; i < borderAgentServices.size(); i++) {
if (borderAgentServices.get(i).instanceName.equals(serviceInfo.instanceName)) {
borderAgentServices.set(i, serviceInfo);
hasExistingBorderRouter = true;
}
}

if (!hasExistingBorderRouter) {
borderAgentServices.add(serviceInfo);
}

notifyDataSetChanged();
}

public void removeBorderAgent(boolean isEpskcService, String instanceName) {
if (isEpskcService) {
epskcServices.remove(instanceName);
} else {
borderAgentServices.removeIf(serviceInfo -> serviceInfo.instanceName.equals(instanceName));
}
notifyDataSetChanged();
}

public void clear() {
borderAgentServices.clear();
epskcServices.clear();
notifyDataSetChanged();
}

@Override
public int getCount() {
return borderAgentServices.size();
}

@Override
public Object getItem(int position) {
return borderAgentServices.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.border_agent_list_item, container, false);
}

BorderAgentInfo borderAgentInfo = borderAgentServices.get(position);

TextView instanceNameText = convertView.findViewById(R.id.border_agent_instance_name);
instanceNameText.setText(borderAgentInfo.instanceName);

TextView vendorNameText = convertView.findViewById(R.id.border_agent_vendor_name);
vendorNameText.setText(borderAgentInfo.vendorName);

TextView modelNameText = convertView.findViewById(R.id.border_agent_model_name);
modelNameText.setText(borderAgentInfo.modelName);

TextView adminModeText = convertView.findViewById(R.id.border_agent_admin_mode);
adminModeText.setText(
"In Administration Mode: " + (inAdministrationMode(borderAgentInfo) ? "YES" : "NO"));

TextView borderAgentIpAddrText = convertView.findViewById(R.id.border_agent_ip_addr);
int port = inAdministrationMode(borderAgentInfo) ? getEpskcService(borderAgentInfo).port
: borderAgentInfo.port;
String socketAddress;
if (borderAgentInfo.host instanceof Inet6Address) {
socketAddress = "[" + borderAgentInfo.host.getHostAddress() + "]:" + port;
} else {
socketAddress = borderAgentInfo.host.getHostAddress() + ":" + port;
}
borderAgentIpAddrText.setText(socketAddress);
return convertView;
}

private boolean inAdministrationMode(BorderAgentInfo borderAgentInfo) {
return epskcServices.containsKey(borderAgentInfo.instanceName);
}

@Override
public void onBorderAgentFound(BorderAgentInfo borderAgentInfo) {
new Handler(Looper.getMainLooper()).post(() -> addBorderAgent(borderAgentInfo));
}

@Override
public void onBorderAgentLost(boolean isEpskcService, String instanceName) {
new Handler(Looper.getMainLooper()).post(() -> removeBorderAgent(isEpskcService, instanceName));
}


/**
* Returns the _meshcop-e._udp service which is associated with the given _meshcop._udp service,
* or {@code null} if such service doesn't exist.
*/
@Nullable
private BorderAgentInfo getEpskcService(BorderAgentInfo meshcopService) {
return epskcServices.get(meshcopService.instanceName);
}
}
Loading

0 comments on commit f3d2398

Please sign in to comment.