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) {
}
}
+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;
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
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) {
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) {
return TizenSuccess();
}
+TizenResult SecureElementInstance::Shutdown(picojson::object const& args) {
+ ScopeLogger();
+
+ UnregisterListener();
+ return Deinitialize();
+}
+
// Reader methods
TizenResult SecureElementInstance::GetName(picojson::object const& args) {
ScopeLogger();
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) {
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) {
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) {
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) {