mgmt+face: move protocol-specific face creation checks into protocol factories

Also brought implementation of faces/create in line with design

refs #3731

Change-Id: I4f48079136b42c7fdbd4fdfba37116d2565f9dc1
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 8b7057c..9cd0e07 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -91,17 +91,21 @@
   FaceUri uri;
   if (!uri.parse(parameters.getUri())) {
     NFD_LOG_TRACE("failed to parse URI");
-    return done(ControlResponse(400, "Malformed command"));
+    done(ControlResponse(400, "Malformed command"));
+    return;
   }
 
   if (!uri.isCanonical()) {
     NFD_LOG_TRACE("received non-canonical URI");
-    return done(ControlResponse(400, "Non-canonical URI"));
+    done(ControlResponse(400, "Non-canonical URI"));
+    return;
   }
 
   auto factory = m_factories.find(uri.getScheme());
   if (factory == m_factories.end()) {
-    return done(ControlResponse(501, "Unsupported protocol"));
+    NFD_LOG_TRACE("received create request for unsupported protocol");
+    done(ControlResponse(406, "Unsupported protocol"));
+    return;
   }
 
   try {
@@ -110,35 +114,50 @@
                                 bind(&FaceManager::afterCreateFaceSuccess,
                                      this, parameters, _1, done),
                                 bind(&FaceManager::afterCreateFaceFailure,
-                                     this, _1, done));
+                                     this, _1, _2, done));
   }
   catch (const std::runtime_error& error) {
-    std::string errorMessage = "Face creation failed: ";
-    errorMessage += error.what();
-
-    NFD_LOG_ERROR(errorMessage);
-    return done(ControlResponse(500, errorMessage));
+    NFD_LOG_ERROR("Face creation failed: " << error.what());
+    done(ControlResponse(500, "Face creation failed due to internal error"));
+    return;
   }
   catch (const std::logic_error& error) {
-    std::string errorMessage = "Face creation failed: ";
-    errorMessage += error.what();
-
-    NFD_LOG_ERROR(errorMessage);
-    return done(ControlResponse(500, errorMessage));
+    NFD_LOG_ERROR("Face creation failed: " << error.what());
+    done(ControlResponse(500, "Face creation failed due to internal error"));
+    return;
   }
 }
 
+/**
+ * \todo #3232
+ *       If the creation of this face would conflict with an existing face (e.g. same underlying
+ *       protocol and remote address, or a NIC-associated permanent face), the command will fail
+ *       with StatusCode 409.
+ */
 void
-FaceManager::afterCreateFaceSuccess(ControlParameters& parameters,
+FaceManager::afterCreateFaceSuccess(const ControlParameters& parameters,
                                     const shared_ptr<Face>& newFace,
                                     const ndn::mgmt::CommandContinuation& done)
 {
-  m_faceTable.add(newFace);
-  parameters.setFaceId(newFace->getId());
-  parameters.setUri(newFace->getRemoteUri().toString());
-  parameters.setFacePersistency(newFace->getPersistency());
+  ControlParameters response;
 
-  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  m_faceTable.add(newFace);
+
+  // Set ControlResponse parameters
+  response.setFaceId(newFace->getId());
+  response.setFacePersistency(newFace->getPersistency());
+
+  done(ControlResponse(200, "OK").setBody(response.wireEncode()));
+}
+
+void
+FaceManager::afterCreateFaceFailure(uint32_t status,
+                                    const std::string& reason,
+                                    const ndn::mgmt::CommandContinuation& done)
+{
+  NFD_LOG_DEBUG("Face creation failed: " << reason);
+
+  done(ControlResponse(status, reason));
 }
 
 void
@@ -155,15 +174,6 @@
 }
 
 void
-FaceManager::afterCreateFaceFailure(const std::string& reason,
-                                    const ndn::mgmt::CommandContinuation& done)
-{
-  NFD_LOG_DEBUG("Failed to create face: " << reason);
-
-  done(ControlResponse(408, "Failed to create face: " + reason));
-}
-
-void
 FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
                                 const ControlParameters& parameters,
                                 const ndn::mgmt::CommandContinuation& done)
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index f31f04b..094f288 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -77,12 +77,13 @@
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers for ControlCommand
   void
-  afterCreateFaceSuccess(ControlParameters& parameters,
+  afterCreateFaceSuccess(const ControlParameters& parameters,
                          const shared_ptr<Face>& newFace,
                          const ndn::mgmt::CommandContinuation& done);
 
   void
-  afterCreateFaceFailure(const std::string& reason,
+  afterCreateFaceFailure(uint32_t status,
+                         const std::string& reason,
                          const ndn::mgmt::CommandContinuation& done);
 
   Face*