2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 /* standard library header */
24 #include <sys/socket.h>
26 /* SLP library header */
27 #ifdef USER_SPACE_SMACK
28 #include "security-server.h"
32 #include "smartcard-types.h"
34 #include "ByteArray.h"
35 #include "ServerResource.h"
36 #include "GDBusHelper.h"
37 #include "ServerGDBus.h"
41 namespace smartcard_service_api
43 GDBusDispatcher::GDBusDispatcher() : Synchronous()
47 GDBusDispatcher::~GDBusDispatcher()
51 GDBusDispatcher &GDBusDispatcher::getInstance()
53 static GDBusDispatcher dispatcher;
58 void GDBusDispatcher::_push(dispatcher_cb_t cb,
59 const vector<void *> ¶ms)
63 q.push(make_pair(cb, params));
64 _INFO("request pushed, count [%d]", q.size());
68 _INFO("start dispatcher");
69 g_idle_add(&GDBusDispatcher::dispatch, this);
75 void GDBusDispatcher::push(dispatcher_cb_t cb,
76 const vector<void *> ¶ms)
78 GDBusDispatcher::getInstance()._push(cb, params);
81 gboolean GDBusDispatcher::dispatch(gpointer user_data)
83 GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
84 gboolean result = false;
88 dispatcher->syncLock();
90 pair<dispatcher_cb_t, vector<void *> > &job =
91 dispatcher->q.front();
93 dispatcher->syncUnlock();
95 job.first(job.second);
97 dispatcher->syncLock();
100 if (dispatcher->q.size() > 0) {
101 _INFO("remaining messages : %d", dispatcher->q.size());
105 _INFO("dispatch finished");
108 dispatcher->syncUnlock();
115 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
116 seService(NULL), reader(NULL), session(NULL), channel(NULL)
120 ServerGDBus::~ServerGDBus()
125 ServerGDBus &ServerGDBus::getInstance()
127 static ServerGDBus serverGDBus;
132 static void name_owner_changed(GDBusProxy *proxy,
133 const gchar *name, const gchar *old_owner,
134 const gchar *new_owner, void *user_data)
136 if (strlen(new_owner) == 0) {
137 ClientInstance *client;
139 ServerResource &resource = ServerResource::getInstance();
141 client = resource.getClient(old_owner);
142 if (client != NULL) {
143 _INFO("terminated client, pid [%d]", client->getPID());
144 resource.removeClient(old_owner);
151 static void _on_name_owner_changed(GDBusConnection *connection,
152 const gchar *sender_name, const gchar *object_path,
153 const gchar *interface_name, const gchar *signal_name,
154 GVariant *parameters, gpointer user_data)
161 iter = g_variant_iter_new(parameters);
163 g_variant_iter_next(iter, "s", &name);
164 g_variant_iter_next(iter, "s", &old_owner);
165 g_variant_iter_next(iter, "s", &new_owner);
167 name_owner_changed((GDBusProxy *)connection,
168 name, old_owner, new_owner, user_data);
171 bool ServerGDBus::_init()
173 GError *error = NULL;
175 /* init default context */
176 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
177 G_DBUS_PROXY_FLAGS_NONE,
178 NULL, /* GDBusInterfaceInfo */
179 "org.freedesktop.DBus",
180 "/org/freedesktop/DBus",
181 "org.freedesktop.DBus",
182 NULL, /* GCancellable */
184 if (dbus_proxy == NULL)
186 _ERR("Can not create proxy : %s", error->message);
192 /* subscribe signal */
193 g_dbus_connection_signal_subscribe(connection,
194 "org.freedesktop.DBus", /* bus name */
195 "org.freedesktop.DBus", /* interface */
196 "NameOwnerChanged", /* member */
197 "/org/freedesktop/DBus", /* path */
199 G_DBUS_SIGNAL_FLAGS_NONE,
200 _on_name_owner_changed,
206 void ServerGDBus::_deinit()
208 if (dbus_proxy != NULL) {
209 g_object_unref(dbus_proxy);
214 bool ServerGDBus::init()
216 GError *error = NULL;
218 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
219 if (connection != NULL) {
221 _ERR("Can not get connection %s", error->message);
237 void ServerGDBus::deinit()
246 if (connection != NULL) {
247 g_object_unref(connection);
252 static gboolean _call_get_connection_unix_process_id_sync(
253 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
254 GCancellable *cancellable, GError **error) {
257 _ret = g_dbus_proxy_call_sync(proxy,
258 "GetConnectionUnixProcessID",
259 g_variant_new("(s)", arg_name),
260 G_DBUS_CALL_FLAGS_NONE,
261 -1, cancellable, error);
263 g_variant_get(_ret, "(u)", out_pid);
264 g_variant_unref(_ret);
270 pid_t ServerGDBus::getPID(const char *name)
273 GError *error = NULL;
275 if (_call_get_connection_unix_process_id_sync(
276 (GDBusProxy *)dbus_proxy, name,
277 &pid, NULL, &error) == true) {
279 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
286 static bool _is_authorized_request(GDBusMethodInvocation *invocation,
290 #ifdef USER_SPACE_SMACK
293 ClientInstance *instance;
295 name = g_dbus_method_invocation_get_sender(invocation);
297 instance = ServerResource::getInstance().getClient(name);
298 if (instance != NULL) {
299 pid = instance->getPID();
301 pid = ServerGDBus::getInstance().getPID(name);
304 result = (security_server_check_privilege_by_pid(
307 rights) == SECURITY_SERVER_API_SUCCESS);
316 static GVariant *_reader_to_variant(
317 vector<pair<unsigned int, string> > &readers)
319 GVariantBuilder builder;
322 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
324 for (i = 0; i < readers.size(); i++) {
325 g_variant_builder_add(&builder, "(us)",
326 readers[i].first, readers[i].second.c_str());
329 return g_variant_builder_end(&builder);
332 static gboolean __process_se_service(SmartcardServiceSeService *object,
333 GDBusMethodInvocation *invocation,
336 gint result = SCARD_ERROR_OK;
337 GVariant *readers = NULL;
338 vector<pair<unsigned int, string> > list;
339 unsigned int handle = IntegerHandle::INVALID_HANDLE;
343 _INFO("[MSG_REQUEST_READERS]");
345 ServerResource &resource = ServerResource::getInstance();
347 name = g_dbus_method_invocation_get_sender(invocation);
349 /* load secure elements */
350 resource.loadSecureElements();
352 pid = ServerGDBus::getInstance().getPID(name);
354 _DBG("service requested, pid [%d]", pid);
357 ClientInstance *instance;
359 instance = resource.getClient(name);
360 if (instance == NULL) {
361 _INFO("create client instance, pid [%d]", pid);
363 resource.createClient(name, pid);
365 instance = resource.getClient(name);
367 /* generate certification hashes */
368 instance->generateCertificationHashes();
371 if (instance != NULL) {
372 ServiceInstance *service;
375 service = resource.createService(name);
376 if (service != NULL) {
378 handle = service->getHandle();
379 resource.getReaders(list);
381 if (list.size() == 0) {
382 _INFO("no secure elements");
385 _ERR("createService failed");
387 result = SCARD_ERROR_OUT_OF_MEMORY;
390 _ERR("client doesn't exist, pid [%d]", pid);
392 result = SCARD_ERROR_OUT_OF_MEMORY;
395 _ERR("invalid pid, [%d]", pid);
397 result = SCARD_ERROR_IPC_FAILED;
400 readers = _reader_to_variant(list);
402 /* response to client */
403 smartcard_service_se_service_complete_se_service(object,
404 invocation, result, handle, readers);
409 static void _process_se_service(vector<void *> ¶ms)
411 SmartcardServiceSeService *object;
412 GDBusMethodInvocation *invocation;
415 if (params.size() != 3) {
416 _ERR("invalid parameter");
421 object = (SmartcardServiceSeService *)params[0];
422 invocation = (GDBusMethodInvocation *)params[1];
423 user_data = params[2];
425 __process_se_service(object, invocation, user_data);
427 g_object_unref(object);
428 g_object_unref(invocation);
431 static gboolean _handle_se_service(SmartcardServiceSeService *object,
432 GDBusMethodInvocation *invocation,
435 vector<void *> params;
437 /* apply user space smack */
438 if (_is_authorized_request(invocation, "r") == true) {
439 g_object_ref(object);
440 params.push_back((void *)object);
442 g_object_ref(invocation);
443 params.push_back((void *)invocation);
445 params.push_back((void *)user_data);
447 GDBusDispatcher::push(_process_se_service, params);
449 vector<pair<unsigned int, string> > list;
451 _ERR("access denied");
453 /* response to client */
454 smartcard_service_se_service_complete_se_service(object,
456 SCARD_ERROR_SECURITY_NOT_ALLOWED,
457 IntegerHandle::INVALID_HANDLE,
458 _reader_to_variant(list));
464 static gboolean __process_shutdown(SmartcardServiceSeService *object,
465 GDBusMethodInvocation *invocation,
466 guint handle, void *user_data)
470 _INFO("[MSG_REQUEST_SHUTDOWN]");
472 ServerResource &resource = ServerResource::getInstance();
474 name = g_dbus_method_invocation_get_sender(invocation);
476 resource.removeService(name, handle);
478 /* response to client */
479 smartcard_service_se_service_complete_shutdown(object,
480 invocation, SCARD_ERROR_OK);
488 static void _process_shutdown(vector<void *> ¶ms)
490 SmartcardServiceSeService *object;
491 GDBusMethodInvocation *invocation;
495 if (params.size() != 4) {
496 _ERR("invalid parameter");
501 object = (SmartcardServiceSeService *)params[0];
502 invocation = (GDBusMethodInvocation *)params[1];
503 handle = (guint)params[2];
504 user_data = params[3];
506 __process_shutdown(object, invocation, handle, user_data);
508 g_object_unref(object);
509 g_object_unref(invocation);
512 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
513 GDBusMethodInvocation *invocation,
517 vector<void *> params;
519 /* apply user space smack */
520 if (_is_authorized_request(invocation, "r") == true) {
521 g_object_ref(object);
522 params.push_back((void *)object);
524 g_object_ref(invocation);
525 params.push_back((void *)invocation);
527 params.push_back((void *)handle);
528 params.push_back(user_data);
530 GDBusDispatcher::push(_process_shutdown, params);
532 _ERR("access denied");
534 /* response to client */
535 smartcard_service_se_service_complete_shutdown(object,
536 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
542 bool ServerGDBus::initSEService()
544 GError *error = NULL;
546 seService = smartcard_service_se_service_skeleton_new();
548 g_signal_connect(seService,
550 G_CALLBACK(_handle_se_service),
553 g_signal_connect(seService,
555 G_CALLBACK(_handle_shutdown),
558 if (g_dbus_interface_skeleton_export(
559 G_DBUS_INTERFACE_SKELETON(seService),
561 "/org/tizen/SmartcardService/SeService",
564 _ERR("Can not skeleton_export %s", error->message);
567 g_object_unref(seService);
576 void ServerGDBus::deinitSEService()
578 if (seService != NULL) {
579 g_object_unref(seService);
584 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
585 const char *reader_name)
587 smartcard_service_se_service_emit_reader_inserted(
588 SMARTCARD_SERVICE_SE_SERVICE(seService),
589 reader_id, reader_name);
592 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
593 const char *reader_name)
595 smartcard_service_se_service_emit_reader_removed(
596 SMARTCARD_SERVICE_SE_SERVICE(seService),
597 reader_id, reader_name);
604 static gboolean __process_open_session(SmartcardServiceReader *object,
605 GDBusMethodInvocation *invocation, guint service_id,
606 guint reader_id, void *user_data)
608 unsigned int handle = IntegerHandle::INVALID_HANDLE;
612 _INFO("[MSG_REQUEST_OPEN_SESSION]");
614 ServerResource &resource = ServerResource::getInstance();
616 name = g_dbus_method_invocation_get_sender(invocation);
618 if (resource.isValidReaderHandle(reader_id)) {
619 vector<ByteArray> temp;
621 handle = resource.createSession(name,
626 if (handle != IntegerHandle::INVALID_HANDLE) {
627 result = SCARD_ERROR_OK;
629 _ERR("createSession failed [%d]", handle);
631 result = SCARD_ERROR_OUT_OF_MEMORY;
634 _ERR("request invalid reader handle [%d]", reader_id);
636 result = SCARD_ERROR_ILLEGAL_PARAM;
639 /* response to client */
640 smartcard_service_reader_complete_open_session(object,
641 invocation, result, handle);
646 static void _process_open_session(vector<void *> ¶ms)
648 SmartcardServiceReader *object;
649 GDBusMethodInvocation *invocation;
654 if (params.size() != 5) {
655 _ERR("invalid parameter");
660 object = (SmartcardServiceReader *)params[0];
661 invocation = (GDBusMethodInvocation *)params[1];
662 service_id = (guint)params[2];
663 reader_id = (guint)params[3];
664 user_data = params[4];
666 __process_open_session(object, invocation, service_id,
667 reader_id, user_data);
669 g_object_unref(object);
670 g_object_unref(invocation);
673 static gboolean _handle_open_session(SmartcardServiceReader *object,
674 GDBusMethodInvocation *invocation,
676 guint reader_id, void *user_data)
678 vector<void *> params;
680 /* apply user space smack */
681 if (_is_authorized_request(invocation, "r") == true) {
682 g_object_ref(object);
683 params.push_back((void *)object);
685 g_object_ref(invocation);
686 params.push_back((void *)invocation);
688 params.push_back((void *)service_id);
689 params.push_back((void *)reader_id);
690 params.push_back(user_data);
692 GDBusDispatcher::push(_process_open_session, params);
694 _ERR("access denied");
696 /* response to client */
697 smartcard_service_reader_complete_open_session(object,
699 SCARD_ERROR_SECURITY_NOT_ALLOWED,
700 IntegerHandle::INVALID_HANDLE);
706 bool ServerGDBus::initReader()
708 GError *error = NULL;
710 reader = smartcard_service_reader_skeleton_new();
712 g_signal_connect(reader,
713 "handle-open-session",
714 G_CALLBACK(_handle_open_session),
717 if (g_dbus_interface_skeleton_export(
718 G_DBUS_INTERFACE_SKELETON(reader),
720 "/org/tizen/SmartcardService/Reader",
723 _ERR("Can not skeleton_export %s", error->message);
726 g_object_unref(reader);
735 void ServerGDBus::deinitReader()
737 if (reader != NULL) {
738 g_object_unref(reader);
747 static gboolean __process_close_session(SmartcardServiceSession *object,
748 GDBusMethodInvocation *invocation, guint service_id,
749 guint session_id, void *user_data)
753 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
755 ServerResource &resource = ServerResource::getInstance();
757 name = g_dbus_method_invocation_get_sender(invocation);
759 if (resource.isValidSessionHandle(name, service_id,
761 resource.removeSession(name, service_id,
764 _ERR("invalid parameters");
767 /* response to client */
768 smartcard_service_session_complete_close_session(object,
769 invocation, SCARD_ERROR_OK);
774 static void _process_close_session(vector<void *> ¶ms)
776 SmartcardServiceSession *object;
777 GDBusMethodInvocation *invocation;
782 if (params.size() != 5) {
783 _ERR("invalid parameter");
788 object = (SmartcardServiceSession *)params[0];
789 invocation = (GDBusMethodInvocation *)params[1];
790 service_id = (guint)params[2];
791 session_id = (guint)params[3];
792 user_data = params[4];
794 __process_close_session(object, invocation, service_id,
795 session_id, user_data);
797 g_object_unref(object);
798 g_object_unref(invocation);
801 static gboolean _handle_close_session(SmartcardServiceSession *object,
802 GDBusMethodInvocation *invocation,
804 guint session_id, void *user_data)
806 vector<void *> params;
808 /* apply user space smack */
809 if (_is_authorized_request(invocation, "r") == true) {
810 g_object_ref(object);
811 params.push_back((void *)object);
813 g_object_ref(invocation);
814 params.push_back((void *)invocation);
816 params.push_back((void *)service_id);
817 params.push_back((void *)session_id);
818 params.push_back(user_data);
820 GDBusDispatcher::push(_process_close_session, params);
822 _ERR("access denied");
824 /* response to client */
825 smartcard_service_session_complete_close_session(object,
826 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
832 static gboolean __process_get_atr(SmartcardServiceSession *object,
833 GDBusMethodInvocation *invocation, guint service_id,
834 guint session_id, void *user_data)
838 GVariant *atr = NULL;
840 ServiceInstance *client = NULL;
842 _INFO("[MSG_REQUEST_GET_ATR]");
844 ServerResource &resource = ServerResource::getInstance();
846 name = g_dbus_method_invocation_get_sender(invocation);
848 client = resource.getService(name, service_id);
849 if (client != NULL) {
852 terminal = client->getTerminal(session_id);
853 if (terminal != NULL) {
856 if ((rv = terminal->getATRSync(resp)) == 0) {
857 result = SCARD_ERROR_OK;
859 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
864 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
866 result = SCARD_ERROR_UNAVAILABLE;
869 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
871 result = SCARD_ERROR_UNAVAILABLE;
874 atr = GDBusHelper::convertByteArrayToVariant(resp);
876 /* response to client */
877 smartcard_service_session_complete_get_atr(object, invocation,
883 static void _process_get_atr(vector<void *> ¶ms)
885 SmartcardServiceSession *object;
886 GDBusMethodInvocation *invocation;
891 if (params.size() != 5) {
892 _ERR("invalid parameter");
897 object = (SmartcardServiceSession *)params[0];
898 invocation = (GDBusMethodInvocation *)params[1];
899 service_id = (guint)params[2];
900 session_id = (guint)params[3];
901 user_data = params[4];
903 __process_get_atr(object, invocation, service_id,
904 session_id, user_data);
906 g_object_unref(object);
907 g_object_unref(invocation);
910 static gboolean _handle_get_atr(SmartcardServiceSession *object,
911 GDBusMethodInvocation *invocation,
913 guint session_id, void *user_data)
915 vector<void *> params;
917 /* apply user space smack */
918 if (_is_authorized_request(invocation, "r") == true) {
919 g_object_ref(object);
920 params.push_back((void *)object);
922 g_object_ref(invocation);
923 params.push_back((void *)invocation);
925 params.push_back((void *)service_id);
926 params.push_back((void *)session_id);
927 params.push_back(user_data);
929 GDBusDispatcher::push(_process_get_atr, params);
933 _ERR("access denied");
935 /* response to client */
936 smartcard_service_session_complete_get_atr(
939 SCARD_ERROR_SECURITY_NOT_ALLOWED,
940 GDBusHelper::convertByteArrayToVariant(resp));
946 static gboolean __process_open_channel(SmartcardServiceSession *object,
947 GDBusMethodInvocation *invocation, guint service_id,
948 guint session_id, guint type, GVariant *aid, void *user_data)
950 int result = SCARD_ERROR_UNKNOWN;
952 GVariant *response = NULL;
953 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
956 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
958 ServerResource &resource = ServerResource::getInstance();
960 name = g_dbus_method_invocation_get_sender(invocation);
966 GDBusHelper::convertVariantToByteArray(aid,
969 channelID = resource.createChannel(name,
970 service_id, session_id, type, tempAid);
971 if (channelID != IntegerHandle::INVALID_HANDLE) {
974 temp = (ServerChannel *)resource.getChannel(
975 name, service_id, channelID);
977 resp = temp->getSelectResponse();
979 result = SCARD_ERROR_OK;
982 _ERR("channel is null.");
984 /* set error value */
985 result = SCARD_ERROR_UNAVAILABLE;
988 catch (ExceptionBase &e)
990 result = e.getErrorCode();
993 response = GDBusHelper::convertByteArrayToVariant(resp);
995 /* response to client */
996 smartcard_service_session_complete_open_channel(object,
997 invocation, result, channelID, response);
1002 static void _process_open_channel(vector<void *> ¶ms)
1004 SmartcardServiceSession *object;
1005 GDBusMethodInvocation *invocation;
1012 if (params.size() != 7) {
1013 _ERR("invalid parameter");
1018 object = (SmartcardServiceSession *)params[0];
1019 invocation = (GDBusMethodInvocation *)params[1];
1020 service_id = (guint)params[2];
1021 session_id = (guint)params[3];
1022 type = (guint)params[4];
1023 aid = (GVariant *)params[5];
1024 user_data = params[6];
1026 __process_open_channel(object, invocation, service_id,
1027 session_id, type, aid, user_data);
1029 g_object_unref(object);
1030 g_object_unref(invocation);
1031 g_object_unref(aid);
1034 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1035 GDBusMethodInvocation *invocation,
1037 guint session_id, guint type, GVariant *aid, void *user_data)
1039 vector<void *> params;
1041 /* apply user space smack */
1042 if (_is_authorized_request(invocation, "rw") == true) {
1043 g_object_ref(object);
1044 params.push_back((void *)object);
1046 g_object_ref(invocation);
1047 params.push_back((void *)invocation);
1049 params.push_back((void *)service_id);
1050 params.push_back((void *)session_id);
1051 params.push_back((void *)type);
1054 params.push_back((void *)aid);
1055 params.push_back(user_data);
1057 GDBusDispatcher::push(_process_open_channel, params);
1061 _ERR("access denied");
1063 /* response to client */
1064 smartcard_service_session_complete_open_channel(object,
1066 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1067 IntegerHandle::INVALID_HANDLE,
1068 GDBusHelper::convertByteArrayToVariant(resp));
1074 bool ServerGDBus::initSession()
1076 GError *error = NULL;
1078 session = smartcard_service_session_skeleton_new();
1080 g_signal_connect(session,
1081 "handle-close-session",
1082 G_CALLBACK(_handle_close_session),
1085 g_signal_connect(session,
1087 G_CALLBACK(_handle_get_atr),
1090 g_signal_connect(session,
1091 "handle-open-channel",
1092 G_CALLBACK(_handle_open_channel),
1095 if (g_dbus_interface_skeleton_export(
1096 G_DBUS_INTERFACE_SKELETON(session),
1098 "/org/tizen/SmartcardService/Session",
1101 _ERR("Can not skeleton_export %s", error->message);
1103 g_error_free(error);
1104 g_object_unref(session);
1113 void ServerGDBus::deinitSession()
1115 if (session != NULL) {
1116 g_object_unref(session);
1125 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1126 GDBusMethodInvocation *invocation, guint service_id,
1127 guint channel_id, void *user_data)
1132 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1134 ServerResource &resource = ServerResource::getInstance();
1136 name = g_dbus_method_invocation_get_sender(invocation);
1138 resource.removeChannel(name, service_id, channel_id);
1140 result = SCARD_ERROR_OK;
1142 /* response to client */
1143 smartcard_service_channel_complete_close_channel(object,
1144 invocation, result);
1149 static void _process_close_channel(vector<void *> ¶ms)
1151 SmartcardServiceChannel *object;
1152 GDBusMethodInvocation *invocation;
1157 if (params.size() != 5) {
1158 _ERR("invalid parameter");
1163 object = (SmartcardServiceChannel *)params[0];
1164 invocation = (GDBusMethodInvocation *)params[1];
1165 service_id = (guint)params[2];
1166 channel_id = (guint)params[3];
1167 user_data = params[4];
1169 __process_close_channel(object, invocation, service_id,
1170 channel_id, user_data);
1172 g_object_unref(object);
1173 g_object_unref(invocation);
1176 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1177 GDBusMethodInvocation *invocation,
1178 guint service_id, guint channel_id, void *user_data)
1180 vector<void *> params;
1182 /* apply user space smack */
1183 if (_is_authorized_request(invocation, "r") == true) {
1184 g_object_ref(object);
1185 params.push_back((void *)object);
1187 g_object_ref(invocation);
1188 params.push_back((void *)invocation);
1190 params.push_back((void *)service_id);
1191 params.push_back((void *)channel_id);
1192 params.push_back(user_data);
1194 GDBusDispatcher::push(_process_close_channel, params);
1196 _ERR("access denied");
1198 /* response to client */
1199 smartcard_service_channel_complete_close_channel(
1202 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1208 static gboolean __process_transmit(SmartcardServiceChannel *object,
1209 GDBusMethodInvocation *invocation,
1216 Channel *channel = NULL;
1218 GVariant *response = NULL;
1221 _INFO("[MSG_REQUEST_TRANSMIT]");
1223 ServerResource &resource = ServerResource::getInstance();
1225 name = g_dbus_method_invocation_get_sender(invocation);
1227 channel = resource.getChannel(name, service_id, channel_id);
1228 if (channel != NULL) {
1232 GDBusHelper::convertVariantToByteArray(command, cmd);
1234 rv = channel->transmitSync(cmd, resp);
1236 result = SCARD_ERROR_OK;
1238 _ERR("transmit failed [%d]", rv);
1243 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1245 result = SCARD_ERROR_UNAVAILABLE;
1248 response = GDBusHelper::convertByteArrayToVariant(resp);
1250 /* response to client */
1251 smartcard_service_channel_complete_transmit(object, invocation,
1257 static void _process_transmit(vector<void *> ¶ms)
1259 SmartcardServiceChannel *object;
1260 GDBusMethodInvocation *invocation;
1266 if (params.size() != 6) {
1267 _ERR("invalid parameter");
1272 object = (SmartcardServiceChannel *)params[0];
1273 invocation = (GDBusMethodInvocation *)params[1];
1274 service_id = (guint)params[2];
1275 channel_id = (guint)params[3];
1276 command = (GVariant *)params[4];
1277 user_data = params[5];
1279 __process_transmit(object, invocation, service_id,
1280 channel_id, command, user_data);
1282 g_object_unref(object);
1283 g_object_unref(invocation);
1284 g_object_unref(command);
1287 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1288 GDBusMethodInvocation *invocation,
1294 vector<void *> params;
1296 /* apply user space smack */
1297 if (_is_authorized_request(invocation, "r") == true) {
1298 /* enqueue message */
1299 g_object_ref(object);
1300 params.push_back((void *)object);
1302 g_object_ref(invocation);
1303 params.push_back((void *)invocation);
1305 params.push_back((void *)service_id);
1306 params.push_back((void *)channel_id);
1308 g_object_ref(command);
1309 params.push_back((void *)command);
1311 params.push_back(user_data);
1313 GDBusDispatcher::push(_process_transmit, params);
1317 _ERR("access denied");
1319 /* response to client */
1320 smartcard_service_channel_complete_transmit(object,
1322 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1323 GDBusHelper::convertByteArrayToVariant(resp));
1329 bool ServerGDBus::initChannel()
1331 GError *error = NULL;
1333 channel = smartcard_service_channel_skeleton_new();
1335 g_signal_connect(channel,
1336 "handle-close-channel",
1337 G_CALLBACK(_handle_close_channel),
1340 g_signal_connect(channel,
1342 G_CALLBACK(_handle_transmit),
1345 if (g_dbus_interface_skeleton_export(
1346 G_DBUS_INTERFACE_SKELETON(channel),
1348 "/org/tizen/SmartcardService/Channel",
1351 _ERR("Can not skeleton_export %s", error->message);
1353 g_error_free(error);
1354 g_object_unref(channel);
1363 void ServerGDBus::deinitChannel()
1365 if (channel != NULL) {
1366 g_object_unref(channel);
1370 } /* namespace smartcard_service_api */