Add support for NDN-FCH hub discovery
Change-Id: Iff39ef6667e7b6e69be7ae8205cc387015f44631
Refs: #4028
diff --git a/app/src/main/java/net/named_data/nfd/FaceListFragment.java b/app/src/main/java/net/named_data/nfd/FaceListFragment.java
index 4a605d1..022ec32 100644
--- a/app/src/main/java/net/named_data/nfd/FaceListFragment.java
+++ b/app/src/main/java/net/named_data/nfd/FaceListFragment.java
@@ -1,6 +1,6 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015 Regents of the University of California
+ * Copyright (c) 2015-2017 Regents of the University of California
*
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
@@ -50,7 +50,7 @@
import net.named_data.jndn_xx.util.FaceUri;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
-import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
+import net.named_data.nfd.utils.SharedPreferencesManager;
import java.util.HashSet;
import java.util.List;
@@ -436,11 +436,11 @@
if (null != one){
removeRoutesOfFace(nfdcHelper, faceId);
// TODO: what if face was saved but is not in the face list? Is it possible?
- PermanentFaceUriAndRouteManager.deletePermanentFaceUri(
+ SharedPreferencesManager.deletePermanentFaceUri(
context,
one.getRemoteUri()
);
- PermanentFaceUriAndRouteManager.deletePermanentFaceId(context, faceId);
+ SharedPreferencesManager.deletePermanentFaceId(context, faceId);
nfdcHelper.faceDestroy(faceId);
}
}
@@ -506,11 +506,11 @@
Context context = getActivity().getApplicationContext();
int faceId = nfdcHelper.faceCreate(m_faceUri);
if (m_isPermanent) {
- PermanentFaceUriAndRouteManager.addPermanentFaceUri(
+ SharedPreferencesManager.addPermanentFaceUri(
context,
NfdcHelper.formatFaceUri(m_faceUri)
);
- PermanentFaceUriAndRouteManager.addPermanentFaceId(context, faceId);
+ SharedPreferencesManager.addPermanentFaceId(context, faceId);
}
nfdcHelper.shutdown();
return "OK. Face id: " + String.valueOf(faceId);
diff --git a/app/src/main/java/net/named_data/nfd/MainFragment.java b/app/src/main/java/net/named_data/nfd/MainFragment.java
index 72df064..f7a6f2e 100644
--- a/app/src/main/java/net/named_data/nfd/MainFragment.java
+++ b/app/src/main/java/net/named_data/nfd/MainFragment.java
@@ -41,18 +41,34 @@
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
+import android.widget.Toast;
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+import com.intel.jndn.management.ManagementException;
import com.intel.jndn.management.types.ForwarderStatus;
+import com.intel.jndn.management.types.RibEntry;
+import net.named_data.jndn.Name;
import net.named_data.nfd.service.NfdService;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
+import net.named_data.nfd.utils.SharedPreferencesManager;
import net.named_data.nfd.wifidirect.utils.NDNController;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormat;
+import java.util.List;
+
public class MainFragment extends Fragment {
+ public static final String URI_UDP_PREFIX = "udp://";
+ public static final String PREFIX_NDN = "/";
+ public static final String PREFIX_LOCALHOP_NFD = "/localhop/nfd";
public static MainFragment newInstance() {
// Create fragment arguments here (if necessary)
@@ -88,6 +104,24 @@
}
});
+ m_connectNearestHubSwitch = (Switch) v.findViewById(R.id.connect_nearest_hub_switch);
+ if (SharedPreferencesManager.getConnectNearestHubAutomatically(getActivity().getApplicationContext())) {
+ m_connectNearestHubSwitch.setChecked(true);
+ }
+ m_connectNearestHubSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean isOn) {
+ SharedPreferencesManager.
+ setConnectNearestHubAutomatically(getActivity().getApplicationContext(), isOn);
+ if (isOn) {
+ // when nfd service is running, connect NDN hub, otherwise, do nothing
+ if(m_sharedPreferences.getBoolean(PREF_NFD_SERVICE_STATUS, true)) {
+ connectNearestHub();
+ }
+ }
+ }
+ });
+
m_nfdStatusView = (ViewGroup) v.findViewById(R.id.status_view);
m_nfdStatusView.setVisibility(View.GONE);
m_versionView = (TextView) v.findViewById(R.id.version);
@@ -107,6 +141,14 @@
return v;
}
+ /**
+ * when the user clicks "connect to the nearest hub automatically", create face and register prefix
+ */
+ private void connectNearestHub() {
+ m_connectNearestHubAsyncTask = new ConnectNearestHubAsyncTask();
+ m_connectNearestHubAsyncTask.execute();
+ }
+
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -360,6 +402,91 @@
}
}
+
+ private class ConnectNearestHubAsyncTask extends AsyncTask<Void, Void, String> {
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ //check whether two prefixes exist or not
+ boolean prefix_ndn_exist = false;
+ boolean prefix_localhop_nfd_exist = false;
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ List<RibEntry> ribEntries = nfdcHelper.ribList();
+ for (RibEntry one : ribEntries) {
+ if (one.getName().toUri().equals(PREFIX_NDN)) {
+ prefix_ndn_exist = true;
+ }
+
+ if (one.getName().toUri().equals(PREFIX_LOCALHOP_NFD)) {
+ prefix_localhop_nfd_exist = true;
+ }
+ }
+ } catch (ManagementException e) {
+ G.Log("Error fetching RIB list from NFD (" + e.getMessage() + ")");
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ if (prefix_ndn_exist && prefix_localhop_nfd_exist)
+ return "";
+ final boolean prefix_ndn_exist_inner = prefix_ndn_exist;
+ final boolean prefix_localhop_nfd_exist_inner = prefix_localhop_nfd_exist;
+ //register prefixes if they don't exist
+ RequestQueue queue = Volley.newRequestQueue(getContext());
+ StringRequest stringRequest = new StringRequest(Request.Method.GET,
+ getResources().getString(R.string.ndn_fch_website),
+ new Response.Listener<String>() {
+ @Override
+ public void onResponse(String response) {
+ if (!prefix_ndn_exist_inner)
+ new RouteCreateToConnectNearestHubAsyncTask(
+ new Name(PREFIX_NDN), URI_UDP_PREFIX + response).execute();
+ if (!prefix_localhop_nfd_exist_inner)
+ new RouteCreateToConnectNearestHubAsyncTask(
+ new Name(PREFIX_LOCALHOP_NFD), URI_UDP_PREFIX + response).execute();
+ }
+ },
+ new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ String toastString = getResources().getString(R.string.fragment_route_list_toast_cannot_connect_hub);
+ Toast.makeText(getActivity(), toastString, Toast.LENGTH_LONG).show();
+ }
+ });
+ // Add the request to the RequestQueue.
+ queue.add(stringRequest);
+ return "";
+ }
+ }
+
+ private class RouteCreateToConnectNearestHubAsyncTask extends AsyncTask<Void, Void, String> {
+ RouteCreateToConnectNearestHubAsyncTask(Name prefix, String faceUri) {
+ m_prefix = prefix;
+ m_faceUri = faceUri;
+ }
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ G.Log("Try to create route to connect the nearest hub");
+ int faceId = nfdcHelper.faceCreate(m_faceUri);
+ nfdcHelper.ribRegisterPrefix(m_prefix, faceId, 10, true, false);
+ G.Log("Create permanent route" + m_prefix + " - " + m_faceUri);
+ } catch (Exception e) {
+ G.Log("Error in RouteCreateToConnectNearestHubAsyncTask: " + e.getMessage());
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ return null;
+ }
+
+ private Name m_prefix;
+ private String m_faceUri;
+ }
+
//////////////////////////////////////////////////////////////////////////////
/**
@@ -368,10 +495,17 @@
private Switch m_nfdStartStopSwitch;
/**
+ * Button that starts and stops the auto configuration
+ */
+ private Switch m_connectNearestHubSwitch;
+
+ /**
* Flag that marks that application is connected to the NfdService
*/
private boolean m_isNfdServiceConnected = false;
+ private ConnectNearestHubAsyncTask m_connectNearestHubAsyncTask;
+
/**
* Client Message Handler
*/
@@ -412,4 +546,6 @@
private SharedPreferences m_sharedPreferences;
private static final String PREF_NFD_SERVICE_STATUS = "NFD_SERVICE_STATUS";
+
+ private static final String CONNECT_NEAREST_HUB_STATUS = "CONNECT_NEAREST_HUB_STATUS";
}
\ No newline at end of file
diff --git a/app/src/main/java/net/named_data/nfd/RouteListFragment.java b/app/src/main/java/net/named_data/nfd/RouteListFragment.java
index 2201381..275dcde 100644
--- a/app/src/main/java/net/named_data/nfd/RouteListFragment.java
+++ b/app/src/main/java/net/named_data/nfd/RouteListFragment.java
@@ -1,6 +1,6 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015-2016 Regents of the University of California
+ * Copyright (c) 2015-2017 Regents of the University of California
* <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
@@ -19,7 +19,9 @@
package net.named_data.nfd;
+import android.app.AlertDialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
@@ -33,15 +35,13 @@
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.AdapterView;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
import com.intel.jndn.management.ManagementException;
import com.intel.jndn.management.types.FaceStatus;
@@ -52,7 +52,7 @@
import net.named_data.jndn_xx.util.FaceUri;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
-import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
+import net.named_data.nfd.utils.SharedPreferencesManager;
import java.util.ArrayList;
import java.util.List;
@@ -75,11 +75,10 @@
}
@Override
- public void onAttach(Context context)
- {
+ public void onAttach(Context context) {
super.onAttach(context);
try {
- m_callbacks = (Callbacks)context;
+ m_callbacks = (Callbacks) context;
} catch (Exception e) {
G.Log("Hosting activity must implement this fragment's callbacks: " + e);
}
@@ -111,22 +110,21 @@
final RibEntry entry = (RibEntry) parent.getItemAtPosition(position);
;
new AlertDialog.Builder(v.getContext())
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle("Deleting route")
- .setMessage("Are you sure you want to delete " + entry.getName().toUri() + "?")
- .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- List<Integer> faceList = new ArrayList<>();
- for (Route r : entry.getRoutes()) {
- faceList.add(r.getFaceId());
- }
- removeRoute(entry.getName(), faceList);
- Toast.makeText(getActivity(), "Route Deleted", Toast.LENGTH_LONG).show();
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle("Deleting route")
+ .setMessage("Are you sure you want to delete " + entry.getName().toUri() + "?")
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ List<Integer> faceList = new ArrayList<>();
+ for (Route r : entry.getRoutes()) {
+ faceList.add(r.getFaceId());
}
- })
- .setNegativeButton("No", null)
- .show();
+ removeRoute(entry.getName(), faceList);
+ }
+ })
+ .setNegativeButton("No", null)
+ .show();
return true;
@@ -221,10 +219,10 @@
FaceStatus face,
Name prefix) throws ManagementException {
nfdcHelper.ribUnregisterPrefix(prefix, face.getFaceId());
- PermanentFaceUriAndRouteManager.deletePermanentRoute(
- applicationContext,
- prefix.toString(),
- face.getRemoteUri()
+ SharedPreferencesManager.deletePermanentRoute(
+ applicationContext,
+ prefix.toString(),
+ face.getRemoteUri()
);
}
@@ -237,10 +235,10 @@
try {
for (int faceId : faceIds) {
removeOneRouteSync(
- applicationContext,
- nfdcHelper,
- faceSparseArray.get(faceId),
- prefix);
+ applicationContext,
+ nfdcHelper,
+ faceSparseArray.get(faceId),
+ prefix);
}
} finally {
nfdcHelper.shutdown();
@@ -256,10 +254,10 @@
try {
for (Name prefix : prefixes) {
removeOneRouteSync(
- applicationContext,
- nfdcHelper,
- faceSparseArray.get(faceId),
- prefix);
+ applicationContext,
+ nfdcHelper,
+ faceSparseArray.get(faceId),
+ prefix);
}
} finally {
nfdcHelper.shutdown();
@@ -270,7 +268,7 @@
/**
* Updates the underlying adapter with the given list of RibEntry.
- *
+ * <p>
* Note: This method should only be called from the UI thread.
*
* @param list Update ListView with the given List<RibEntry>
@@ -428,8 +426,8 @@
if (result.second != null) {
Toast.makeText(getActivity(),
- "Error communicating with NFD (" + result.second.getMessage() + ")",
- Toast.LENGTH_LONG).show();
+ "Error communicating with NFD (" + result.second.getMessage() + ")",
+ Toast.LENGTH_LONG).show();
}
updateRouteList(result.first);
@@ -452,12 +450,12 @@
nfdcHelper.ribRegisterPrefix(new Name(m_prefix), faceId, 10, true, false);
if (m_isPermanent) {
Context context = getActivity().getApplicationContext();
- PermanentFaceUriAndRouteManager
- .addPermanentRoute(
- context,
- m_prefix.toUri(),
- NfdcHelper.formatFaceUri(m_faceUri)
- );
+ SharedPreferencesManager
+ .addPermanentRoute(
+ context,
+ m_prefix.toUri(),
+ NfdcHelper.formatFaceUri(m_faceUri)
+ );
}
nfdcHelper.shutdown();
return "OK";
@@ -557,19 +555,29 @@
/////////////////////////////////////////////////////////////////////////////
- /** Callback handler of the hosting activity */
+ /**
+ * Callback handler of the hosting activity
+ */
private Callbacks m_callbacks;
- /** Reference to the most recent AsyncTask that was created for listing routes */
+ /**
+ * Reference to the most recent AsyncTask that was created for listing routes
+ */
private RouteListAsyncTask m_routeListAsyncTask;
- /** Reference to the view to be displayed when no information is available */
+ /**
+ * Reference to the view to be displayed when no information is available
+ */
private View m_routeListInfoUnavailableView;
- /** Progress bar spinner to display to user when destroying faces */
+ /**
+ * Progress bar spinner to display to user when destroying faces
+ */
private ProgressBar m_reloadingListProgressBar;
- /** Reference to the most recent AsyncTask that was created for creating a route */
+ /**
+ * Reference to the most recent AsyncTask that was created for creating a route
+ */
private RouteCreateAsyncTask m_routeCreateAsyncTask;
private RouteRemoveAsyncTask m_routeRemoveAsyncTask;
diff --git a/app/src/main/java/net/named_data/nfd/service/NfdService.java b/app/src/main/java/net/named_data/nfd/service/NfdService.java
index 1b2d4e4..79d18ca 100644
--- a/app/src/main/java/net/named_data/nfd/service/NfdService.java
+++ b/app/src/main/java/net/named_data/nfd/service/NfdService.java
@@ -1,18 +1,18 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2015-2017 Regents of the University of California
- *
+ * <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
- *
+ * <p>
* NFD Android is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
- *
+ * <p>
* NFD Android is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
- *
+ * <p>
* You should have received a copy of the GNU General Public License along with
* NFD Android, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -29,10 +29,21 @@
import android.os.Messenger;
import android.os.RemoteException;
+import com.android.volley.Request;
+import com.android.volley.RequestQueue;
+import com.android.volley.Response;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+import com.intel.jndn.management.ManagementException;
+import com.intel.jndn.management.types.RibEntry;
+
import net.named_data.jndn.Name;
+import net.named_data.nfd.MainFragment;
+import net.named_data.nfd.R;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
-import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
+import net.named_data.nfd.utils.SharedPreferencesManager;
import java.util.HashMap;
import java.util.List;
@@ -41,11 +52,10 @@
/**
* NfdService that runs the native NFD.
- *
+ * <p>
* NfdService runs as an independent process within the Android OS that provides
* service level features to start and stop the NFD native code through the
* NFD JNI wrapper.
- *
*/
public class NfdService extends Service {
/**
@@ -91,6 +101,7 @@
/**
* Native API for getting NFD status
+ *
* @return if NFD is running return true; otherwise false.
*/
public native static boolean
@@ -99,19 +110,29 @@
public native static List<String>
getNfdLogModules();
- /** Message to start NFD Service */
+ /**
+ * Message to start NFD Service
+ */
public static final int START_NFD_SERVICE = 1;
- /** Message to stop NFD Service */
+ /**
+ * Message to stop NFD Service
+ */
public static final int STOP_NFD_SERVICE = 2;
- /** Message to indicate that NFD Service is running */
+ /**
+ * Message to indicate that NFD Service is running
+ */
public static final int NFD_SERVICE_RUNNING = 3;
- /** Message to indicate that NFD Service is not running */
+ /**
+ * Message to indicate that NFD Service is not running
+ */
public static final int NFD_SERVICE_STOPPED = 4;
- /** debug tag */
+ /**
+ * debug tag
+ */
public static final String TAG = NfdService.class.getName();
@@ -128,6 +149,7 @@
serviceStartNfd();
createPermanentFaceUriAndRoute();
+ connectToNeareastHub();
// Service is restarted when killed.
// Pending intents delivered; null intent redelivered otherwise.
@@ -169,7 +191,7 @@
m_isNfdStarted = true;
HashMap<String, String> params = new HashMap<>();
params.put("homePath", getFilesDir().getAbsolutePath());
- Set<Map.Entry<String,String>> e = params.entrySet();
+ Set<Map.Entry<String, String>> e = params.entrySet();
startNfd(params);
@@ -207,6 +229,22 @@
}
}
+ private void connectToNeareastHub() {
+ final long checkInterval = 1000;
+ if (isNfdRunning()) {
+ G.Log(TAG, "connectToNeareastHub: NFD is running, start executing task.");
+ new ConnectNearestHubAsyncTask(getApplicationContext()).execute();
+ } else {
+ G.Log(TAG, "connectToNeareastHub: NFD is not started yet, delay " + String.valueOf(checkInterval) + " ms.");
+ m_handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ connectToNeareastHub();
+ }
+ }, checkInterval);
+ }
+ }
+
/**
* Thread safe way of stopping the NFD and updating the
* started flag.
@@ -218,7 +256,7 @@
// TODO: Save NFD and NRD in memory data structures.
stopNfd();
- PermanentFaceUriAndRouteManager.clearFaceIds(getApplicationContext());
+ SharedPreferencesManager.clearFaceIds(getApplicationContext());
stopSelf();
G.Log(TAG, "serviceStopNfd()");
}
@@ -241,11 +279,11 @@
NfdcHelper nfdcHelper = new NfdcHelper();
try {
G.Log(TAG, "Try to create permanent face");
- Set<String> permanentFace = PermanentFaceUriAndRouteManager.getPermanentFaceUris(this.context);
+ Set<String> permanentFace = SharedPreferencesManager.getPermanentFaceUris(this.context);
G.Log(TAG, "Permanent face list has " + permanentFace.size() + " item(s)");
for (String one : permanentFace) {
int faceId = nfdcHelper.faceCreate(one);
- PermanentFaceUriAndRouteManager.addPermanentFaceId(this.context, faceId);
+ SharedPreferencesManager.addPermanentFaceId(this.context, faceId);
G.Log(TAG, "Create permanent face " + one);
}
} catch (Exception e) {
@@ -262,6 +300,7 @@
*/
private static class RouteCreateAsyncTask extends AsyncTask<Void, Void, String> {
Context context;
+
RouteCreateAsyncTask(Context ctx) {
this.context = ctx;
}
@@ -272,7 +311,7 @@
NfdcHelper nfdcHelper = new NfdcHelper();
try {
G.Log(TAG, "Try to create permanent route");
- Set<String[]> prefixAndFacePairs = PermanentFaceUriAndRouteManager.getPermanentRoutes(this.context);
+ Set<String[]> prefixAndFacePairs = SharedPreferencesManager.getPermanentRoutes(this.context);
G.Log(TAG, "Permanent face list has " + prefixAndFacePairs.size() + " item(s)");
for (String[] prefixAndFaceUri : prefixAndFacePairs) {
int faceId = nfdcHelper.faceCreate(prefixAndFaceUri[1]);
@@ -288,6 +327,100 @@
}
}
+ private static class RouteCreateToConnectNearestHubAsyncTask extends AsyncTask<Void, Void, String> {
+ RouteCreateToConnectNearestHubAsyncTask(Name prefix, String faceUri) {
+ m_prefix = prefix;
+ m_faceUri = faceUri;
+ }
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ G.Log(TAG, "Try to create route to connect the nearest hub");
+ int faceId = nfdcHelper.faceCreate(m_faceUri);
+ nfdcHelper.ribRegisterPrefix(m_prefix, faceId, 10, true, false);
+ G.Log(TAG, "Create permanent route" + m_prefix + " - " + m_faceUri);
+ } catch (Exception e) {
+ G.Log(TAG, "Error in RouteCreateToConnectNearestHubAsyncTask: " + e.getMessage());
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ return null;
+ }
+
+ private Name m_prefix;
+ private String m_faceUri;
+ }
+
+ private static class ConnectNearestHubAsyncTask extends AsyncTask<Void, Void, String> {
+ Context context;
+
+ ConnectNearestHubAsyncTask(Context ctx) {
+ this.context = ctx;
+ }
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ G.Log(TAG, "Try to connect to the nearest hub");
+ if (SharedPreferencesManager.getConnectNearestHubAutomatically(context)) {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ //check whether two prefixes exist or not
+ boolean prefix_ndn_exist = false;
+ boolean prefix_localhop_nfd_exist = false;
+ List<RibEntry> ribEntries = nfdcHelper.ribList();
+ for (RibEntry one : ribEntries) {
+ if (one.getName().toUri().equals(MainFragment.PREFIX_NDN)) {
+ prefix_ndn_exist = true;
+ }
+
+ if (one.getName().toUri().equals(MainFragment.PREFIX_LOCALHOP_NFD)) {
+ prefix_localhop_nfd_exist = true;
+ }
+ }
+
+ //register prefixes if they don't exist
+ if (!prefix_ndn_exist || !prefix_localhop_nfd_exist) {
+ final boolean prefix_ndn_exist_inner = prefix_ndn_exist;
+ final boolean prefix_localhop_nfd_exist_inner = prefix_localhop_nfd_exist;
+ RequestQueue queue = Volley.newRequestQueue(context);
+ StringRequest stringRequest = new StringRequest(Request.Method.GET,
+ context.getResources().getString(R.string.ndn_fch_website),
+ new Response.Listener<String>() {
+ @Override
+ public void onResponse(String response) {
+ if (!prefix_ndn_exist_inner) {
+ new RouteCreateToConnectNearestHubAsyncTask(
+ new Name(MainFragment.PREFIX_NDN), MainFragment.URI_UDP_PREFIX + response).execute();
+ }
+ if (!prefix_localhop_nfd_exist_inner) {
+ new RouteCreateToConnectNearestHubAsyncTask(
+ new Name(MainFragment.PREFIX_LOCALHOP_NFD), MainFragment.URI_UDP_PREFIX + response).execute();
+ }
+ }
+ },
+ new Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ G.Log("cannot connect to the nearest hub");
+ }
+ });
+ // Add the request to the RequestQueue.
+ queue.add(stringRequest);
+ }
+ } catch (ManagementException e) {
+ G.Log(TAG, "Error in ConnectNearestHubAsyncTask: " + e.getMessage());
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ }
+ return null;
+ }
+ }
+
/**
* Message handler for the the NFD Service.
*/
@@ -296,19 +429,19 @@
@Override
public void handleMessage(Message message) {
switch (message.what) {
- case NfdService.START_NFD_SERVICE:
- serviceStartNfd();
- replyToClient(message, NfdService.NFD_SERVICE_RUNNING);
- break;
+ case NfdService.START_NFD_SERVICE:
+ serviceStartNfd();
+ replyToClient(message, NfdService.NFD_SERVICE_RUNNING);
+ break;
- case NfdService.STOP_NFD_SERVICE:
- serviceStopNfd();
- replyToClient(message, NfdService.NFD_SERVICE_STOPPED);
- break;
+ case NfdService.STOP_NFD_SERVICE:
+ serviceStopNfd();
+ replyToClient(message, NfdService.NFD_SERVICE_STOPPED);
+ break;
- default:
- super.handleMessage(message);
- break;
+ default:
+ super.handleMessage(message);
+ break;
}
}
@@ -322,12 +455,18 @@
}
}
- /** Messenger to handle messages that are passed to the NfdService */
+ /**
+ * Messenger to handle messages that are passed to the NfdService
+ */
private Messenger m_nfdServiceMessenger = null;
- /** Flag that denotes if the NFD has been started */
+ /**
+ * Flag that denotes if the NFD has been started
+ */
private boolean m_isNfdStarted = false;
- /** Handler to deal with timeout behaviors */
+ /**
+ * Handler to deal with timeout behaviors
+ */
private Handler m_handler = new Handler();
}
diff --git a/app/src/main/java/net/named_data/nfd/utils/ConnectivityChangeReceiver.java b/app/src/main/java/net/named_data/nfd/utils/ConnectivityChangeReceiver.java
index be9e2ee..bf23eb6 100644
--- a/app/src/main/java/net/named_data/nfd/utils/ConnectivityChangeReceiver.java
+++ b/app/src/main/java/net/named_data/nfd/utils/ConnectivityChangeReceiver.java
@@ -1,6 +1,6 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015-2016 Regents of the University of California
+ * Copyright (c) 2015-2017 Regents of the University of California
* <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
@@ -57,7 +57,9 @@
onChange(Context context, NetworkInfo networkInfo) {
if (networkInfo.isConnected()) {
G.Log(TAG, "Network is connected");
- // (re-)start service, triggering (re-)creation of permanent faces and routes
+ // (re-)start service,
+ // (1)triggering (re-)creation of permanent faces and routes
+ // (2)triggering (re-)connection to nearest hub
context.startService(new Intent(context, NfdService.class));
}
}
diff --git a/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java b/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
index 672003e..1eb35b8 100644
--- a/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
+++ b/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
@@ -176,7 +176,7 @@
{
List<FaceStatus> result = Nfdc.getFaceList(m_face);
for(FaceStatus one : result) {
- if(PermanentFaceUriAndRouteManager.isPermanentFace(context, one.getFaceId())) {
+ if(SharedPreferencesManager.isPermanentFace(context, one.getFaceId())) {
one.setFacePersistency(FacePersistency.PERMANENT);
}
}
diff --git a/app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java b/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
similarity index 89%
rename from app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java
rename to app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
index 3f2ccdd..9214e59 100644
--- a/app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java
+++ b/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
@@ -1,6 +1,6 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015-2016 Regents of the University of California
+ * Copyright (c) 2015-2017 Regents of the University of California
* <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
@@ -28,12 +28,13 @@
/**
* The manager to record and delete permanent faceUris and routes
*/
-public class PermanentFaceUriAndRouteManager {
- private static final String TAG = "Permanent Manager";
+public class SharedPreferencesManager {
+ private static final String TAG = "SharedPreferencesManager";
private static final String PREFS_NAME = "permanent";
private static final String PERMANENT_FACEURI = "permanentFaceUri";
private static final String PERMANENT_ROUTE = "permanentRoute";
private static final String PERMANENT_FACEID = "permanentFaceId";
+ private static final String CONNECT_NEAREAST_HUB = "connectNeareastHub";
private static final String PREFIX_FACEURI_DELIMITER = "\t";
// We need to cache permanent face IDs in order to display whether a face is permanent face or not.
@@ -164,4 +165,16 @@
G.Log(TAG, prefix + " " + faceUri + " is not a permanent route");
}
}
+
+ @SuppressWarnings("deprecation")
+ public static void setConnectNearestHubAutomatically(Context context, boolean isOn) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ setting.edit().putBoolean(CONNECT_NEAREAST_HUB, isOn).commit();
+ }
+
+ @SuppressWarnings("deprecation")
+ public static boolean getConnectNearestHubAutomatically(Context context) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ return setting.getBoolean(CONNECT_NEAREAST_HUB, false);
+ }
}
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index 2fb1d1f..b0d48f1 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -26,6 +26,18 @@
android:text="@string/checking_on_nfd"
/>
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="5dp"/>
+
+ <Switch
+ android:id="@+id/connect_nearest_hub_switch"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:text="@string/connect_nearest_hub_automatically"
+ />
+
<LinearLayout android:id="@+id/status_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5aa76b3..47032af 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -107,6 +107,9 @@
<string name="face_add_dialog_create_face">Create face</string>
<string name="route_add_dialog_create_route">Create route</string>
+ <string name="connect_nearest_hub_automatically">Connect to the nearest hub automatically</string>
+ <string name="ndn_fch_website">http://ndn-fch.named-data.net/</string>
+ <string name="fragment_route_list_toast_cannot_connect_hub">Cannot connect to the nearest hub</string>
<string name="fragment_route_details_title">Route Details</string>
<string name="fragment_route_details_next_hops">List of next hops</string>
<string name="fragment_route_route_name_title">Route Name</string>