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>
25 /* SLP library header */
26 #ifdef USER_SPACE_SMACK
27 #include "security-server.h"
31 #include "smartcard-types.h"
33 #include "ByteArray.h"
34 #include "ServerResource.h"
35 #include "GDBusHelper.h"
36 #include "ServerGDBus.h"
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);
240 void ServerGDBus::deinit()
249 if (connection != NULL) {
250 g_object_unref(connection);
255 static gboolean _call_get_connection_unix_process_id_sync(
256 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
257 GCancellable *cancellable, GError **error) {
260 _ret = g_dbus_proxy_call_sync(proxy,
261 "GetConnectionUnixProcessID",
262 g_variant_new("(s)", arg_name),
263 G_DBUS_CALL_FLAGS_NONE,
264 -1, cancellable, error);
266 g_variant_get(_ret, "(u)", out_pid);
267 g_variant_unref(_ret);
273 pid_t ServerGDBus::getPID(const char *name)
276 GError *error = NULL;
278 if (_call_get_connection_unix_process_id_sync(
279 (GDBusProxy *)dbus_proxy, name,
280 &pid, NULL, &error) == true) {
282 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
289 static bool _is_authorized_request(GDBusMethodInvocation *invocation,
293 #ifdef USER_SPACE_SMACK
296 ClientInstance *instance;
298 name = g_dbus_method_invocation_get_sender(invocation);
300 instance = ServerResource::getInstance().getClient(name);
301 if (instance != NULL) {
302 pid = instance->getPID();
304 pid = ServerGDBus::getInstance().getPID(name);
307 result = (security_server_check_privilege_by_pid(
310 rights) == SECURITY_SERVER_API_SUCCESS);
319 static GVariant *_reader_to_variant(
320 vector<pair<unsigned int, string> > &readers)
322 GVariantBuilder builder;
325 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
327 for (i = 0; i < readers.size(); i++) {
328 g_variant_builder_add(&builder, "(us)",
329 readers[i].first, readers[i].second.c_str());
332 return g_variant_builder_end(&builder);
335 static gboolean __process_se_service(SmartcardServiceSeService *object,
336 GDBusMethodInvocation *invocation,
339 gint result = SCARD_ERROR_OK;
340 GVariant *readers = NULL;
341 vector<pair<unsigned int, string> > list;
342 unsigned int handle = IntegerHandle::INVALID_HANDLE;
346 _INFO("[MSG_REQUEST_READERS]");
348 ServerResource &resource = ServerResource::getInstance();
350 name = g_dbus_method_invocation_get_sender(invocation);
352 /* load secure elements */
353 resource.loadSecureElements();
355 pid = ServerGDBus::getInstance().getPID(name);
357 _DBG("service requested, pid [%d]", pid);
360 ClientInstance *instance;
362 instance = resource.getClient(name);
363 if (instance == NULL) {
364 _INFO("create client instance, pid [%d]", pid);
366 resource.createClient(name, pid);
368 instance = resource.getClient(name);
369 if (instance != NULL) {
370 /* generate certification hashes */
371 instance->generateCertificationHashes();
373 _ERR("createClient failed");
377 if (instance != NULL) {
378 ServiceInstance *service;
381 service = resource.createService(name);
382 if (service != NULL) {
384 handle = service->getHandle();
385 resource.getReaders(list);
387 if (list.size() == 0) {
388 _INFO("no secure elements");
391 _ERR("createService failed");
393 result = SCARD_ERROR_OUT_OF_MEMORY;
396 _ERR("client doesn't exist, pid [%d]", pid);
398 result = SCARD_ERROR_OUT_OF_MEMORY;
401 _ERR("invalid pid, [%d]", pid);
403 result = SCARD_ERROR_IPC_FAILED;
406 readers = _reader_to_variant(list);
408 /* response to client */
409 smartcard_service_se_service_complete_se_service(object,
410 invocation, result, handle, readers);
415 static void _process_se_service(vector<void *> ¶ms)
417 SmartcardServiceSeService *object;
418 GDBusMethodInvocation *invocation;
421 if (params.size() != 3) {
422 _ERR("invalid parameter");
427 object = (SmartcardServiceSeService *)params[0];
428 invocation = (GDBusMethodInvocation *)params[1];
429 user_data = params[2];
431 __process_se_service(object, invocation, user_data);
433 g_object_unref(object);
434 g_object_unref(invocation);
437 static gboolean _handle_se_service(SmartcardServiceSeService *object,
438 GDBusMethodInvocation *invocation,
441 vector<void *> params;
443 /* apply user space smack */
444 if (_is_authorized_request(invocation, "r") == true) {
445 g_object_ref(object);
446 params.push_back((void *)object);
448 g_object_ref(invocation);
449 params.push_back((void *)invocation);
451 params.push_back((void *)user_data);
453 GDBusDispatcher::push(_process_se_service, params);
455 vector<pair<unsigned int, string> > list;
457 _ERR("access denied");
459 /* response to client */
460 smartcard_service_se_service_complete_se_service(object,
462 SCARD_ERROR_SECURITY_NOT_ALLOWED,
463 IntegerHandle::INVALID_HANDLE,
464 _reader_to_variant(list));
470 static gboolean __process_shutdown(SmartcardServiceSeService *object,
471 GDBusMethodInvocation *invocation,
472 guint handle, void *user_data)
476 _INFO("[MSG_REQUEST_SHUTDOWN]");
478 ServerResource &resource = ServerResource::getInstance();
480 name = g_dbus_method_invocation_get_sender(invocation);
482 resource.removeService(name, handle);
484 /* response to client */
485 smartcard_service_se_service_complete_shutdown(object,
486 invocation, SCARD_ERROR_OK);
494 static void _process_shutdown(vector<void *> ¶ms)
496 SmartcardServiceSeService *object;
497 GDBusMethodInvocation *invocation;
501 if (params.size() != 4) {
502 _ERR("invalid parameter");
507 object = (SmartcardServiceSeService *)params[0];
508 invocation = (GDBusMethodInvocation *)params[1];
509 handle = (guint)params[2];
510 user_data = params[3];
512 __process_shutdown(object, invocation, handle, user_data);
514 g_object_unref(object);
515 g_object_unref(invocation);
518 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
519 GDBusMethodInvocation *invocation,
523 vector<void *> params;
525 /* apply user space smack */
526 if (_is_authorized_request(invocation, "r") == true) {
527 g_object_ref(object);
528 params.push_back((void *)object);
530 g_object_ref(invocation);
531 params.push_back((void *)invocation);
533 params.push_back((void *)handle);
534 params.push_back(user_data);
536 GDBusDispatcher::push(_process_shutdown, params);
538 _ERR("access denied");
540 /* response to client */
541 smartcard_service_se_service_complete_shutdown(object,
542 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
548 bool ServerGDBus::initSEService()
550 GError *error = NULL;
552 seService = smartcard_service_se_service_skeleton_new();
554 g_signal_connect(seService,
556 G_CALLBACK(_handle_se_service),
559 g_signal_connect(seService,
561 G_CALLBACK(_handle_shutdown),
564 if (g_dbus_interface_skeleton_export(
565 G_DBUS_INTERFACE_SKELETON(seService),
567 "/org/tizen/SmartcardService/SeService",
570 _ERR("Can not skeleton_export %s", error->message);
573 g_object_unref(seService);
582 void ServerGDBus::deinitSEService()
584 if (seService != NULL) {
585 g_object_unref(seService);
590 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
591 const char *reader_name)
593 smartcard_service_se_service_emit_reader_inserted(
594 SMARTCARD_SERVICE_SE_SERVICE(seService),
595 reader_id, reader_name);
598 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
599 const char *reader_name)
601 smartcard_service_se_service_emit_reader_removed(
602 SMARTCARD_SERVICE_SE_SERVICE(seService),
603 reader_id, reader_name);
610 static gboolean __process_open_session(SmartcardServiceReader *object,
611 GDBusMethodInvocation *invocation, guint service_id,
612 guint reader_id, void *user_data)
614 unsigned int handle = IntegerHandle::INVALID_HANDLE;
618 _INFO("[MSG_REQUEST_OPEN_SESSION]");
620 ServerResource &resource = ServerResource::getInstance();
622 name = g_dbus_method_invocation_get_sender(invocation);
624 if (resource.isValidReaderHandle(reader_id)) {
625 vector<ByteArray> temp;
627 handle = resource.createSession(name,
632 if (handle != IntegerHandle::INVALID_HANDLE) {
633 result = SCARD_ERROR_OK;
635 _ERR("createSession failed [%d]", handle);
637 result = SCARD_ERROR_OUT_OF_MEMORY;
640 _ERR("request invalid reader handle [%d]", reader_id);
642 result = SCARD_ERROR_ILLEGAL_PARAM;
645 /* response to client */
646 smartcard_service_reader_complete_open_session(object,
647 invocation, result, handle);
652 static void _process_open_session(vector<void *> ¶ms)
654 SmartcardServiceReader *object;
655 GDBusMethodInvocation *invocation;
660 if (params.size() != 5) {
661 _ERR("invalid parameter");
666 object = (SmartcardServiceReader *)params[0];
667 invocation = (GDBusMethodInvocation *)params[1];
668 service_id = (guint)params[2];
669 reader_id = (guint)params[3];
670 user_data = params[4];
672 __process_open_session(object, invocation, service_id,
673 reader_id, user_data);
675 g_object_unref(object);
676 g_object_unref(invocation);
679 static gboolean _handle_open_session(SmartcardServiceReader *object,
680 GDBusMethodInvocation *invocation,
682 guint reader_id, void *user_data)
684 vector<void *> params;
686 /* apply user space smack */
687 if (_is_authorized_request(invocation, "r") == true) {
688 g_object_ref(object);
689 params.push_back((void *)object);
691 g_object_ref(invocation);
692 params.push_back((void *)invocation);
694 params.push_back((void *)service_id);
695 params.push_back((void *)reader_id);
696 params.push_back(user_data);
698 GDBusDispatcher::push(_process_open_session, params);
700 _ERR("access denied");
702 /* response to client */
703 smartcard_service_reader_complete_open_session(object,
705 SCARD_ERROR_SECURITY_NOT_ALLOWED,
706 IntegerHandle::INVALID_HANDLE);
712 bool ServerGDBus::initReader()
714 GError *error = NULL;
716 reader = smartcard_service_reader_skeleton_new();
718 g_signal_connect(reader,
719 "handle-open-session",
720 G_CALLBACK(_handle_open_session),
723 if (g_dbus_interface_skeleton_export(
724 G_DBUS_INTERFACE_SKELETON(reader),
726 "/org/tizen/SmartcardService/Reader",
729 _ERR("Can not skeleton_export %s", error->message);
732 g_object_unref(reader);
741 void ServerGDBus::deinitReader()
743 if (reader != NULL) {
744 g_object_unref(reader);
753 static gboolean __process_close_session(SmartcardServiceSession *object,
754 GDBusMethodInvocation *invocation, guint service_id,
755 guint session_id, void *user_data)
759 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
761 ServerResource &resource = ServerResource::getInstance();
763 name = g_dbus_method_invocation_get_sender(invocation);
765 if (resource.isValidSessionHandle(name, service_id,
767 resource.removeSession(name, service_id,
770 _ERR("invalid parameters");
773 /* response to client */
774 smartcard_service_session_complete_close_session(object,
775 invocation, SCARD_ERROR_OK);
780 static void _process_close_session(vector<void *> ¶ms)
782 SmartcardServiceSession *object;
783 GDBusMethodInvocation *invocation;
788 if (params.size() != 5) {
789 _ERR("invalid parameter");
794 object = (SmartcardServiceSession *)params[0];
795 invocation = (GDBusMethodInvocation *)params[1];
796 service_id = (guint)params[2];
797 session_id = (guint)params[3];
798 user_data = params[4];
800 __process_close_session(object, invocation, service_id,
801 session_id, user_data);
803 g_object_unref(object);
804 g_object_unref(invocation);
807 static gboolean _handle_close_session(SmartcardServiceSession *object,
808 GDBusMethodInvocation *invocation,
810 guint session_id, void *user_data)
812 vector<void *> params;
814 /* apply user space smack */
815 if (_is_authorized_request(invocation, "r") == true) {
816 g_object_ref(object);
817 params.push_back((void *)object);
819 g_object_ref(invocation);
820 params.push_back((void *)invocation);
822 params.push_back((void *)service_id);
823 params.push_back((void *)session_id);
824 params.push_back(user_data);
826 GDBusDispatcher::push(_process_close_session, params);
828 _ERR("access denied");
830 /* response to client */
831 smartcard_service_session_complete_close_session(object,
832 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
838 static gboolean __process_get_atr(SmartcardServiceSession *object,
839 GDBusMethodInvocation *invocation, guint service_id,
840 guint session_id, void *user_data)
844 GVariant *atr = NULL;
846 ServiceInstance *client = NULL;
848 _INFO("[MSG_REQUEST_GET_ATR]");
850 ServerResource &resource = ServerResource::getInstance();
852 name = g_dbus_method_invocation_get_sender(invocation);
854 client = resource.getService(name, service_id);
855 if (client != NULL) {
858 terminal = client->getTerminal(session_id);
859 if (terminal != NULL) {
862 if ((rv = terminal->getATRSync(resp)) == 0) {
863 result = SCARD_ERROR_OK;
865 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
870 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
872 result = SCARD_ERROR_UNAVAILABLE;
875 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
877 result = SCARD_ERROR_UNAVAILABLE;
880 atr = GDBusHelper::convertByteArrayToVariant(resp);
882 /* response to client */
883 smartcard_service_session_complete_get_atr(object, invocation,
889 static void _process_get_atr(vector<void *> ¶ms)
891 SmartcardServiceSession *object;
892 GDBusMethodInvocation *invocation;
897 if (params.size() != 5) {
898 _ERR("invalid parameter");
903 object = (SmartcardServiceSession *)params[0];
904 invocation = (GDBusMethodInvocation *)params[1];
905 service_id = (guint)params[2];
906 session_id = (guint)params[3];
907 user_data = params[4];
909 __process_get_atr(object, invocation, service_id,
910 session_id, user_data);
912 g_object_unref(object);
913 g_object_unref(invocation);
916 static gboolean _handle_get_atr(SmartcardServiceSession *object,
917 GDBusMethodInvocation *invocation,
919 guint session_id, void *user_data)
921 vector<void *> params;
923 /* apply user space smack */
924 if (_is_authorized_request(invocation, "r") == true) {
925 g_object_ref(object);
926 params.push_back((void *)object);
928 g_object_ref(invocation);
929 params.push_back((void *)invocation);
931 params.push_back((void *)service_id);
932 params.push_back((void *)session_id);
933 params.push_back(user_data);
935 GDBusDispatcher::push(_process_get_atr, params);
939 _ERR("access denied");
941 /* response to client */
942 smartcard_service_session_complete_get_atr(
945 SCARD_ERROR_SECURITY_NOT_ALLOWED,
946 GDBusHelper::convertByteArrayToVariant(resp));
952 static gboolean __process_open_channel(SmartcardServiceSession *object,
953 GDBusMethodInvocation *invocation, guint service_id,
954 guint session_id, guint type, GVariant *aid, void *user_data)
956 int result = SCARD_ERROR_UNKNOWN;
958 GVariant *response = NULL;
959 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
962 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
964 ServerResource &resource = ServerResource::getInstance();
966 name = g_dbus_method_invocation_get_sender(invocation);
972 GDBusHelper::convertVariantToByteArray(aid,
975 channelID = resource.createChannel(name,
976 service_id, session_id, type, tempAid);
977 if (channelID != IntegerHandle::INVALID_HANDLE) {
980 temp = (ServerChannel *)resource.getChannel(
981 name, service_id, channelID);
983 resp = temp->getSelectResponse();
985 result = SCARD_ERROR_OK;
988 _ERR("channel is null.");
990 /* set error value */
991 result = SCARD_ERROR_UNAVAILABLE;
994 catch (ExceptionBase &e)
996 result = e.getErrorCode();
999 response = GDBusHelper::convertByteArrayToVariant(resp);
1001 /* response to client */
1002 smartcard_service_session_complete_open_channel(object,
1003 invocation, result, channelID, response);
1008 static void _process_open_channel(vector<void *> ¶ms)
1010 SmartcardServiceSession *object;
1011 GDBusMethodInvocation *invocation;
1018 if (params.size() != 7) {
1019 _ERR("invalid parameter");
1024 object = (SmartcardServiceSession *)params[0];
1025 invocation = (GDBusMethodInvocation *)params[1];
1026 service_id = (guint)params[2];
1027 session_id = (guint)params[3];
1028 type = (guint)params[4];
1029 aid = (GVariant *)params[5];
1030 user_data = params[6];
1032 __process_open_channel(object, invocation, service_id,
1033 session_id, type, aid, user_data);
1035 g_object_unref(object);
1036 g_object_unref(invocation);
1037 g_object_unref(aid);
1040 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1041 GDBusMethodInvocation *invocation,
1043 guint session_id, guint type, GVariant *aid, void *user_data)
1045 vector<void *> params;
1047 /* apply user space smack */
1048 if (_is_authorized_request(invocation, "rw") == true) {
1049 g_object_ref(object);
1050 params.push_back((void *)object);
1052 g_object_ref(invocation);
1053 params.push_back((void *)invocation);
1055 params.push_back((void *)service_id);
1056 params.push_back((void *)session_id);
1057 params.push_back((void *)type);
1060 params.push_back((void *)aid);
1061 params.push_back(user_data);
1063 GDBusDispatcher::push(_process_open_channel, params);
1067 _ERR("access denied");
1069 /* response to client */
1070 smartcard_service_session_complete_open_channel(object,
1072 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1073 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 = (guint)params[2];
1172 channel_id = (guint)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 = (guint)params[2];
1281 channel_id = (guint)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 */