[SecureElement] Adjusted to new native api - part 2. 27/84827/2
authorTomasz Marciniak <t.marciniak@samsung.com>
Fri, 19 Aug 2016 13:24:44 +0000 (15:24 +0200)
committerTomasz Marciniak <t.marciniak@samsung.com>
Wed, 24 Aug 2016 07:14:11 +0000 (09:14 +0200)
[Verification] Code compiles.

Change-Id: I3374d0b42a910a6357e811ca72d40051d5f58e9c
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
src/secureelement/secureelement_instance.cc
src/secureelement/secureelement_instance.h

index 75063a7..899d855 100644 (file)
@@ -32,6 +32,13 @@ namespace {
 const std::string kPrivilegeSecureElement = "http://tizen.org/privilege/secureelement";
 
 const std::string kHandle = "handle";
+const std::string kIsBasicChannel = "isBasicChannel";
+const std::string kAid = "aid";
+const std::string kAction = "action";
+const std::string kListenerId = "listenerId";
+const std::string kListener = "SecureElementChangeListener";
+const std::string kReady = "onSEReady";
+const std::string kNotReady = "onSENotReady";
 
 TizenResult ConvertErrorCode(int error) {
   switch (error) {
@@ -57,10 +64,39 @@ TizenResult ConvertErrorCode(int error) {
   }
 }
 
+void SecureElementEventCb(int reader, smartcard_reader_event_type_e event_type, void *user_data) {
+  ScopeLogger();
+
+  //TODO What action should be performed in case of SMARTCARD_READER_EVENT_TYPE_IO_ERROR event
+  if (SMARTCARD_READER_EVENT_TYPE_INSERTED != event_type &&
+      SMARTCARD_READER_EVENT_TYPE_REMOVED != event_type) {
+    LoggerD("Incorrect event type");
+    return;
+  }
+
+  SecureElementInstance* instance = static_cast<SecureElementInstance*>(user_data);
+  if (!instance) {
+    LoggerD("user data is null");
+    return;
+  }
+
+  picojson::value result{picojson::object{}};
+  auto& obj = result.get<picojson::object>();
+
+  std::string action = SMARTCARD_READER_EVENT_TYPE_INSERTED == event_type ? kReady : kNotReady;
+
+  obj.insert(std::make_pair(kAction, picojson::value(action)));
+  obj.insert(std::make_pair(kHandle, picojson::value(static_cast<double>(reader))));
+  obj.insert(std::make_pair(kListenerId, picojson::value(kListener)));
+
+  instance->Instance::PostMessage(instance, result.serialize().c_str());
+}
+
 } //namespace
 
 SecureElementInstance::SecureElementInstance() :
-  is_initialized_(false) {
+  is_initialized_(false),
+  is_listener_set_(false) {
   ScopeLogger();
 
   using std::placeholders::_1;
@@ -101,12 +137,8 @@ SecureElementInstance::SecureElementInstance() :
 SecureElementInstance::~SecureElementInstance() {
   ScopeLogger();
 
-  if (is_initialized_) {
-    if (SMARTCARD_ERROR_NONE != smartcard_deinitialize()) {
-      LoggerE("Failed to deinitilize smartcard service");
-    }
-    is_initialized_ = false;
-  }
+  UnregisterListener();
+  Deinitialize();
 }
 
 // Service methods
@@ -157,7 +189,31 @@ TizenResult SecureElementInstance::RegisterSEListener(picojson::object const& ar
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  int ret = smartcard_reader_set_event_cb(SecureElementEventCb, this);
+  if (SMARTCARD_ERROR_NONE != ret) {
+    LogAndReturnTizenError(ConvertErrorCode(ret), ("smartcard_reader_set_event_cb() failed"));
+  }
+
+  is_listener_set_ = true;
+
+  return TizenSuccess();
+}
+
+TizenResult SecureElementInstance::UnregisterListener() {
+  ScopeLogger();
+
+  CHECK_PRIVILEGE(kPrivilegeSecureElement);
+
+  if (is_listener_set_) {
+    int ret = smartcard_reader_unset_event_cb();
+    if (SMARTCARD_ERROR_NONE != ret) {
+      LogAndReturnTizenError(ConvertErrorCode(ret), ("smartcard_reader_unset_event_cb() failed"));
+    }
+
+    is_listener_set_ = false;
+  }
+
+  return TizenSuccess();
 }
 
 TizenResult SecureElementInstance::UnregisterSEListener(picojson::object const& args) {
@@ -165,12 +221,14 @@ TizenResult SecureElementInstance::UnregisterSEListener(picojson::object const&
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  return UnregisterListener();
 }
 
-TizenResult SecureElementInstance::Shutdown(picojson::object const& args) {
+TizenResult SecureElementInstance::Deinitialize() {
   ScopeLogger();
 
+  CHECK_PRIVILEGE(kPrivilegeSecureElement);
+
   if (is_initialized_) {
     int ret = smartcard_deinitialize();
     if (SMARTCARD_ERROR_NONE != ret) {
@@ -183,6 +241,13 @@ TizenResult SecureElementInstance::Shutdown(picojson::object const& args) {
   return TizenSuccess();
 }
 
+TizenResult SecureElementInstance::Shutdown(picojson::object const& args) {
+  ScopeLogger();
+
+  UnregisterListener();
+  return Deinitialize();
+}
+
 // Reader methods
 TizenResult SecureElementInstance::GetName(picojson::object const& args) {
   ScopeLogger();
@@ -207,7 +272,16 @@ TizenResult SecureElementInstance::GetName(picojson::object const& args) {
 TizenResult SecureElementInstance::IsPresent(picojson::object const& args) {
   ScopeLogger();
 
-  return common::NotSupportedError();
+  int reader = static_cast<int>(args.find(kHandle)->second.get<double>());
+  bool is_present = false;
+
+  int ret = smartcard_reader_is_secure_element_present(reader, &is_present);
+  if (SMARTCARD_ERROR_NONE != ret) {
+    LogAndReturnTizenError(ConvertErrorCode(ret),
+                           ("smartcard_reader_is_secure_element_present() failed"));
+  }
+
+  return TizenSuccess(picojson::value(is_present));
 }
 
 TizenResult SecureElementInstance::OpenSession(picojson::object const& args, const common::AsyncToken& token) {
@@ -215,7 +289,30 @@ TizenResult SecureElementInstance::OpenSession(picojson::object const& args, con
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  int reader = static_cast<int>(args.find(kHandle)->second.get<double>());
+
+  auto open_session = [this, reader](const common::AsyncToken& token) -> void {
+    TizenResult result = TizenSuccess();
+    int session = 0;
+
+    int ret = smartcard_reader_open_session(reader, &session);
+    if (SMARTCARD_ERROR_NONE != ret) {
+      LoggerE("smartcard_reader_open_session() failed");
+      result = ConvertErrorCode(ret);
+    } else {
+      picojson::value response{picojson::object{}};
+      auto& obj = response.get<picojson::object>();
+
+      obj.insert(std::make_pair(kHandle, picojson::value(static_cast<double>(session))));
+      result = TizenSuccess(response);
+    }
+
+    this->Post(token, result);
+  };
+
+  std::thread(open_session, token).detach();
+
+  return TizenSuccess();
 }
 
 TizenResult SecureElementInstance::CloseSessions(picojson::object const& args) {
@@ -223,16 +320,74 @@ TizenResult SecureElementInstance::CloseSessions(picojson::object const& args) {
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  int reader = static_cast<int>(args.find(kHandle)->second.get<double>());
+
+  int ret = smartcard_reader_close_sessions(reader);
+  if (SMARTCARD_ERROR_NONE != ret) {
+    LogAndReturnTizenError(ConvertErrorCode(ret), ("smartcard_reader_close_sessions() failed"));
+  }
+
+  return TizenSuccess();
 }
 
 // Session functions
+
+TizenResult SecureElementInstance::IsBasicChannel(int channel, picojson::value& val) {
+  ScopeLogger();
+
+  bool is_basic = false;
+  int ret = smartcard_channel_is_basic_channel(channel, &is_basic);
+  if (SMARTCARD_ERROR_NONE != ret) {
+    LogAndReturnTizenError(ConvertErrorCode(ret), ("smartcard_channel_is_basic_channel() failed"));
+  }
+
+  auto& obj = val.get<picojson::object>();
+  obj.insert(std::make_pair(kIsBasicChannel, picojson::value(is_basic)));
+
+  return TizenSuccess(val);
+}
+
 TizenResult SecureElementInstance::OpenBasicChannel(picojson::object const& args, const common::AsyncToken& token) {
   ScopeLogger();
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  int session = static_cast<int>(args.find(kHandle)->second.get<double>());
+  const picojson::array v_aid = args.find(kAid)->second.get<picojson::array>();
+
+  auto open_basic_channel = [this, session, v_aid](const common::AsyncToken& token) -> void {
+    TizenResult result = TizenSuccess();
+    int channel = 0;
+    unsigned char P2 = 0;
+
+    size_t v_aid_size = v_aid.size();
+    unsigned char* aid = new unsigned char[v_aid_size];
+    SCOPE_EXIT {
+      delete [] aid;
+    };
+
+    for (size_t i = 0; i < v_aid_size; i++) {
+      aid[i] = static_cast<unsigned char>(v_aid[i].get<double>());
+    }
+
+    int ret = smartcard_session_open_basic_channel(session, aid, v_aid_size, P2, &channel);
+    if (SMARTCARD_ERROR_NONE != ret) {
+      LoggerE("smartcard_session_open_basic_channel() failed");
+      result = ConvertErrorCode(ret);
+    } else {
+      picojson::value response{picojson::object{}};
+      auto& obj = response.get<picojson::object>();
+
+      obj.insert(std::make_pair(kHandle, picojson::value(static_cast<double>(channel))));
+      result = IsBasicChannel(channel, response);
+    }
+
+    this->Post(token, result);
+  };
+
+  std::thread(open_basic_channel, token).detach();
+
+  return TizenSuccess();
 }
 
 TizenResult SecureElementInstance::OpenLogicalChannel(picojson::object const& args, const common::AsyncToken& token) {
@@ -240,7 +395,42 @@ TizenResult SecureElementInstance::OpenLogicalChannel(picojson::object const& ar
 
   CHECK_PRIVILEGE(kPrivilegeSecureElement);
 
-  return common::NotSupportedError();
+  int session = static_cast<int>(args.find(kHandle)->second.get<double>());
+  const picojson::array v_aid = args.find(kAid)->second.get<picojson::array>();
+
+  auto open_basic_logical = [this, session, v_aid](const common::AsyncToken& token) -> void {
+    TizenResult result = TizenSuccess();
+    int channel = 0;
+    unsigned char P2 = 0;
+
+    size_t v_aid_size = v_aid.size();
+    unsigned char* aid = new unsigned char[v_aid_size];
+    SCOPE_EXIT {
+      delete [] aid;
+    };
+
+    for (size_t i = 0; i < v_aid_size; i++) {
+      aid[i] = static_cast<unsigned char>(v_aid[i].get<double>());
+    }
+
+    int ret = smartcard_session_open_logical_channel(session, aid, v_aid_size, P2, &channel);
+    if (SMARTCARD_ERROR_NONE != ret) {
+      LoggerE("smartcard_session_open_logical_channel() failed");
+      result = ConvertErrorCode(ret);
+    } else {
+      picojson::value response{picojson::object{}};
+      auto& obj = response.get<picojson::object>();
+
+      obj.insert(std::make_pair(kHandle, picojson::value(static_cast<double>(channel))));
+      result = IsBasicChannel(channel, response);
+    }
+
+    this->Post(token, result);
+  };
+
+  std::thread(open_basic_logical, token).detach();
+
+  return TizenSuccess();
 }
 
 TizenResult SecureElementInstance::GetATR(picojson::object const& args) {
index 21a9bcc..d4e1295 100644 (file)
@@ -41,6 +41,7 @@ private:
     common::TizenResult CloseSessions(picojson::object const& args);
 
     /* Session methods */
+    common::TizenResult IsBasicChannel(int channel, picojson::value& val);
     common::TizenResult OpenBasicChannel(picojson::object const& args, const common::AsyncToken& token);
     common::TizenResult OpenLogicalChannel(picojson::object const& args, const common::AsyncToken& token);
     common::TizenResult GetATR(picojson::object const& args);
@@ -53,7 +54,11 @@ private:
     common::TizenResult Transmit(picojson::object const& args, const common::AsyncToken& token);
     common::TizenResult GetSelectResponse(picojson::object const& args);
 
+    common::TizenResult Deinitialize();
+    common::TizenResult UnregisterListener();
+
     bool is_initialized_;
+    bool is_listener_set_;
 };
 
 } // namespace secureelement