2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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 */
22 #include <sys/socket.h>
23 #ifdef USE_UNIX_DOMAIN
26 #else /* USE_UNIX_DOMAIN */
27 #include <netinet/in.h>
28 #endif /* USE_UNIX_DOMAIN */
31 /* SLP library header */
35 #include "IPCHelper.h"
37 #ifdef USE_UNIX_DOMAIN
38 #define OMAPI_SERVER_DOMAIN "/tmp/omapi-server-domain"
39 #endif /* USE_UNIX_DOMAIN */
41 static void setNonBlockSocket(int socket)
45 flags = fcntl(socket, F_GETFL);
49 if (fcntl(socket, F_SETFL, flags) < 0)
51 /* SCARD_DEBUG_ERR("fcntl, executing nonblock error"); */
55 namespace smartcard_service_api
57 IPCHelper::IPCHelper()
62 memset(&ipcLock, 0, sizeof(ipcLock));
66 IPCHelper::~IPCHelper()
70 gboolean IPCHelper::channelCallbackFunc(GIOChannel* channel, GIOCondition condition, gpointer data)
72 IPCHelper *helper = (IPCHelper *)data;
73 gboolean result = FALSE;
75 SCARD_DEBUG("channel [%p], condition [%d], data [%p]", channel, condition, data);
79 SCARD_DEBUG_ERR("ipchelper is null");
83 if ((G_IO_ERR & condition) || (G_IO_HUP & condition))
85 result = helper->handleIOErrorCondition(channel, condition);
87 else if (G_IO_NVAL & condition)
89 result = helper->handleInvalidSocketCondition(channel, condition);
91 else if (G_IO_IN & condition)
93 result = helper->handleIncomingCondition(channel, condition);
99 bool IPCHelper::createListenSocket()
101 GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
102 struct sockaddr_un saddrun_rv;
107 memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
109 unlink(OMAPI_SERVER_DOMAIN);
111 ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
114 SCARD_DEBUG_ERR("get socket is failed");
118 ::setNonBlockSocket(ipcSocket);
120 saddrun_rv.sun_family = AF_UNIX;
121 strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
123 if (bind(ipcSocket, (struct sockaddr *)&saddrun_rv, sizeof(saddrun_rv)) < 0)
125 SCARD_DEBUG_ERR("bind is failed \n");
129 if (chmod(OMAPI_SERVER_DOMAIN, 0777) < 0)
131 SCARD_DEBUG_ERR("can not change permission of UNIX DOMAIN file");
135 if (listen(ipcSocket, IPC_SERVER_MAX_CLIENT) < 0)
137 SCARD_DEBUG_ERR("listen is failed \n");
141 if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
143 if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
145 SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
151 SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
155 #ifdef SECURITY_SERVER
156 gid = security_server_get_gid(NET_NFC_MANAGER_OBJECT);
159 SCARD_DEBUG("get gid from security server is failed. this object is not allowed by security server");
163 if((cookies_size = security_server_get_cookie_size()) != 0)
165 if((cookies = (char *)calloc(1, cookies_size)) == NULL)
172 SCARD_DEBUG("server ipc is initialized");
176 if (watchId != (uint32_t)-1)
178 g_source_remove(watchId);
182 if (ioChannel != NULL)
184 g_io_channel_unref(ioChannel);
190 shutdown(ipcSocket, SHUT_RDWR);
199 bool IPCHelper::createConnectSocket()
201 GIOCondition condition = (GIOCondition) (G_IO_ERR | G_IO_HUP | G_IO_IN);
208 pthread_mutex_lock(&ipcLock);
210 struct sockaddr_un saddrun_rv;
211 socklen_t len_saddr = 0;
213 memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
215 ipcSocket = socket(AF_UNIX, SOCK_STREAM, 0);
218 SCARD_DEBUG_ERR("get socket is failed \n");
219 pthread_mutex_unlock(&ipcLock);
226 SCARD_DEBUG("socket is created");
228 ::setNonBlockSocket(ipcSocket);
230 saddrun_rv.sun_family = AF_UNIX;
231 strncpy(saddrun_rv.sun_path, OMAPI_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
233 len_saddr = sizeof(saddrun_rv.sun_family) + strlen(OMAPI_SERVER_DOMAIN);
235 if ((connect(ipcSocket, (struct sockaddr *)&saddrun_rv, len_saddr)) < 0)
237 SCARD_DEBUG_ERR("error is occured");
238 pthread_mutex_unlock(&ipcLock);
242 pthread_mutex_unlock(&ipcLock);
244 if ((ioChannel = g_io_channel_unix_new(ipcSocket)) != NULL)
246 if ((watchId = g_io_add_watch(ioChannel, condition, &IPCHelper::channelCallbackFunc, this)) < 1)
248 SCARD_DEBUG_ERR(" g_io_add_watch is failed \n");
254 SCARD_DEBUG_ERR(" g_io_channel_unix_new is failed \n");
258 SCARD_DEBUG("socket and g io channel is binded");
265 SCARD_DEBUG_ERR("error while initializing client ipc");
269 g_source_remove(watchId);
273 if(ioChannel != NULL)
275 g_io_channel_unref(ioChannel);
281 shutdown(ipcSocket, SHUT_RDWR);
291 bool IPCHelper::sendMessage(Message *msg)
296 return sendMessage(ipcSocket, msg);
299 bool IPCHelper::sendMessage(int socket, Message *msg)
303 unsigned int length = 0;
305 stream = msg->serialize();
306 length = stream.getLength();
308 SCARD_DEBUG(">>>[SEND]>>> socket [%d], msg [%d], length [%d]", socket, msg->message, length);
314 /* send 4 bytes (length) */
315 pthread_mutex_lock(&ipcLock);
316 sentBytes = send(socket, &length, sizeof(length), 0);
317 pthread_mutex_unlock(&ipcLock);
318 if (sentBytes == sizeof(length))
320 unsigned int current = 0;
323 pthread_mutex_lock(&ipcLock);
326 sentBytes = send(socket, stream.getBuffer(current), length - current, 0);
328 current += sentBytes;
330 while (current < length);
331 pthread_mutex_unlock(&ipcLock);
337 SCARD_DEBUG_ERR("send failed, sentBytes [%d]", sentBytes);
342 SCARD_DEBUG_ERR("stream length is zero");
348 Message *IPCHelper::retrieveMessage()
350 return retrieveMessage(ipcSocket);
353 Message *IPCHelper::retrieveMessage(int socket)
356 unsigned int length = 0;
361 /* read 4 bytes (length) */
362 pthread_mutex_lock(&ipcLock);
363 readBytes = recv(socket, &length, sizeof(length), 0);
364 pthread_mutex_unlock(&ipcLock);
365 if (readBytes == sizeof(length))
369 unsigned char *buffer = NULL;
372 buffer = new unsigned char[length];
376 unsigned int current = 0;
379 pthread_mutex_lock(&ipcLock);
382 readBytes = recv(socket, buffer + current, length - current, 0);
384 current += readBytes;
387 while (current < length);
388 pthread_mutex_unlock(&ipcLock);
393 msg->deserialize(buffer, length);
395 SCARD_DEBUG("<<<[RETRIEVE]<<< socket [%d], msg_length [%d]", socket, length);
399 SCARD_DEBUG_ERR("alloc failed");
406 SCARD_DEBUG_ERR("allocation failed");
411 SCARD_DEBUG_ERR("invalid length, socket = [%d], msg_length = [%d]", socket, length);
416 SCARD_DEBUG_ERR("failed to recv length, socket = [%d], readBytes [%d]", socket, readBytes);
425 void IPCHelper::setDispatcher(DispatcherHelper *dispatcher)
427 this->dispatcher = dispatcher;
430 } /* namespace smartcard_service_api */