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.
22 #include <sys/socket.h>
24 #ifdef USER_SPACE_SMACK
25 #include "security-server.h"
28 #include "smartcard-types.h"
30 #include "ByteArray.h"
31 #include "ServerResource.h"
32 #include "GDBusHelper.h"
33 #include "ServerGDBus.h"
37 namespace smartcard_service_api
39 GDBusDispatcher::GDBusDispatcher() : Synchronous()
43 GDBusDispatcher::~GDBusDispatcher()
47 GDBusDispatcher &GDBusDispatcher::getInstance()
49 static GDBusDispatcher dispatcher;
54 void GDBusDispatcher::_push(dispatcher_cb_t cb,
55 const vector<void *> ¶ms)
59 q.push(make_pair(cb, params));
60 _INFO("request pushed, count [%d]", q.size());
64 _INFO("start dispatcher");
65 g_idle_add(&GDBusDispatcher::dispatch, this);
71 void GDBusDispatcher::push(dispatcher_cb_t cb,
72 const vector<void *> ¶ms)
74 GDBusDispatcher::getInstance()._push(cb, params);
77 gboolean GDBusDispatcher::dispatch(gpointer user_data)
79 GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
80 gboolean result = false;
84 dispatcher->syncLock();
86 pair<dispatcher_cb_t, vector<void *> > &job =
87 dispatcher->q.front();
89 dispatcher->syncUnlock();
91 job.first(job.second);
93 dispatcher->syncLock();
96 if (dispatcher->q.size() > 0) {
97 _INFO("remaining messages : %d", dispatcher->q.size());
101 _INFO("dispatch finished");
104 dispatcher->syncUnlock();
111 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
112 seService(NULL), reader(NULL), session(NULL), channel(NULL)
116 ServerGDBus::~ServerGDBus()
121 ServerGDBus &ServerGDBus::getInstance()
123 static ServerGDBus serverGDBus;
128 static void name_owner_changed(GDBusProxy *proxy,
129 const gchar *name, const gchar *old_owner,
130 const gchar *new_owner, void *user_data)
132 if (name == NULL || old_owner == NULL || new_owner == NULL) {
133 _ERR("invalid parameter");
137 if (strlen(new_owner) == 0) {
138 ClientInstance *client;
140 ServerResource &resource = ServerResource::getInstance();
142 client = resource.getClient(old_owner);
143 if (client != NULL) {
144 _INFO("terminated client, pid [%d]", client->getPID());
145 resource.removeClient(old_owner);
152 static void _on_name_owner_changed(GDBusConnection *connection,
153 const gchar *sender_name, const gchar *object_path,
154 const gchar *interface_name, const gchar *signal_name,
155 GVariant *parameters, gpointer user_data)
161 g_variant_get(parameters,
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);
366 if (instance != NULL) {
367 /* generate certification hashes */
368 instance->generateCertificationHashes();
370 _ERR("createClient failed");
374 if (instance != NULL) {
375 ServiceInstance *service;
378 service = resource.createService(name);
379 if (service != NULL) {
381 handle = service->getHandle();
382 resource.getReaders(list);
384 if (list.size() == 0) {
385 _INFO("no secure elements");
388 _ERR("createService failed");
390 result = SCARD_ERROR_OUT_OF_MEMORY;
393 _ERR("client doesn't exist, pid [%d]", pid);
395 result = SCARD_ERROR_OUT_OF_MEMORY;
398 _ERR("invalid pid, [%d]", pid);
400 result = SCARD_ERROR_IPC_FAILED;
403 readers = _reader_to_variant(list);
405 /* response to client */
406 smartcard_service_se_service_complete_se_service(object,
407 invocation, result, handle, readers);
412 static void _process_se_service(vector<void *> ¶ms)
414 SmartcardServiceSeService *object;
415 GDBusMethodInvocation *invocation;
418 if (params.size() != 3) {
419 _ERR("invalid parameter");
424 object = (SmartcardServiceSeService *)params[0];
425 invocation = (GDBusMethodInvocation *)params[1];
426 user_data = params[2];
428 __process_se_service(object, invocation, user_data);
430 g_object_unref(object);
431 g_object_unref(invocation);
434 static gboolean _handle_se_service(SmartcardServiceSeService *object,
435 GDBusMethodInvocation *invocation,
438 vector<void *> params;
440 /* apply user space smack */
441 if (_is_authorized_request(invocation, "r") == true) {
442 g_object_ref(object);
443 params.push_back((void *)object);
445 g_object_ref(invocation);
446 params.push_back((void *)invocation);
448 params.push_back((void *)user_data);
450 GDBusDispatcher::push(_process_se_service, params);
452 vector<pair<unsigned int, string> > list;
454 _ERR("access denied");
456 /* response to client */
457 smartcard_service_se_service_complete_se_service(object,
459 SCARD_ERROR_SECURITY_NOT_ALLOWED,
460 IntegerHandle::INVALID_HANDLE,
461 _reader_to_variant(list));
467 static gboolean __process_shutdown(SmartcardServiceSeService *object,
468 GDBusMethodInvocation *invocation,
469 intptr_t handle, void *user_data)
473 _INFO("[MSG_REQUEST_SHUTDOWN]");
475 ServerResource &resource = ServerResource::getInstance();
477 name = g_dbus_method_invocation_get_sender(invocation);
479 resource.removeService(name, handle);
481 /* response to client */
482 smartcard_service_se_service_complete_shutdown(object,
483 invocation, SCARD_ERROR_OK);
491 static void _process_shutdown(vector<void *> ¶ms)
493 SmartcardServiceSeService *object;
494 GDBusMethodInvocation *invocation;
498 if (params.size() != 4) {
499 _ERR("invalid parameter");
504 object = (SmartcardServiceSeService *)params[0];
505 invocation = (GDBusMethodInvocation *)params[1];
506 handle = (intptr_t)params[2];
507 user_data = params[3];
509 __process_shutdown(object, invocation, handle, user_data);
511 g_object_unref(object);
512 g_object_unref(invocation);
515 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
516 GDBusMethodInvocation *invocation,
520 vector<void *> params;
522 /* apply user space smack */
523 if (_is_authorized_request(invocation, "r") == true) {
524 g_object_ref(object);
525 params.push_back((void *)object);
527 g_object_ref(invocation);
528 params.push_back((void *)invocation);
530 params.push_back((void *)handle);
531 params.push_back(user_data);
533 GDBusDispatcher::push(_process_shutdown, params);
535 _ERR("access denied");
537 /* response to client */
538 smartcard_service_se_service_complete_shutdown(object,
539 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
545 bool ServerGDBus::initSEService()
547 GError *error = NULL;
549 seService = smartcard_service_se_service_skeleton_new();
551 g_signal_connect(seService,
553 G_CALLBACK(_handle_se_service),
556 g_signal_connect(seService,
558 G_CALLBACK(_handle_shutdown),
561 if (g_dbus_interface_skeleton_export(
562 G_DBUS_INTERFACE_SKELETON(seService),
564 "/org/tizen/SmartcardService/SeService",
567 _ERR("Can not skeleton_export %s", error->message);
570 g_object_unref(seService);
579 void ServerGDBus::deinitSEService()
581 if (seService != NULL) {
582 g_object_unref(seService);
587 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
588 const char *reader_name)
590 smartcard_service_se_service_emit_reader_inserted(
591 SMARTCARD_SERVICE_SE_SERVICE(seService),
592 reader_id, reader_name);
595 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
596 const char *reader_name)
598 smartcard_service_se_service_emit_reader_removed(
599 SMARTCARD_SERVICE_SE_SERVICE(seService),
600 reader_id, reader_name);
607 static gboolean __process_open_session(SmartcardServiceReader *object,
608 GDBusMethodInvocation *invocation, intptr_t service_id,
609 intptr_t reader_id, void *user_data)
611 unsigned int handle = IntegerHandle::INVALID_HANDLE;
615 _INFO("[MSG_REQUEST_OPEN_SESSION]");
617 ServerResource &resource = ServerResource::getInstance();
619 name = g_dbus_method_invocation_get_sender(invocation);
621 if (resource.isValidReaderHandle(reader_id)) {
622 vector<ByteArray> temp;
624 handle = resource.createSession(name,
629 if (handle != IntegerHandle::INVALID_HANDLE) {
630 result = SCARD_ERROR_OK;
632 _ERR("createSession failed [%d]", handle);
634 result = SCARD_ERROR_OUT_OF_MEMORY;
637 _ERR("request invalid reader handle [%d]", reader_id);
639 result = SCARD_ERROR_ILLEGAL_PARAM;
642 /* response to client */
643 smartcard_service_reader_complete_open_session(object,
644 invocation, result, handle);
649 static void _process_open_session(vector<void *> ¶ms)
651 SmartcardServiceReader *object;
652 GDBusMethodInvocation *invocation;
657 if (params.size() != 5) {
658 _ERR("invalid parameter");
663 object = (SmartcardServiceReader *)params[0];
664 invocation = (GDBusMethodInvocation *)params[1];
665 service_id = (intptr_t)params[2];
666 reader_id = (intptr_t)params[3];
667 user_data = params[4];
669 __process_open_session(object, invocation, service_id,
670 reader_id, user_data);
672 g_object_unref(object);
673 g_object_unref(invocation);
676 static gboolean _handle_open_session(SmartcardServiceReader *object,
677 GDBusMethodInvocation *invocation,
679 intptr_t reader_id, void *user_data)
681 vector<void *> params;
683 /* apply user space smack */
684 if (_is_authorized_request(invocation, "r") == true) {
685 g_object_ref(object);
686 params.push_back((void *)object);
688 g_object_ref(invocation);
689 params.push_back((void *)invocation);
691 params.push_back((void *)service_id);
692 params.push_back((void *)reader_id);
693 params.push_back(user_data);
695 GDBusDispatcher::push(_process_open_session, params);
697 _ERR("access denied");
699 /* response to client */
700 smartcard_service_reader_complete_open_session(object,
702 SCARD_ERROR_SECURITY_NOT_ALLOWED,
703 IntegerHandle::INVALID_HANDLE);
709 bool ServerGDBus::initReader()
711 GError *error = NULL;
713 reader = smartcard_service_reader_skeleton_new();
715 g_signal_connect(reader,
716 "handle-open-session",
717 G_CALLBACK(_handle_open_session),
720 if (g_dbus_interface_skeleton_export(
721 G_DBUS_INTERFACE_SKELETON(reader),
723 "/org/tizen/SmartcardService/Reader",
726 _ERR("Can not skeleton_export %s", error->message);
729 g_object_unref(reader);
738 void ServerGDBus::deinitReader()
740 if (reader != NULL) {
741 g_object_unref(reader);
750 static gboolean __process_close_session(SmartcardServiceSession *object,
751 GDBusMethodInvocation *invocation, intptr_t service_id,
752 intptr_t session_id, void *user_data)
756 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
758 ServerResource &resource = ServerResource::getInstance();
760 name = g_dbus_method_invocation_get_sender(invocation);
762 if (resource.isValidSessionHandle(name, service_id,
764 resource.removeSession(name, service_id,
767 _ERR("invalid parameters");
770 /* response to client */
771 smartcard_service_session_complete_close_session(object,
772 invocation, SCARD_ERROR_OK);
777 static void _process_close_session(vector<void *> ¶ms)
779 SmartcardServiceSession *object;
780 GDBusMethodInvocation *invocation;
785 if (params.size() != 5) {
786 _ERR("invalid parameter");
791 object = (SmartcardServiceSession *)params[0];
792 invocation = (GDBusMethodInvocation *)params[1];
793 service_id = (intptr_t)params[2];
794 session_id = (intptr_t)params[3];
795 user_data = params[4];
797 __process_close_session(object, invocation, service_id,
798 session_id, user_data);
800 g_object_unref(object);
801 g_object_unref(invocation);
804 static gboolean _handle_close_session(SmartcardServiceSession *object,
805 GDBusMethodInvocation *invocation,
807 intptr_t session_id, void *user_data)
809 vector<void *> params;
811 /* apply user space smack */
812 if (_is_authorized_request(invocation, "r") == true) {
813 g_object_ref(object);
814 params.push_back((void *)object);
816 g_object_ref(invocation);
817 params.push_back((void *)invocation);
819 params.push_back((void *)service_id);
820 params.push_back((void *)session_id);
821 params.push_back(user_data);
823 GDBusDispatcher::push(_process_close_session, params);
825 _ERR("access denied");
827 /* response to client */
828 smartcard_service_session_complete_close_session(object,
829 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
835 static gboolean __process_get_atr(SmartcardServiceSession *object,
836 GDBusMethodInvocation *invocation, intptr_t service_id,
837 intptr_t session_id, void *user_data)
841 GVariant *atr = NULL;
843 ServiceInstance *client = NULL;
845 _INFO("[MSG_REQUEST_GET_ATR]");
847 ServerResource &resource = ServerResource::getInstance();
849 name = g_dbus_method_invocation_get_sender(invocation);
851 client = resource.getService(name, service_id);
852 if (client != NULL) {
855 terminal = client->getTerminal(session_id);
856 if (terminal != NULL) {
859 if (terminal->open() == true) {
860 rv = terminal->getATRSync(resp);
861 if (rv < SCARD_ERROR_OK) {
862 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
869 _ERR("terminal->open failed");
871 result = SCARD_ERROR_UNAVAILABLE;
874 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
876 result = SCARD_ERROR_UNAVAILABLE;
879 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
881 result = SCARD_ERROR_UNAVAILABLE;
884 atr = GDBusHelper::convertByteArrayToVariant(resp);
886 /* response to client */
887 smartcard_service_session_complete_get_atr(object, invocation,
893 static void _process_get_atr(vector<void *> ¶ms)
895 SmartcardServiceSession *object;
896 GDBusMethodInvocation *invocation;
901 if (params.size() != 5) {
902 _ERR("invalid parameter");
907 object = (SmartcardServiceSession *)params[0];
908 invocation = (GDBusMethodInvocation *)params[1];
909 service_id = (intptr_t)params[2];
910 session_id = (intptr_t)params[3];
911 user_data = params[4];
913 __process_get_atr(object, invocation, service_id,
914 session_id, user_data);
916 g_object_unref(object);
917 g_object_unref(invocation);
920 static gboolean _handle_get_atr(SmartcardServiceSession *object,
921 GDBusMethodInvocation *invocation,
923 intptr_t session_id, void *user_data)
925 vector<void *> params;
927 /* apply user space smack */
928 if (_is_authorized_request(invocation, "r") == true) {
929 g_object_ref(object);
930 params.push_back((void *)object);
932 g_object_ref(invocation);
933 params.push_back((void *)invocation);
935 params.push_back((void *)service_id);
936 params.push_back((void *)session_id);
937 params.push_back(user_data);
939 GDBusDispatcher::push(_process_get_atr, params);
943 _ERR("access denied");
945 /* response to client */
946 smartcard_service_session_complete_get_atr(
949 SCARD_ERROR_SECURITY_NOT_ALLOWED,
950 GDBusHelper::convertByteArrayToVariant(resp));
956 static gboolean __process_open_channel(SmartcardServiceSession *object,
957 GDBusMethodInvocation *invocation, intptr_t service_id,
958 intptr_t session_id, intptr_t type, GVariant *aid, void *user_data)
960 int result = SCARD_ERROR_UNKNOWN;
962 GVariant *response = NULL;
963 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
966 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
968 ServerResource &resource = ServerResource::getInstance();
970 name = g_dbus_method_invocation_get_sender(invocation);
976 GDBusHelper::convertVariantToByteArray(aid,
979 channelID = resource.createChannel(name,
980 service_id, session_id, type, tempAid);
981 if (channelID != IntegerHandle::INVALID_HANDLE) {
984 temp = (ServerChannel *)resource.getChannel(
985 name, service_id, channelID);
987 resp = temp->getSelectResponse();
989 result = SCARD_ERROR_OK;
992 _ERR("channel is null.");
994 /* set error value */
995 result = SCARD_ERROR_UNAVAILABLE;
998 catch (ExceptionBase &e)
1000 result = e.getErrorCode();
1003 response = GDBusHelper::convertByteArrayToVariant(resp);
1005 /* response to client */
1006 smartcard_service_session_complete_open_channel(object,
1007 invocation, result, channelID, response);
1012 static void _process_open_channel(vector<void *> ¶ms)
1014 SmartcardServiceSession *object;
1015 GDBusMethodInvocation *invocation;
1016 intptr_t service_id;
1017 intptr_t session_id;
1022 if (params.size() != 7) {
1023 _ERR("invalid parameter");
1028 object = (SmartcardServiceSession *)params[0];
1029 invocation = (GDBusMethodInvocation *)params[1];
1030 service_id = (intptr_t)params[2];
1031 session_id = (intptr_t)params[3];
1032 type = (intptr_t)params[4];
1033 aid = (GVariant *)params[5];
1034 user_data = params[6];
1036 __process_open_channel(object, invocation, service_id,
1037 session_id, type, aid, user_data);
1039 g_object_unref(object);
1040 g_object_unref(invocation);
1041 g_object_unref(aid);
1044 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1045 GDBusMethodInvocation *invocation,
1046 intptr_t service_id,
1047 intptr_t session_id, intptr_t type, GVariant *aid, void *user_data)
1049 vector<void *> params;
1051 /* apply user space smack */
1052 if (_is_authorized_request(invocation, "rw") == true) {
1053 g_object_ref(object);
1054 params.push_back((void *)object);
1056 g_object_ref(invocation);
1057 params.push_back((void *)invocation);
1059 params.push_back((void *)service_id);
1060 params.push_back((void *)session_id);
1061 params.push_back((void *)type);
1064 params.push_back((void *)aid);
1065 params.push_back(user_data);
1067 GDBusDispatcher::push(_process_open_channel, params);
1071 _ERR("access denied");
1073 /* response to client */
1074 smartcard_service_session_complete_open_channel(object,
1076 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1077 IntegerHandle::INVALID_HANDLE,
1078 GDBusHelper::convertByteArrayToVariant(resp));
1084 bool ServerGDBus::initSession()
1086 GError *error = NULL;
1088 session = smartcard_service_session_skeleton_new();
1090 g_signal_connect(session,
1091 "handle-close-session",
1092 G_CALLBACK(_handle_close_session),
1095 g_signal_connect(session,
1097 G_CALLBACK(_handle_get_atr),
1100 g_signal_connect(session,
1101 "handle-open-channel",
1102 G_CALLBACK(_handle_open_channel),
1105 if (g_dbus_interface_skeleton_export(
1106 G_DBUS_INTERFACE_SKELETON(session),
1108 "/org/tizen/SmartcardService/Session",
1111 _ERR("Can not skeleton_export %s", error->message);
1113 g_error_free(error);
1114 g_object_unref(session);
1123 void ServerGDBus::deinitSession()
1125 if (session != NULL) {
1126 g_object_unref(session);
1135 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1136 GDBusMethodInvocation *invocation, intptr_t service_id,
1137 intptr_t channel_id, void *user_data)
1142 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1144 ServerResource &resource = ServerResource::getInstance();
1146 name = g_dbus_method_invocation_get_sender(invocation);
1148 resource.removeChannel(name, service_id, channel_id);
1150 result = SCARD_ERROR_OK;
1152 /* response to client */
1153 smartcard_service_channel_complete_close_channel(object,
1154 invocation, result);
1159 static void _process_close_channel(vector<void *> ¶ms)
1161 SmartcardServiceChannel *object;
1162 GDBusMethodInvocation *invocation;
1163 intptr_t service_id;
1164 intptr_t channel_id;
1167 if (params.size() != 5) {
1168 _ERR("invalid parameter");
1173 object = (SmartcardServiceChannel *)params[0];
1174 invocation = (GDBusMethodInvocation *)params[1];
1175 service_id = (intptr_t)params[2];
1176 channel_id = (intptr_t)params[3];
1177 user_data = params[4];
1179 __process_close_channel(object, invocation, service_id,
1180 channel_id, user_data);
1182 g_object_unref(object);
1183 g_object_unref(invocation);
1186 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1187 GDBusMethodInvocation *invocation,
1188 intptr_t service_id, intptr_t channel_id, void *user_data)
1190 vector<void *> params;
1192 /* apply user space smack */
1193 if (_is_authorized_request(invocation, "r") == true) {
1194 g_object_ref(object);
1195 params.push_back((void *)object);
1197 g_object_ref(invocation);
1198 params.push_back((void *)invocation);
1200 params.push_back((void *)service_id);
1201 params.push_back((void *)channel_id);
1202 params.push_back(user_data);
1204 GDBusDispatcher::push(_process_close_channel, params);
1206 _ERR("access denied");
1208 /* response to client */
1209 smartcard_service_channel_complete_close_channel(
1212 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1218 static gboolean __process_transmit(SmartcardServiceChannel *object,
1219 GDBusMethodInvocation *invocation,
1220 intptr_t service_id,
1221 intptr_t channel_id,
1226 Channel *channel = NULL;
1228 GVariant *response = NULL;
1231 _INFO("[MSG_REQUEST_TRANSMIT]");
1233 ServerResource &resource = ServerResource::getInstance();
1235 name = g_dbus_method_invocation_get_sender(invocation);
1237 channel = resource.getChannel(name, service_id, channel_id);
1238 if (channel != NULL) {
1242 GDBusHelper::convertVariantToByteArray(command, cmd);
1244 rv = channel->transmitSync(cmd, resp);
1246 result = SCARD_ERROR_OK;
1248 _ERR("transmit failed [%d]", rv);
1253 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1255 result = SCARD_ERROR_UNAVAILABLE;
1258 response = GDBusHelper::convertByteArrayToVariant(resp);
1260 /* response to client */
1261 smartcard_service_channel_complete_transmit(object, invocation,
1267 static void _process_transmit(vector<void *> ¶ms)
1269 SmartcardServiceChannel *object;
1270 GDBusMethodInvocation *invocation;
1271 intptr_t service_id;
1272 intptr_t channel_id;
1276 if (params.size() != 6) {
1277 _ERR("invalid parameter");
1282 object = (SmartcardServiceChannel *)params[0];
1283 invocation = (GDBusMethodInvocation *)params[1];
1284 service_id = (intptr_t)params[2];
1285 channel_id = (intptr_t)params[3];
1286 command = (GVariant *)params[4];
1287 user_data = params[5];
1289 __process_transmit(object, invocation, service_id,
1290 channel_id, command, user_data);
1292 g_object_unref(object);
1293 g_object_unref(invocation);
1294 g_object_unref(command);
1297 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1298 GDBusMethodInvocation *invocation,
1299 intptr_t service_id,
1300 intptr_t channel_id,
1304 vector<void *> params;
1306 /* apply user space smack */
1307 if (_is_authorized_request(invocation, "r") == true) {
1308 /* enqueue message */
1309 g_object_ref(object);
1310 params.push_back((void *)object);
1312 g_object_ref(invocation);
1313 params.push_back((void *)invocation);
1315 params.push_back((void *)service_id);
1316 params.push_back((void *)channel_id);
1318 g_object_ref(command);
1319 params.push_back((void *)command);
1321 params.push_back(user_data);
1323 GDBusDispatcher::push(_process_transmit, params);
1327 _ERR("access denied");
1329 /* response to client */
1330 smartcard_service_channel_complete_transmit(object,
1332 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1333 GDBusHelper::convertByteArrayToVariant(resp));
1339 bool ServerGDBus::initChannel()
1341 GError *error = NULL;
1343 channel = smartcard_service_channel_skeleton_new();
1345 g_signal_connect(channel,
1346 "handle-close-channel",
1347 G_CALLBACK(_handle_close_channel),
1350 g_signal_connect(channel,
1352 G_CALLBACK(_handle_transmit),
1355 if (g_dbus_interface_skeleton_export(
1356 G_DBUS_INTERFACE_SKELETON(channel),
1358 "/org/tizen/SmartcardService/Channel",
1361 _ERR("Can not skeleton_export %s", error->message);
1363 g_error_free(error);
1364 g_object_unref(channel);
1373 void ServerGDBus::deinitChannel()
1375 if (channel != NULL) {
1376 g_object_unref(channel);
1380 } /* namespace smartcard_service_api */