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.
17 /* standard library header */
23 #include <sys/socket.h>
26 #include "smartcard-types.h"
28 #include "ByteArray.h"
29 #include "ServerResource.h"
30 #include "GDBusHelper.h"
31 #include "ServerGDBus.h"
36 extern "C" bool smartcard_service_init_access_control(void *connection);
37 extern "C" void smartcard_service_deinit_access_control();
40 namespace smartcard_service_api
42 GDBusDispatcher::GDBusDispatcher() : Synchronous()
46 GDBusDispatcher::~GDBusDispatcher()
50 GDBusDispatcher &GDBusDispatcher::getInstance()
52 static GDBusDispatcher dispatcher;
57 void GDBusDispatcher::_push(dispatcher_cb_t cb,
58 const vector<void *> ¶ms)
62 q.push(make_pair(cb, params));
63 _INFO("request pushed, count [%d]", q.size());
67 _INFO("start dispatcher");
68 g_idle_add(&GDBusDispatcher::dispatch, this);
74 void GDBusDispatcher::push(dispatcher_cb_t cb,
75 const vector<void *> ¶ms)
77 GDBusDispatcher::getInstance()._push(cb, params);
80 gboolean GDBusDispatcher::dispatch(gpointer user_data)
82 GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
83 gboolean result = false;
87 dispatcher->syncLock();
89 pair<dispatcher_cb_t, vector<void *> > &job =
90 dispatcher->q.front();
92 dispatcher->syncUnlock();
94 job.first(job.second);
96 dispatcher->syncLock();
99 if (dispatcher->q.size() > 0) {
100 _INFO("remaining messages : %d", dispatcher->q.size());
104 _INFO("dispatch finished");
107 dispatcher->syncUnlock();
114 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
115 seService(NULL), reader(NULL), session(NULL), channel(NULL)
119 ServerGDBus::~ServerGDBus()
124 ServerGDBus &ServerGDBus::getInstance()
126 static ServerGDBus serverGDBus;
131 static void name_owner_changed(GDBusProxy *proxy,
132 const gchar *name, const gchar *old_owner,
133 const gchar *new_owner, void *user_data)
135 if (name == NULL || old_owner == NULL || new_owner == NULL) {
136 _ERR("invalid parameter");
140 if (strlen(new_owner) == 0) {
141 ClientInstance *client;
143 ServerResource &resource = ServerResource::getInstance();
145 client = resource.getClient(old_owner);
146 if (client != NULL) {
147 _INFO("terminated client, pid [%d]", client->getPID());
148 resource.removeClient(old_owner);
155 static void _on_name_owner_changed(GDBusConnection *connection,
156 const gchar *sender_name, const gchar *object_path,
157 const gchar *interface_name, const gchar *signal_name,
158 GVariant *parameters, gpointer user_data)
164 g_variant_get(parameters,
170 name_owner_changed((GDBusProxy *)connection,
171 name, old_owner, new_owner, user_data);
174 bool ServerGDBus::_init()
176 GError *error = NULL;
178 /* init default context */
179 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
180 G_DBUS_PROXY_FLAGS_NONE,
181 NULL, /* GDBusInterfaceInfo */
182 "org.freedesktop.DBus",
183 "/org/freedesktop/DBus",
184 "org.freedesktop.DBus",
185 NULL, /* GCancellable */
187 if (dbus_proxy == NULL)
189 _ERR("Can not create proxy : %s", error->message);
195 /* subscribe signal */
196 g_dbus_connection_signal_subscribe(connection,
197 "org.freedesktop.DBus", /* bus name */
198 "org.freedesktop.DBus", /* interface */
199 "NameOwnerChanged", /* member */
200 "/org/freedesktop/DBus", /* path */
202 G_DBUS_SIGNAL_FLAGS_NONE,
203 _on_name_owner_changed,
209 void ServerGDBus::_deinit()
211 if (dbus_proxy != NULL) {
212 g_object_unref(dbus_proxy);
217 bool ServerGDBus::init()
219 GError *error = NULL;
221 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
222 if (connection != NULL) {
224 _ERR("Can not get connection %s", error->message);
237 smartcard_service_init_access_control(connection);
242 void ServerGDBus::deinit()
245 smartcard_service_deinit_access_control();
254 if (connection != NULL) {
255 g_object_unref(connection);
260 static gboolean _call_get_connection_unix_process_id_sync(
261 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
262 GCancellable *cancellable, GError **error) {
265 _ret = g_dbus_proxy_call_sync(proxy,
266 "GetConnectionUnixProcessID",
267 g_variant_new("(s)", arg_name),
268 G_DBUS_CALL_FLAGS_NONE,
269 -1, cancellable, error);
271 g_variant_get(_ret, "(u)", out_pid);
272 g_variant_unref(_ret);
278 pid_t ServerGDBus::getPID(const char *name)
281 GError *error = NULL;
283 if (_call_get_connection_unix_process_id_sync(
284 (GDBusProxy *)dbus_proxy, name,
285 &pid, NULL, &error) == true) {
287 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
294 static bool _is_authorized_request(GDBusMethodInvocation *invocation,
306 static GVariant *_reader_to_variant(
307 vector<pair<unsigned int, string> > &readers)
309 GVariantBuilder builder;
312 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
314 for (i = 0; i < readers.size(); i++) {
315 g_variant_builder_add(&builder, "(us)",
316 readers[i].first, readers[i].second.c_str());
319 return g_variant_builder_end(&builder);
322 static gboolean __process_se_service(SmartcardServiceSeService *object,
323 GDBusMethodInvocation *invocation,
326 gint result = SCARD_ERROR_OK;
327 GVariant *readers = NULL;
328 vector<pair<unsigned int, string> > list;
329 unsigned int handle = IntegerHandle::INVALID_HANDLE;
333 _INFO("[MSG_REQUEST_READERS]");
335 ServerResource &resource = ServerResource::getInstance();
337 name = g_dbus_method_invocation_get_sender(invocation);
339 /* load secure elements */
340 resource.loadSecureElements();
342 pid = ServerGDBus::getInstance().getPID(name);
344 _DBG("service requested, pid [%d]", pid);
347 ClientInstance *instance;
349 instance = resource.getClient(name);
350 if (instance == NULL) {
351 _INFO("create client instance, pid [%d]", pid);
353 resource.createClient(name, pid);
355 instance = resource.getClient(name);
356 if (instance != NULL) {
357 /* generate certification hashes */
358 instance->generateCertificationHashes();
360 _ERR("createClient failed");
364 if (instance != NULL) {
365 ServiceInstance *service;
368 service = resource.createService(name);
369 if (service != NULL) {
371 handle = service->getHandle();
372 resource.getReaders(list);
374 if (list.size() == 0) {
375 _INFO("no secure elements");
378 _ERR("createService failed");
380 result = SCARD_ERROR_OUT_OF_MEMORY;
383 _ERR("client doesn't exist, pid [%d]", pid);
385 result = SCARD_ERROR_OUT_OF_MEMORY;
388 _ERR("invalid pid, [%d]", pid);
390 result = SCARD_ERROR_IPC_FAILED;
393 readers = _reader_to_variant(list);
395 /* response to client */
396 smartcard_service_se_service_complete_se_service(object,
397 invocation, result, handle, readers);
402 static void _process_se_service(vector<void *> ¶ms)
404 SmartcardServiceSeService *object;
405 GDBusMethodInvocation *invocation;
408 if (params.size() != 3) {
409 _ERR("invalid parameter");
414 object = (SmartcardServiceSeService *)params[0];
415 invocation = (GDBusMethodInvocation *)params[1];
416 user_data = params[2];
418 __process_se_service(object, invocation, user_data);
420 g_object_unref(object);
421 g_object_unref(invocation);
424 static gboolean _handle_se_service(SmartcardServiceSeService *object,
425 GDBusMethodInvocation *invocation,
428 vector<void *> params;
430 /* apply user space smack */
431 if (_is_authorized_request(invocation, "r") == true) {
432 g_object_ref(object);
433 params.push_back((void *)object);
435 g_object_ref(invocation);
436 params.push_back((void *)invocation);
438 params.push_back((void *)user_data);
440 GDBusDispatcher::push(_process_se_service, params);
442 vector<pair<unsigned int, string> > list;
444 _ERR("access denied");
446 /* response to client */
447 smartcard_service_se_service_complete_se_service(object,
449 SCARD_ERROR_SECURITY_NOT_ALLOWED,
450 IntegerHandle::INVALID_HANDLE,
451 _reader_to_variant(list));
457 static gboolean __process_shutdown(SmartcardServiceSeService *object,
458 GDBusMethodInvocation *invocation,
459 guint handle, void *user_data)
463 _INFO("[MSG_REQUEST_SHUTDOWN]");
465 ServerResource &resource = ServerResource::getInstance();
467 name = g_dbus_method_invocation_get_sender(invocation);
469 resource.removeService(name, handle);
471 /* response to client */
472 smartcard_service_se_service_complete_shutdown(object,
473 invocation, SCARD_ERROR_OK);
481 static void _process_shutdown(vector<void *> ¶ms)
483 SmartcardServiceSeService *object;
484 GDBusMethodInvocation *invocation;
488 if (params.size() != 4) {
489 _ERR("invalid parameter");
494 object = (SmartcardServiceSeService *)params[0];
495 invocation = (GDBusMethodInvocation *)params[1];
496 handle = (gulong)params[2];
497 user_data = params[3];
499 __process_shutdown(object, invocation, handle, user_data);
501 g_object_unref(object);
502 g_object_unref(invocation);
505 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
506 GDBusMethodInvocation *invocation,
510 vector<void *> params;
512 /* apply user space smack */
513 if (_is_authorized_request(invocation, "r") == true) {
514 g_object_ref(object);
515 params.push_back((void *)object);
517 g_object_ref(invocation);
518 params.push_back((void *)invocation);
520 params.push_back((void *)handle);
521 params.push_back(user_data);
523 GDBusDispatcher::push(_process_shutdown, params);
525 _ERR("access denied");
527 /* response to client */
528 smartcard_service_se_service_complete_shutdown(object,
529 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
535 bool ServerGDBus::initSEService()
537 GError *error = NULL;
539 seService = smartcard_service_se_service_skeleton_new();
541 g_signal_connect(seService,
543 G_CALLBACK(_handle_se_service),
546 g_signal_connect(seService,
548 G_CALLBACK(_handle_shutdown),
551 if (g_dbus_interface_skeleton_export(
552 G_DBUS_INTERFACE_SKELETON(seService),
554 "/org/tizen/SmartcardService/SeService",
557 _ERR("Can not skeleton_export %s", error->message);
560 g_object_unref(seService);
569 void ServerGDBus::deinitSEService()
571 if (seService != NULL) {
572 g_object_unref(seService);
577 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
578 const char *reader_name)
580 smartcard_service_se_service_emit_reader_inserted(
581 SMARTCARD_SERVICE_SE_SERVICE(seService),
582 reader_id, reader_name);
585 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
586 const char *reader_name)
588 smartcard_service_se_service_emit_reader_removed(
589 SMARTCARD_SERVICE_SE_SERVICE(seService),
590 reader_id, reader_name);
597 static gboolean __process_open_session(SmartcardServiceReader *object,
598 GDBusMethodInvocation *invocation, guint service_id,
599 guint reader_id, void *user_data)
601 unsigned int handle = IntegerHandle::INVALID_HANDLE;
605 _INFO("[MSG_REQUEST_OPEN_SESSION]");
607 ServerResource &resource = ServerResource::getInstance();
609 name = g_dbus_method_invocation_get_sender(invocation);
611 if (resource.isValidReaderHandle(reader_id)) {
612 vector<ByteArray> temp;
614 handle = resource.createSession(name,
619 if (handle != IntegerHandle::INVALID_HANDLE) {
620 result = SCARD_ERROR_OK;
622 _ERR("createSession failed [%d]", handle);
624 result = SCARD_ERROR_OUT_OF_MEMORY;
627 _ERR("request invalid reader handle [%d]", reader_id);
629 result = SCARD_ERROR_ILLEGAL_PARAM;
632 /* response to client */
633 smartcard_service_reader_complete_open_session(object,
634 invocation, result, handle);
639 static void _process_open_session(vector<void *> ¶ms)
641 SmartcardServiceReader *object;
642 GDBusMethodInvocation *invocation;
647 if (params.size() != 5) {
648 _ERR("invalid parameter");
653 object = (SmartcardServiceReader *)params[0];
654 invocation = (GDBusMethodInvocation *)params[1];
655 service_id = (gulong)params[2];
656 reader_id = (gulong)params[3];
657 user_data = params[4];
659 __process_open_session(object, invocation, service_id,
660 reader_id, user_data);
662 g_object_unref(object);
663 g_object_unref(invocation);
666 static gboolean _handle_open_session(SmartcardServiceReader *object,
667 GDBusMethodInvocation *invocation,
669 guint reader_id, void *user_data)
671 vector<void *> params;
673 /* apply user space smack */
674 if (_is_authorized_request(invocation, "r") == true) {
675 g_object_ref(object);
676 params.push_back((void *)object);
678 g_object_ref(invocation);
679 params.push_back((void *)invocation);
681 params.push_back((void *)service_id);
682 params.push_back((void *)reader_id);
683 params.push_back(user_data);
685 GDBusDispatcher::push(_process_open_session, params);
687 _ERR("access denied");
689 /* response to client */
690 smartcard_service_reader_complete_open_session(object,
692 SCARD_ERROR_SECURITY_NOT_ALLOWED,
693 IntegerHandle::INVALID_HANDLE);
699 bool ServerGDBus::initReader()
701 GError *error = NULL;
703 reader = smartcard_service_reader_skeleton_new();
705 g_signal_connect(reader,
706 "handle-open-session",
707 G_CALLBACK(_handle_open_session),
710 if (g_dbus_interface_skeleton_export(
711 G_DBUS_INTERFACE_SKELETON(reader),
713 "/org/tizen/SmartcardService/Reader",
716 _ERR("Can not skeleton_export %s", error->message);
719 g_object_unref(reader);
728 void ServerGDBus::deinitReader()
730 if (reader != NULL) {
731 g_object_unref(reader);
740 static gboolean __process_close_session(SmartcardServiceSession *object,
741 GDBusMethodInvocation *invocation, guint service_id,
742 guint session_id, void *user_data)
746 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
748 ServerResource &resource = ServerResource::getInstance();
750 name = g_dbus_method_invocation_get_sender(invocation);
752 if (resource.isValidSessionHandle(name, service_id,
754 resource.removeSession(name, service_id,
757 _ERR("invalid parameters");
760 /* response to client */
761 smartcard_service_session_complete_close_session(object,
762 invocation, SCARD_ERROR_OK);
767 static void _process_close_session(vector<void *> ¶ms)
769 SmartcardServiceSession *object;
770 GDBusMethodInvocation *invocation;
775 if (params.size() != 5) {
776 _ERR("invalid parameter");
781 object = (SmartcardServiceSession *)params[0];
782 invocation = (GDBusMethodInvocation *)params[1];
783 service_id = (gulong)params[2];
784 session_id = (gulong)params[3];
785 user_data = params[4];
787 __process_close_session(object, invocation, service_id,
788 session_id, user_data);
790 g_object_unref(object);
791 g_object_unref(invocation);
794 static gboolean _handle_close_session(SmartcardServiceSession *object,
795 GDBusMethodInvocation *invocation,
797 guint session_id, void *user_data)
799 vector<void *> params;
801 /* apply user space smack */
802 if (_is_authorized_request(invocation, "r") == true) {
803 g_object_ref(object);
804 params.push_back((void *)object);
806 g_object_ref(invocation);
807 params.push_back((void *)invocation);
809 params.push_back((void *)service_id);
810 params.push_back((void *)session_id);
811 params.push_back(user_data);
813 GDBusDispatcher::push(_process_close_session, params);
815 _ERR("access denied");
817 /* response to client */
818 smartcard_service_session_complete_close_session(object,
819 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
825 static gboolean __process_get_atr(SmartcardServiceSession *object,
826 GDBusMethodInvocation *invocation, guint service_id,
827 guint session_id, void *user_data)
831 GVariant *atr = NULL;
833 ServiceInstance *client = NULL;
835 _INFO("[MSG_REQUEST_GET_ATR]");
837 ServerResource &resource = ServerResource::getInstance();
839 name = g_dbus_method_invocation_get_sender(invocation);
841 client = resource.getService(name, service_id);
842 if (client != NULL) {
845 terminal = client->getTerminal(session_id);
846 if (terminal != NULL) {
847 if (terminal->open() == true) {
848 result = terminal->getATRSync(resp);
849 if (result < SCARD_ERROR_OK) {
850 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
855 _ERR("terminal->open failed");
857 result = SCARD_ERROR_UNAVAILABLE;
860 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
862 result = SCARD_ERROR_UNAVAILABLE;
865 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
867 result = SCARD_ERROR_UNAVAILABLE;
870 atr = GDBusHelper::convertByteArrayToVariant(resp);
872 /* response to client */
873 smartcard_service_session_complete_get_atr(object, invocation,
879 static void _process_get_atr(vector<void *> ¶ms)
881 SmartcardServiceSession *object;
882 GDBusMethodInvocation *invocation;
887 if (params.size() != 5) {
888 _ERR("invalid parameter");
893 object = (SmartcardServiceSession *)params[0];
894 invocation = (GDBusMethodInvocation *)params[1];
895 service_id = (gulong)params[2];
896 session_id = (gulong)params[3];
897 user_data = params[4];
899 __process_get_atr(object, invocation, service_id,
900 session_id, user_data);
902 g_object_unref(object);
903 g_object_unref(invocation);
906 static gboolean _handle_get_atr(SmartcardServiceSession *object,
907 GDBusMethodInvocation *invocation,
909 guint session_id, void *user_data)
911 vector<void *> params;
913 /* apply user space smack */
914 if (_is_authorized_request(invocation, "r") == true) {
915 g_object_ref(object);
916 params.push_back((void *)object);
918 g_object_ref(invocation);
919 params.push_back((void *)invocation);
921 params.push_back((void *)service_id);
922 params.push_back((void *)session_id);
923 params.push_back(user_data);
925 GDBusDispatcher::push(_process_get_atr, params);
929 _ERR("access denied");
931 /* response to client */
932 smartcard_service_session_complete_get_atr(
935 SCARD_ERROR_SECURITY_NOT_ALLOWED,
936 GDBusHelper::convertByteArrayToVariant(resp));
942 static gboolean __process_open_channel(SmartcardServiceSession *object,
943 GDBusMethodInvocation *invocation, guint service_id,
944 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
947 int result = SCARD_ERROR_UNKNOWN;
949 GVariant *response = NULL;
950 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
953 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
954 _INFO("P2 is %x", P2);
956 ServerResource &resource = ServerResource::getInstance();
958 name = g_dbus_method_invocation_get_sender(invocation);
964 GDBusHelper::convertVariantToByteArray(aid,
967 channelID = resource.createChannel(name,
968 service_id, session_id, type, tempAid);
969 if (channelID != IntegerHandle::INVALID_HANDLE) {
972 temp = (ServerChannel *)resource.getChannel(
973 name, service_id, channelID);
975 resp = temp->getSelectResponse();
976 channelNum = temp->getChannelNumber();
977 result = SCARD_ERROR_OK;
980 _ERR("getChannel is failed");
981 result = SCARD_ERROR_UNAVAILABLE;
984 _ERR("channel is null.");
986 /* set error value */
987 result = SCARD_ERROR_UNAVAILABLE;
990 catch (ExceptionBase &e)
992 result = e.getErrorCode();
995 response = GDBusHelper::convertByteArrayToVariant(resp);
997 /* response to client */
998 smartcard_service_session_complete_open_channel(object,
999 invocation, result, channelID, channelNum, response);
1004 static void _process_open_channel(vector<void *> ¶ms)
1006 SmartcardServiceSession *object;
1007 GDBusMethodInvocation *invocation;
1015 if (params.size() != 8) {
1016 _ERR("invalid parameter");
1021 object = (SmartcardServiceSession *)params[0];
1022 invocation = (GDBusMethodInvocation *)params[1];
1023 service_id = (gulong)params[2];
1024 session_id = (gulong)params[3];
1025 type = (gulong)params[4];
1026 aid = (GVariant *)params[5];
1027 P2 = (guint8)((gulong)params[6]);
1028 user_data = params[7];
1030 __process_open_channel(object, invocation, service_id,
1031 session_id, type, aid, P2, user_data);
1033 g_object_unref(object);
1034 g_object_unref(invocation);
1035 g_variant_unref(aid);
1038 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1039 GDBusMethodInvocation *invocation,
1041 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1043 vector<void *> params;
1045 /* apply user space smack */
1046 if (_is_authorized_request(invocation, "rw") == true) {
1047 g_object_ref(object);
1048 params.push_back((void *)object);
1050 g_object_ref(invocation);
1051 params.push_back((void *)invocation);
1053 params.push_back((void *)service_id);
1054 params.push_back((void *)session_id);
1055 params.push_back((void *)type);
1058 params.push_back((void *)aid);
1059 params.push_back((void *)((int)P2));
1060 params.push_back(user_data);
1062 GDBusDispatcher::push(_process_open_channel, params);
1066 _ERR("access denied");
1068 /* response to client */
1069 smartcard_service_session_complete_open_channel(object,
1071 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1072 IntegerHandle::INVALID_HANDLE,
1074 GDBusHelper::convertByteArrayToVariant(resp));
1080 bool ServerGDBus::initSession()
1082 GError *error = NULL;
1084 session = smartcard_service_session_skeleton_new();
1086 g_signal_connect(session,
1087 "handle-close-session",
1088 G_CALLBACK(_handle_close_session),
1091 g_signal_connect(session,
1093 G_CALLBACK(_handle_get_atr),
1096 g_signal_connect(session,
1097 "handle-open-channel",
1098 G_CALLBACK(_handle_open_channel),
1101 if (g_dbus_interface_skeleton_export(
1102 G_DBUS_INTERFACE_SKELETON(session),
1104 "/org/tizen/SmartcardService/Session",
1107 _ERR("Can not skeleton_export %s", error->message);
1109 g_error_free(error);
1110 g_object_unref(session);
1119 void ServerGDBus::deinitSession()
1121 if (session != NULL) {
1122 g_object_unref(session);
1131 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1132 GDBusMethodInvocation *invocation, guint service_id,
1133 guint channel_id, void *user_data)
1138 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1140 ServerResource &resource = ServerResource::getInstance();
1142 name = g_dbus_method_invocation_get_sender(invocation);
1144 resource.removeChannel(name, service_id, channel_id);
1146 result = SCARD_ERROR_OK;
1148 /* response to client */
1149 smartcard_service_channel_complete_close_channel(object,
1150 invocation, result);
1155 static void _process_close_channel(vector<void *> ¶ms)
1157 SmartcardServiceChannel *object;
1158 GDBusMethodInvocation *invocation;
1163 if (params.size() != 5) {
1164 _ERR("invalid parameter");
1169 object = (SmartcardServiceChannel *)params[0];
1170 invocation = (GDBusMethodInvocation *)params[1];
1171 service_id = (gulong)params[2];
1172 channel_id = (gulong)params[3];
1173 user_data = params[4];
1175 __process_close_channel(object, invocation, service_id,
1176 channel_id, user_data);
1178 g_object_unref(object);
1179 g_object_unref(invocation);
1182 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1183 GDBusMethodInvocation *invocation,
1184 guint service_id, guint channel_id, void *user_data)
1186 vector<void *> params;
1188 /* apply user space smack */
1189 if (_is_authorized_request(invocation, "r") == true) {
1190 g_object_ref(object);
1191 params.push_back((void *)object);
1193 g_object_ref(invocation);
1194 params.push_back((void *)invocation);
1196 params.push_back((void *)service_id);
1197 params.push_back((void *)channel_id);
1198 params.push_back(user_data);
1200 GDBusDispatcher::push(_process_close_channel, params);
1202 _ERR("access denied");
1204 /* response to client */
1205 smartcard_service_channel_complete_close_channel(
1208 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1214 static gboolean __process_transmit(SmartcardServiceChannel *object,
1215 GDBusMethodInvocation *invocation,
1222 Channel *channel = NULL;
1224 GVariant *response = NULL;
1227 _INFO("[MSG_REQUEST_TRANSMIT]");
1229 ServerResource &resource = ServerResource::getInstance();
1231 name = g_dbus_method_invocation_get_sender(invocation);
1233 channel = resource.getChannel(name, service_id, channel_id);
1234 if (channel != NULL) {
1238 GDBusHelper::convertVariantToByteArray(command, cmd);
1240 rv = channel->transmitSync(cmd, resp);
1242 result = SCARD_ERROR_OK;
1244 _ERR("transmit failed [%d]", rv);
1249 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1251 result = SCARD_ERROR_UNAVAILABLE;
1254 response = GDBusHelper::convertByteArrayToVariant(resp);
1256 /* response to client */
1257 smartcard_service_channel_complete_transmit(object, invocation,
1263 static void _process_transmit(vector<void *> ¶ms)
1265 SmartcardServiceChannel *object;
1266 GDBusMethodInvocation *invocation;
1272 if (params.size() != 6) {
1273 _ERR("invalid parameter");
1278 object = (SmartcardServiceChannel *)params[0];
1279 invocation = (GDBusMethodInvocation *)params[1];
1280 service_id = (gulong)params[2];
1281 channel_id = (gulong)params[3];
1282 command = (GVariant *)params[4];
1283 user_data = params[5];
1285 __process_transmit(object, invocation, service_id,
1286 channel_id, command, user_data);
1288 g_object_unref(object);
1289 g_object_unref(invocation);
1290 g_object_unref(command);
1293 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1294 GDBusMethodInvocation *invocation,
1300 vector<void *> params;
1302 /* apply user space smack */
1303 if (_is_authorized_request(invocation, "r") == true) {
1304 /* enqueue message */
1305 g_object_ref(object);
1306 params.push_back((void *)object);
1308 g_object_ref(invocation);
1309 params.push_back((void *)invocation);
1311 params.push_back((void *)service_id);
1312 params.push_back((void *)channel_id);
1314 g_object_ref(command);
1315 params.push_back((void *)command);
1317 params.push_back(user_data);
1319 GDBusDispatcher::push(_process_transmit, params);
1323 _ERR("access denied");
1325 /* response to client */
1326 smartcard_service_channel_complete_transmit(object,
1328 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1329 GDBusHelper::convertByteArrayToVariant(resp));
1335 bool ServerGDBus::initChannel()
1337 GError *error = NULL;
1339 channel = smartcard_service_channel_skeleton_new();
1341 g_signal_connect(channel,
1342 "handle-close-channel",
1343 G_CALLBACK(_handle_close_channel),
1346 g_signal_connect(channel,
1348 G_CALLBACK(_handle_transmit),
1351 if (g_dbus_interface_skeleton_export(
1352 G_DBUS_INTERFACE_SKELETON(channel),
1354 "/org/tizen/SmartcardService/Channel",
1357 _ERR("Can not skeleton_export %s", error->message);
1359 g_error_free(error);
1360 g_object_unref(channel);
1369 void ServerGDBus::deinitChannel()
1371 if (channel != NULL) {
1372 g_object_unref(channel);
1376 } /* namespace smartcard_service_api */