4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
28 #include <sys/epoll.h>
31 #include "email-ipc-build.h"
32 #include "email-ipc-api-info.h"
33 #include "email-ipc-socket.h"
34 #include "email-stub-task.h"
35 #include "email-stub-task-manager.h"
36 #include "email-stub-socket.h"
38 #include "email-debug-log.h"
40 #define MAX_EPOLL_EVENT 50
42 static int stub_socket = 0;
43 static pthread_t stub_socket_thread = 0;
44 static bool stop_thread = false;
46 static void *emipc_stub_socket_thread_proc();
48 EXPORT_API bool emipc_start_stub_socket()
52 ret = emipc_init_email_socket(&stub_socket);
54 EM_DEBUG_EXCEPTION("emipc_init_email_socket failed");
58 ret = emipc_start_stub_socket_thread();
60 EM_DEBUG_EXCEPTION("emipc_start_stub_socket_thread failed");
64 ret = emipc_start_task_thread();
66 EM_DEBUG_EXCEPTION("emipc_start_task_thread failed");
73 EXPORT_API bool emipc_start_stub_socket_thread()
75 EM_DEBUG_LOG("[IPCLib] emipc_email_stub_socket_thread start");
76 if (stub_socket_thread)
79 pthread_attr_t thread_attr;
80 pthread_attr_init(&thread_attr);
81 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
82 if (pthread_create(&stub_socket_thread, &thread_attr, &emipc_stub_socket_thread_proc, NULL) != 0) {
83 EM_DEBUG_EXCEPTION("[IPCLib] emipc_start_stub_socket_thread() - fail to create a thread");
89 EXPORT_API bool emipc_stop_stub_socket_thread()
91 if (stub_socket_thread)
97 static void *emipc_stub_socket_thread_proc()
99 emipc_wait_for_ipc_request();
100 stub_socket_thread = 0;
104 EXPORT_API void emipc_wait_for_ipc_request()
106 struct epoll_event ev = {0};
107 struct epoll_event events[MAX_EPOLL_EVENT] = {{0}, };
112 EM_DEBUG_EXCEPTION("Server Socket is not initialized");
116 emipc_open_email_socket(stub_socket, EM_SOCKET_PATH);
118 epfd = epoll_create(MAX_EPOLL_EVENT);
120 EM_DEBUG_EXCEPTION("epoll_ctl: %s[%d]", strerror(errno), errno);
121 EM_DEBUG_CRITICAL_EXCEPTION("epoll_create: %s[%d]", strerror(errno), errno);
126 ev.data.fd = stub_socket;
128 if (epoll_ctl(epfd, EPOLL_CTL_ADD, stub_socket, &ev) == -1) {
129 EM_DEBUG_EXCEPTION("epoll_ctl: %s[%d]", strerror(errno), errno);
130 EM_DEBUG_CRITICAL_EXCEPTION("epoll_ctl:%s[%d]", strerror(errno), errno);
135 event_num = epoll_wait(epfd, events, MAX_EPOLL_EVENT, -1);
137 if (event_num == -1) {
138 EM_DEBUG_EXCEPTION("epoll_wait: %s[%d]", strerror(errno), errno);
139 EM_DEBUG_CRITICAL_EXCEPTION("epoll_wait: %s[%d]", strerror(errno), errno);
140 if (errno == EINTR) continue; /* resume when interrupted system call*/
143 for (i = 0; i < event_num; i++) {
144 int event_fd = events[i].data.fd;
146 if (event_fd == stub_socket) { /* if it is socket connection request */
147 int cfd = emipc_accept_email_socket(stub_socket);
149 EM_DEBUG_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
150 EM_DEBUG_CRITICAL_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
155 epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
160 recv_len = emipc_recv_email_socket(event_fd, &sz_buf);
163 EM_DEBUG_LOG("====================================================================");
164 EM_DEBUG_LOG("[IPCLib]Stub Socket Recv [Socket ID = %d], [recv_len = %d]", event_fd, recv_len);
165 EM_DEBUG_LOG("====================================================================");
167 /* IPC request stream is at least 16byte */
168 if (recv_len >= sizeof(long) * eSTREAM_DATA) {
169 emipc_create_task((unsigned char *)sz_buf, event_fd);
171 EM_DEBUG_LOG("[IPCLib] Stream size is less than default size");
172 } else if( recv_len == 0 ) {
173 EM_DEBUG_LOG("[IPCLib] Client closed connection [%d]", event_fd);
174 epoll_ctl(epfd, EPOLL_CTL_DEL, event_fd, events);
177 EM_SAFE_FREE(sz_buf);
184 EXPORT_API bool emipc_end_stub_socket()
186 EM_DEBUG_FUNC_BEGIN();
189 emipc_close_email_socket(&stub_socket);
192 if (stub_socket_thread) {
193 emipc_stop_stub_socket_thread(stub_socket_thread);
194 pthread_cancel(stub_socket_thread);
195 stub_socket_thread = 0;
198 if (!emipc_stop_task_thread()) {
199 EM_DEBUG_EXCEPTION("emipc_stop_task_thread failed");
206 EXPORT_API int emipc_send_stub_socket(int sock_fd, void *data, int len)
208 EM_DEBUG_FUNC_BEGIN("Stub socket sending %d bytes", len);
210 int sending_bytes = emipc_send_email_socket(sock_fd, data, len);
212 EM_DEBUG_FUNC_END("sending_bytes = %d", sending_bytes);
213 return sending_bytes;
215 /* stub socket accpet, recv, send */