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 */
19 #include <sys/socket.h>
22 /* SLP library header */
23 #ifdef SECURITY_SERVER
24 #include "security-server.h"
29 #include "ServerIPC.h"
30 #include "ServerResource.h"
31 #include "ServerDispatcher.h"
34 #define EXTERN_API __attribute__((visibility("default")))
37 namespace smartcard_service_api
39 ServerIPC::ServerIPC():IPCHelper()
43 setDispatcher(ServerDispatcher::getInstance());
48 ServerIPC::~ServerIPC()
52 ServerIPC *ServerIPC::getInstance()
54 static ServerIPC instance;
59 Message *ServerIPC::retrieveMessage(int socket)
66 buffer = IPCHelper::retrieveBuffer(socket);
67 if (buffer.getLength() > 0)
69 #ifdef SECURITY_SERVER
73 if (buffer.getLength() < 20)
76 cookie.setBuffer(buffer.getBuffer(), 20);
78 gid = security_server_get_gid("smartcard-daemon");
79 if ((result = security_server_check_privilege(cookie.getBuffer(), gid)) != SECURITY_SERVER_API_SUCCESS)
81 SCARD_DEBUG_ERR("security_server_check_privilege failed [%d]", result);
88 msg->deserialize(buffer);
92 SCARD_DEBUG_ERR("alloc failed");
97 SCARD_DEBUG_ERR("retrieveBuffer failed ");
105 bool ServerIPC::acceptClient()
107 GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
108 socklen_t addrlen = 0;
109 int client_sock_fd = 0;
110 GIOChannel *client_channel = NULL;
113 SCARD_DEBUG("client is trying to connect to server");
115 pthread_mutex_lock(&ipcLock);
116 client_sock_fd = accept(ipcSocket, NULL, &addrlen);
117 pthread_mutex_unlock(&ipcLock);
119 if (client_sock_fd < 0)
121 SCARD_DEBUG_ERR("can not accept client");
125 SCARD_DEBUG("client is accepted by server");
127 if ((client_channel = g_io_channel_unix_new(client_sock_fd)) == NULL)
129 SCARD_DEBUG_ERR("create new g io channel is failed");
133 if ((client_src_id = g_io_add_watch(client_channel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
135 SCARD_DEBUG_ERR("add io callback is failed");
139 SCARD_DEBUG("client socket is bond with g_io_channel");
141 if (ServerResource::getInstance().createClient(client_channel, client_sock_fd, client_src_id, 0, -1) == false)
143 SCARD_DEBUG_ERR("failed to add client");
149 if (client_channel != NULL)
151 g_io_channel_unref(client_channel);
154 if (client_sock_fd != -1)
156 shutdown(client_sock_fd, SHUT_RDWR);
157 close(client_sock_fd);
163 void ServerIPC::restartServerIPC()
165 destroyListenSocket();
167 createListenSocket();
170 void ServerIPC::releaseClient(void *channel, int socket, int watchID)
174 g_source_remove(watchID);
179 g_io_channel_unref((GIOChannel *)channel);
184 shutdown(socket, SHUT_RDWR);
189 int ServerIPC::handleIOErrorCondition(void *channel, GIOCondition condition)
193 if(channel == ioChannel)
195 SCARD_DEBUG("server socket is closed");
200 DispatcherMsg dispMsg;
201 int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
203 SCARD_DEBUG("client socket is closed, socket [%d]", peerSocket);
205 /* push messsage to dispatcher */
206 dispMsg.message = Message::MSG_OPERATION_RELEASE_CLIENT;
207 dispMsg.param1 = peerSocket;
208 dispMsg.setPeerSocket(peerSocket);
210 /* push to dispatcher */
211 ServerDispatcher::getInstance()->pushMessage(&dispMsg);
219 int ServerIPC::handleInvalidSocketCondition(void *channel, GIOCondition condition)
227 int ServerIPC::handleIncomingCondition(void *channel, GIOCondition condition)
233 if(channel == ioChannel)
235 /* connect state. should accept */
236 SCARD_DEBUG("new client connected");
238 result = acceptClient();
242 int peerSocket = g_io_channel_unix_get_fd((GIOChannel *)channel);
244 SCARD_DEBUG("data incomming from [%d]", peerSocket);
251 if ((msg = retrieveMessage(peerSocket)) != NULL)
253 DispatcherMsg dispMsg(msg, peerSocket);
255 /* push to dispatcher */
256 ServerDispatcher::getInstance()->pushMessage(&dispMsg);
264 /* clear client connection */
265 SCARD_DEBUG_ERR("retrieve message failed, socket [%d]", peerSocket);
270 SCARD_DEBUG_ERR("client context doesn't exist, socket [%d]", peerSocket);
279 } /* namespace smartcard_service_api */
281 using namespace smartcard_service_api;
283 EXTERN_API void server_ipc_create_listen_socket()
285 ServerIPC *ipc = ServerIPC::getInstance();
287 ipc->createListenSocket();