From: Tomasz Marciniak Date: Fri, 19 Aug 2016 13:24:44 +0000 (+0200) Subject: [SecureElement] Adjusted to new native api - part 2. X-Git-Tag: submit/tizen/20160831.012604~5^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F27%2F84827%2F2;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [SecureElement] Adjusted to new native api - part 2. [Verification] Code compiles. Change-Id: I3374d0b42a910a6357e811ca72d40051d5f58e9c Signed-off-by: Tomasz Marciniak --- diff --git a/src/secureelement/secureelement_instance.cc b/src/secureelement/secureelement_instance.cc index 75063a78..899d855e 100644 --- a/src/secureelement/secureelement_instance.cc +++ b/src/secureelement/secureelement_instance.cc @@ -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(user_data); + if (!instance) { + LoggerD("user data is null"); + return; + } + + picojson::value result{picojson::object{}}; + auto& obj = result.get(); + + 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(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(args.find(kHandle)->second.get()); + 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(args.find(kHandle)->second.get()); + + 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(); + + obj.insert(std::make_pair(kHandle, picojson::value(static_cast(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(args.find(kHandle)->second.get()); + + 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(); + 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(args.find(kHandle)->second.get()); + const picojson::array v_aid = args.find(kAid)->second.get(); + + 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(v_aid[i].get()); + } + + 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(); + + obj.insert(std::make_pair(kHandle, picojson::value(static_cast(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(args.find(kHandle)->second.get()); + const picojson::array v_aid = args.find(kAid)->second.get(); + + 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(v_aid[i].get()); + } + + 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(); + + obj.insert(std::make_pair(kHandle, picojson::value(static_cast(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) { diff --git a/src/secureelement/secureelement_instance.h b/src/secureelement/secureelement_instance.h index 21a9bcc0..d4e12952 100644 --- a/src/secureelement/secureelement_instance.h +++ b/src/secureelement/secureelement_instance.h @@ -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