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 (name == NULL || old_owner == NULL || new_owner == NULL) {
137 _ERR("invalid parameter");
141 if (strlen(new_owner) == 0) {
142 ClientInstance *client;
144 ServerResource &resource = ServerResource::getInstance();
146 client = resource.getClient(old_owner);
147 if (client != NULL) {
148 _INFO("terminated client, pid [%d]", client->getPID());
149 resource.removeClient(old_owner);
156 static void _on_name_owner_changed(GDBusConnection *connection,
157 const gchar *sender_name, const gchar *object_path,
158 const gchar *interface_name, const gchar *signal_name,
159 GVariant *parameters, gpointer user_data)
166 iter = g_variant_iter_new(parameters);
168 g_variant_iter_next(iter, "s", &name);
169 g_variant_iter_next(iter, "s", &old_owner);
170 g_variant_iter_next(iter, "s", &new_owner);
172 name_owner_changed((GDBusProxy *)connection,
173 name, old_owner, new_owner, user_data);
176 bool ServerGDBus::_init()
178 GError *error = NULL;
180 /* init default context */
181 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
182 G_DBUS_PROXY_FLAGS_NONE,
183 NULL, /* GDBusInterfaceInfo */
184 "org.freedesktop.DBus",
185 "/org/freedesktop/DBus",
186 "org.freedesktop.DBus",
187 NULL, /* GCancellable */
189 if (dbus_proxy == NULL)
191 _ERR("Can not create proxy : %s", error->message);
197 /* subscribe signal */
198 g_dbus_connection_signal_subscribe(connection,
199 "org.freedesktop.DBus", /* bus name */
200 "org.freedesktop.DBus", /* interface */
201 "NameOwnerChanged", /* member */
202 "/org/freedesktop/DBus", /* path */
204 G_DBUS_SIGNAL_FLAGS_NONE,
205 _on_name_owner_changed,
211 void ServerGDBus::_deinit()
213 if (dbus_proxy != NULL) {
214 g_object_unref(dbus_proxy);
219 bool ServerGDBus::init()
221 GError *error = NULL;
223 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
224 if (connection != NULL) {
226 _ERR("Can not get connection %s", error->message);
242 void ServerGDBus::deinit()
251 if (connection != NULL) {
252 g_object_unref(connection);
257 static gboolean _call_get_connection_unix_process_id_sync(
258 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
259 GCancellable *cancellable, GError **error) {
262 _ret = g_dbus_proxy_call_sync(proxy,
263 "GetConnectionUnixProcessID",
264 g_variant_new("(s)", arg_name),
265 G_DBUS_CALL_FLAGS_NONE,
266 -1, cancellable, error);
268 g_variant_get(_ret, "(u)", out_pid);
269 g_variant_unref(_ret);
275 pid_t ServerGDBus::getPID(const char *name)
278 GError *error = NULL;
280 if (_call_get_connection_unix_process_id_sync(
281 (GDBusProxy *)dbus_proxy, name,
282 &pid, NULL, &error) == true) {
284 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
291 static bool _is_authorized_request(GDBusMethodInvocation *invocation,
295 #ifdef USER_SPACE_SMACK
298 ClientInstance *instance;
300 name = g_dbus_method_invocation_get_sender(invocation);
302 instance = ServerResource::getInstance().getClient(name);
303 if (instance != NULL) {
304 pid = instance->getPID();
306 pid = ServerGDBus::getInstance().getPID(name);
309 result = (security_server_check_privilege_by_pid(
312 rights) == SECURITY_SERVER_API_SUCCESS);
321 static GVariant *_reader_to_variant(
322 vector<pair<unsigned int, string> > &readers)
324 GVariantBuilder builder;
327 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
329 for (i = 0; i < readers.size(); i++) {
330 g_variant_builder_add(&builder, "(us)",
331 readers[i].first, readers[i].second.c_str());
334 return g_variant_builder_end(&builder);
337 static gboolean __process_se_service(SmartcardServiceSeService *object,
338 GDBusMethodInvocation *invocation,
341 gint result = SCARD_ERROR_OK;
342 GVariant *readers = NULL;
343 vector<pair<unsigned int, string> > list;
344 unsigned int handle = IntegerHandle::INVALID_HANDLE;
348 _INFO("[MSG_REQUEST_READERS]");
350 ServerResource &resource = ServerResource::getInstance();
352 name = g_dbus_method_invocation_get_sender(invocation);
354 /* load secure elements */
355 resource.loadSecureElements();
357 pid = ServerGDBus::getInstance().getPID(name);
359 _DBG("service requested, pid [%d]", pid);
362 ClientInstance *instance;
364 instance = resource.getClient(name);
365 if (instance == NULL) {
366 _INFO("create client instance, pid [%d]", pid);
368 resource.createClient(name, pid);
370 instance = resource.getClient(name);
371 if (instance != NULL) {
372 /* generate certification hashes */
373 instance->generateCertificationHashes();
375 _ERR("createClient failed");
379 if (instance != NULL) {
380 ServiceInstance *service;
383 service = resource.createService(name);
384 if (service != NULL) {
386 handle = service->getHandle();
387 resource.getReaders(list);
389 if (list.size() == 0) {
390 _INFO("no secure elements");
393 _ERR("createService failed");
395 result = SCARD_ERROR_OUT_OF_MEMORY;
398 _ERR("client doesn't exist, pid [%d]", pid);
400 result = SCARD_ERROR_OUT_OF_MEMORY;
403 _ERR("invalid pid, [%d]", pid);
405 result = SCARD_ERROR_IPC_FAILED;
408 readers = _reader_to_variant(list);
410 /* response to client */
411 smartcard_service_se_service_complete_se_service(object,
412 invocation, result, handle, readers);
417 static void _process_se_service(vector<void *> ¶ms)
419 SmartcardServiceSeService *object;
420 GDBusMethodInvocation *invocation;
423 if (params.size() != 3) {
424 _ERR("invalid parameter");
429 object = (SmartcardServiceSeService *)params[0];
430 invocation = (GDBusMethodInvocation *)params[1];
431 user_data = params[2];
433 __process_se_service(object, invocation, user_data);
435 g_object_unref(object);
436 g_object_unref(invocation);
439 static gboolean _handle_se_service(SmartcardServiceSeService *object,
440 GDBusMethodInvocation *invocation,
443 vector<void *> params;
445 /* apply user space smack */
446 if (_is_authorized_request(invocation, "r") == true) {
447 g_object_ref(object);
448 params.push_back((void *)object);
450 g_object_ref(invocation);
451 params.push_back((void *)invocation);
453 params.push_back((void *)user_data);
455 GDBusDispatcher::push(_process_se_service, params);
457 vector<pair<unsigned int, string> > list;
459 _ERR("access denied");
461 /* response to client */
462 smartcard_service_se_service_complete_se_service(object,
464 SCARD_ERROR_SECURITY_NOT_ALLOWED,
465 IntegerHandle::INVALID_HANDLE,
466 _reader_to_variant(list));
472 static gboolean __process_shutdown(SmartcardServiceSeService *object,
473 GDBusMethodInvocation *invocation,
474 guint handle, void *user_data)
478 _INFO("[MSG_REQUEST_SHUTDOWN]");
480 ServerResource &resource = ServerResource::getInstance();
482 name = g_dbus_method_invocation_get_sender(invocation);
484 resource.removeService(name, handle);
486 /* response to client */
487 smartcard_service_se_service_complete_shutdown(object,
488 invocation, SCARD_ERROR_OK);
496 static void _process_shutdown(vector<void *> ¶ms)
498 SmartcardServiceSeService *object;
499 GDBusMethodInvocation *invocation;
503 if (params.size() != 4) {
504 _ERR("invalid parameter");
509 object = (SmartcardServiceSeService *)params[0];
510 invocation = (GDBusMethodInvocation *)params[1];
511 handle = (guint)params[2];
512 user_data = params[3];
514 __process_shutdown(object, invocation, handle, user_data);
516 g_object_unref(object);
517 g_object_unref(invocation);
520 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
521 GDBusMethodInvocation *invocation,
525 vector<void *> params;
527 /* apply user space smack */
528 if (_is_authorized_request(invocation, "r") == true) {
529 g_object_ref(object);
530 params.push_back((void *)object);
532 g_object_ref(invocation);
533 params.push_back((void *)invocation);
535 params.push_back((void *)handle);
536 params.push_back(user_data);
538 GDBusDispatcher::push(_process_shutdown, params);
540 _ERR("access denied");
542 /* response to client */
543 smartcard_service_se_service_complete_shutdown(object,
544 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
550 bool ServerGDBus::initSEService()
552 GError *error = NULL;
554 seService = smartcard_service_se_service_skeleton_new();
556 g_signal_connect(seService,
558 G_CALLBACK(_handle_se_service),
561 g_signal_connect(seService,
563 G_CALLBACK(_handle_shutdown),
566 if (g_dbus_interface_skeleton_export(
567 G_DBUS_INTERFACE_SKELETON(seService),
569 "/org/tizen/SmartcardService/SeService",
572 _ERR("Can not skeleton_export %s", error->message);
575 g_object_unref(seService);
584 void ServerGDBus::deinitSEService()
586 if (seService != NULL) {
587 g_object_unref(seService);
592 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
593 const char *reader_name)
595 smartcard_service_se_service_emit_reader_inserted(
596 SMARTCARD_SERVICE_SE_SERVICE(seService),
597 reader_id, reader_name);
600 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
601 const char *reader_name)
603 smartcard_service_se_service_emit_reader_removed(
604 SMARTCARD_SERVICE_SE_SERVICE(seService),
605 reader_id, reader_name);
612 static gboolean __process_open_session(SmartcardServiceReader *object,
613 GDBusMethodInvocation *invocation, guint service_id,
614 guint reader_id, void *user_data)
616 unsigned int handle = IntegerHandle::INVALID_HANDLE;
620 _INFO("[MSG_REQUEST_OPEN_SESSION]");
622 ServerResource &resource = ServerResource::getInstance();
624 name = g_dbus_method_invocation_get_sender(invocation);
626 if (resource.isValidReaderHandle(reader_id)) {
627 vector<ByteArray> temp;
629 handle = resource.createSession(name,
634 if (handle != IntegerHandle::INVALID_HANDLE) {
635 result = SCARD_ERROR_OK;
637 _ERR("createSession failed [%d]", handle);
639 result = SCARD_ERROR_OUT_OF_MEMORY;
642 _ERR("request invalid reader handle [%d]", reader_id);
644 result = SCARD_ERROR_ILLEGAL_PARAM;
647 /* response to client */
648 smartcard_service_reader_complete_open_session(object,
649 invocation, result, handle);
654 static void _process_open_session(vector<void *> ¶ms)
656 SmartcardServiceReader *object;
657 GDBusMethodInvocation *invocation;
662 if (params.size() != 5) {
663 _ERR("invalid parameter");
668 object = (SmartcardServiceReader *)params[0];
669 invocation = (GDBusMethodInvocation *)params[1];
670 service_id = (guint)params[2];
671 reader_id = (guint)params[3];
672 user_data = params[4];
674 __process_open_session(object, invocation, service_id,
675 reader_id, user_data);
677 g_object_unref(object);
678 g_object_unref(invocation);
681 static gboolean _handle_open_session(SmartcardServiceReader *object,
682 GDBusMethodInvocation *invocation,
684 guint reader_id, void *user_data)
686 vector<void *> params;
688 /* apply user space smack */
689 if (_is_authorized_request(invocation, "r") == true) {
690 g_object_ref(object);
691 params.push_back((void *)object);
693 g_object_ref(invocation);
694 params.push_back((void *)invocation);
696 params.push_back((void *)service_id);
697 params.push_back((void *)reader_id);
698 params.push_back(user_data);
700 GDBusDispatcher::push(_process_open_session, params);
702 _ERR("access denied");
704 /* response to client */
705 smartcard_service_reader_complete_open_session(object,
707 SCARD_ERROR_SECURITY_NOT_ALLOWED,
708 IntegerHandle::INVALID_HANDLE);
714 bool ServerGDBus::initReader()
716 GError *error = NULL;
718 reader = smartcard_service_reader_skeleton_new();
720 g_signal_connect(reader,
721 "handle-open-session",
722 G_CALLBACK(_handle_open_session),
725 if (g_dbus_interface_skeleton_export(
726 G_DBUS_INTERFACE_SKELETON(reader),
728 "/org/tizen/SmartcardService/Reader",
731 _ERR("Can not skeleton_export %s", error->message);
734 g_object_unref(reader);
743 void ServerGDBus::deinitReader()
745 if (reader != NULL) {
746 g_object_unref(reader);
755 static gboolean __process_close_session(SmartcardServiceSession *object,
756 GDBusMethodInvocation *invocation, guint service_id,
757 guint session_id, void *user_data)
761 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
763 ServerResource &resource = ServerResource::getInstance();
765 name = g_dbus_method_invocation_get_sender(invocation);
767 if (resource.isValidSessionHandle(name, service_id,
769 resource.removeSession(name, service_id,
772 _ERR("invalid parameters");
775 /* response to client */
776 smartcard_service_session_complete_close_session(object,
777 invocation, SCARD_ERROR_OK);
782 static void _process_close_session(vector<void *> ¶ms)
784 SmartcardServiceSession *object;
785 GDBusMethodInvocation *invocation;
790 if (params.size() != 5) {
791 _ERR("invalid parameter");
796 object = (SmartcardServiceSession *)params[0];
797 invocation = (GDBusMethodInvocation *)params[1];
798 service_id = (guint)params[2];
799 session_id = (guint)params[3];
800 user_data = params[4];
802 __process_close_session(object, invocation, service_id,
803 session_id, user_data);
805 g_object_unref(object);
806 g_object_unref(invocation);
809 static gboolean _handle_close_session(SmartcardServiceSession *object,
810 GDBusMethodInvocation *invocation,
812 guint session_id, void *user_data)
814 vector<void *> params;
816 /* apply user space smack */
817 if (_is_authorized_request(invocation, "r") == true) {
818 g_object_ref(object);
819 params.push_back((void *)object);
821 g_object_ref(invocation);
822 params.push_back((void *)invocation);
824 params.push_back((void *)service_id);
825 params.push_back((void *)session_id);
826 params.push_back(user_data);
828 GDBusDispatcher::push(_process_close_session, params);
830 _ERR("access denied");
832 /* response to client */
833 smartcard_service_session_complete_close_session(object,
834 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
840 static gboolean __process_get_atr(SmartcardServiceSession *object,
841 GDBusMethodInvocation *invocation, guint service_id,
842 guint session_id, void *user_data)
846 GVariant *atr = NULL;
848 ServiceInstance *client = NULL;
850 _INFO("[MSG_REQUEST_GET_ATR]");
852 ServerResource &resource = ServerResource::getInstance();
854 name = g_dbus_method_invocation_get_sender(invocation);
856 client = resource.getService(name, service_id);
857 if (client != NULL) {
860 terminal = client->getTerminal(session_id);
861 if (terminal != NULL) {
864 if ((rv = terminal->getATRSync(resp)) == 0) {
865 result = SCARD_ERROR_OK;
867 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
872 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
874 result = SCARD_ERROR_UNAVAILABLE;
877 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
879 result = SCARD_ERROR_UNAVAILABLE;
882 atr = GDBusHelper::convertByteArrayToVariant(resp);
884 /* response to client */
885 smartcard_service_session_complete_get_atr(object, invocation,
891 static void _process_get_atr(vector<void *> ¶ms)
893 SmartcardServiceSession *object;
894 GDBusMethodInvocation *invocation;
899 if (params.size() != 5) {
900 _ERR("invalid parameter");
905 object = (SmartcardServiceSession *)params[0];
906 invocation = (GDBusMethodInvocation *)params[1];
907 service_id = (guint)params[2];
908 session_id = (guint)params[3];
909 user_data = params[4];
911 __process_get_atr(object, invocation, service_id,
912 session_id, user_data);
914 g_object_unref(object);
915 g_object_unref(invocation);
918 static gboolean _handle_get_atr(SmartcardServiceSession *object,
919 GDBusMethodInvocation *invocation,
921 guint session_id, void *user_data)
923 vector<void *> params;
925 /* apply user space smack */
926 if (_is_authorized_request(invocation, "r") == true) {
927 g_object_ref(object);
928 params.push_back((void *)object);
930 g_object_ref(invocation);
931 params.push_back((void *)invocation);
933 params.push_back((void *)service_id);
934 params.push_back((void *)session_id);
935 params.push_back(user_data);
937 GDBusDispatcher::push(_process_get_atr, params);
941 _ERR("access denied");
943 /* response to client */
944 smartcard_service_session_complete_get_atr(
947 SCARD_ERROR_SECURITY_NOT_ALLOWED,
948 GDBusHelper::convertByteArrayToVariant(resp));
954 static gboolean __process_open_channel(SmartcardServiceSession *object,
955 GDBusMethodInvocation *invocation, guint service_id,
956 guint session_id, guint type, GVariant *aid, void *user_data)
958 int result = SCARD_ERROR_UNKNOWN;
960 GVariant *response = NULL;
961 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
964 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
966 ServerResource &resource = ServerResource::getInstance();
968 name = g_dbus_method_invocation_get_sender(invocation);
974 GDBusHelper::convertVariantToByteArray(aid,
977 channelID = resource.createChannel(name,
978 service_id, session_id, type, tempAid);
979 if (channelID != IntegerHandle::INVALID_HANDLE) {
982 temp = (ServerChannel *)resource.getChannel(
983 name, service_id, channelID);
985 resp = temp->getSelectResponse();
987 result = SCARD_ERROR_OK;
990 _ERR("channel is null.");
992 /* set error value */
993 result = SCARD_ERROR_UNAVAILABLE;
996 catch (ExceptionBase &e)
998 result = e.getErrorCode();
1001 response = GDBusHelper::convertByteArrayToVariant(resp);
1003 /* response to client */
1004 smartcard_service_session_complete_open_channel(object,
1005 invocation, result, channelID, response);
1010 static void _process_open_channel(vector<void *> ¶ms)
1012 SmartcardServiceSession *object;
1013 GDBusMethodInvocation *invocation;
1020 if (params.size() != 7) {
1021 _ERR("invalid parameter");
1026 object = (SmartcardServiceSession *)params[0];
1027 invocation = (GDBusMethodInvocation *)params[1];
1028 service_id = (guint)params[2];
1029 session_id = (guint)params[3];
1030 type = (guint)params[4];
1031 aid = (GVariant *)params[5];
1032 user_data = params[6];
1034 __process_open_channel(object, invocation, service_id,
1035 session_id, type, aid, user_data);
1037 g_object_unref(object);
1038 g_object_unref(invocation);
1039 g_object_unref(aid);
1042 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1043 GDBusMethodInvocation *invocation,
1045 guint session_id, guint type, GVariant *aid, void *user_data)
1047 vector<void *> params;
1049 /* apply user space smack */
1050 if (_is_authorized_request(invocation, "rw") == true) {
1051 g_object_ref(object);
1052 params.push_back((void *)object);
1054 g_object_ref(invocation);
1055 params.push_back((void *)invocation);
1057 params.push_back((void *)service_id);
1058 params.push_back((void *)session_id);
1059 params.push_back((void *)type);
1062 params.push_back((void *)aid);
1063 params.push_back(user_data);
1065 GDBusDispatcher::push(_process_open_channel, params);
1069 _ERR("access denied");
1071 /* response to client */
1072 smartcard_service_session_complete_open_channel(object,
1074 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1075 IntegerHandle::INVALID_HANDLE,
1076 GDBusHelper::convertByteArrayToVariant(resp));
1082 bool ServerGDBus::initSession()
1084 GError *error = NULL;
1086 session = smartcard_service_session_skeleton_new();
1088 g_signal_connect(session,
1089 "handle-close-session",
1090 G_CALLBACK(_handle_close_session),
1093 g_signal_connect(session,
1095 G_CALLBACK(_handle_get_atr),
1098 g_signal_connect(session,
1099 "handle-open-channel",
1100 G_CALLBACK(_handle_open_channel),
1103 if (g_dbus_interface_skeleton_export(
1104 G_DBUS_INTERFACE_SKELETON(session),
1106 "/org/tizen/SmartcardService/Session",
1109 _ERR("Can not skeleton_export %s", error->message);
1111 g_error_free(error);
1112 g_object_unref(session);
1121 void ServerGDBus::deinitSession()
1123 if (session != NULL) {
1124 g_object_unref(session);
1133 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1134 GDBusMethodInvocation *invocation, guint service_id,
1135 guint channel_id, void *user_data)
1140 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1142 ServerResource &resource = ServerResource::getInstance();
1144 name = g_dbus_method_invocation_get_sender(invocation);
1146 resource.removeChannel(name, service_id, channel_id);
1148 result = SCARD_ERROR_OK;
1150 /* response to client */
1151 smartcard_service_channel_complete_close_channel(object,
1152 invocation, result);
1157 static void _process_close_channel(vector<void *> ¶ms)
1159 SmartcardServiceChannel *object;
1160 GDBusMethodInvocation *invocation;
1165 if (params.size() != 5) {
1166 _ERR("invalid parameter");
1171 object = (SmartcardServiceChannel *)params[0];
1172 invocation = (GDBusMethodInvocation *)params[1];
1173 service_id = (guint)params[2];
1174 channel_id = (guint)params[3];
1175 user_data = params[4];
1177 __process_close_channel(object, invocation, service_id,
1178 channel_id, user_data);
1180 g_object_unref(object);
1181 g_object_unref(invocation);
1184 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1185 GDBusMethodInvocation *invocation,
1186 guint service_id, guint channel_id, void *user_data)
1188 vector<void *> params;
1190 /* apply user space smack */
1191 if (_is_authorized_request(invocation, "r") == true) {
1192 g_object_ref(object);
1193 params.push_back((void *)object);
1195 g_object_ref(invocation);
1196 params.push_back((void *)invocation);
1198 params.push_back((void *)service_id);
1199 params.push_back((void *)channel_id);
1200 params.push_back(user_data);
1202 GDBusDispatcher::push(_process_close_channel, params);
1204 _ERR("access denied");
1206 /* response to client */
1207 smartcard_service_channel_complete_close_channel(
1210 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1216 static gboolean __process_transmit(SmartcardServiceChannel *object,
1217 GDBusMethodInvocation *invocation,
1224 Channel *channel = NULL;
1226 GVariant *response = NULL;
1229 _INFO("[MSG_REQUEST_TRANSMIT]");
1231 ServerResource &resource = ServerResource::getInstance();
1233 name = g_dbus_method_invocation_get_sender(invocation);
1235 channel = resource.getChannel(name, service_id, channel_id);
1236 if (channel != NULL) {
1240 GDBusHelper::convertVariantToByteArray(command, cmd);
1242 rv = channel->transmitSync(cmd, resp);
1244 result = SCARD_ERROR_OK;
1246 _ERR("transmit failed [%d]", rv);
1251 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1253 result = SCARD_ERROR_UNAVAILABLE;
1256 response = GDBusHelper::convertByteArrayToVariant(resp);
1258 /* response to client */
1259 smartcard_service_channel_complete_transmit(object, invocation,
1265 static void _process_transmit(vector<void *> ¶ms)
1267 SmartcardServiceChannel *object;
1268 GDBusMethodInvocation *invocation;
1274 if (params.size() != 6) {
1275 _ERR("invalid parameter");
1280 object = (SmartcardServiceChannel *)params[0];
1281 invocation = (GDBusMethodInvocation *)params[1];
1282 service_id = (guint)params[2];
1283 channel_id = (guint)params[3];
1284 command = (GVariant *)params[4];
1285 user_data = params[5];
1287 __process_transmit(object, invocation, service_id,
1288 channel_id, command, user_data);
1290 g_object_unref(object);
1291 g_object_unref(invocation);
1292 g_object_unref(command);
1295 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1296 GDBusMethodInvocation *invocation,
1302 vector<void *> params;
1304 /* apply user space smack */
1305 if (_is_authorized_request(invocation, "r") == true) {
1306 /* enqueue message */
1307 g_object_ref(object);
1308 params.push_back((void *)object);
1310 g_object_ref(invocation);
1311 params.push_back((void *)invocation);
1313 params.push_back((void *)service_id);
1314 params.push_back((void *)channel_id);
1316 g_object_ref(command);
1317 params.push_back((void *)command);
1319 params.push_back(user_data);
1321 GDBusDispatcher::push(_process_transmit, params);
1325 _ERR("access denied");
1327 /* response to client */
1328 smartcard_service_channel_complete_transmit(object,
1330 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1331 GDBusHelper::convertByteArrayToVariant(resp));
1337 bool ServerGDBus::initChannel()
1339 GError *error = NULL;
1341 channel = smartcard_service_channel_skeleton_new();
1343 g_signal_connect(channel,
1344 "handle-close-channel",
1345 G_CALLBACK(_handle_close_channel),
1348 g_signal_connect(channel,
1350 G_CALLBACK(_handle_transmit),
1353 if (g_dbus_interface_skeleton_export(
1354 G_DBUS_INTERFACE_SKELETON(channel),
1356 "/org/tizen/SmartcardService/Channel",
1359 _ERR("Can not skeleton_export %s", error->message);
1361 g_error_free(error);
1362 g_object_unref(channel);
1371 void ServerGDBus::deinitChannel()
1373 if (channel != NULL) {
1374 g_object_unref(channel);
1378 } /* namespace smartcard_service_api */