Tizen 2.0 Release
[platform/core/messaging/email-service.git] / email-ipc / email-stub / email-stub-socket.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7
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
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
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.
19 *
20 */
21
22
23
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <malloc.h>
28 #include <sys/epoll.h>
29 #include <pthread.h>
30
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"
37
38 #include "email-debug-log.h"
39
40 #define MAX_EPOLL_EVENT 50
41
42 static int stub_socket = 0;
43 static pthread_t stub_socket_thread = 0;
44 static bool stop_thread = false;
45
46 static void *emipc_stub_socket_thread_proc();
47
48 EXPORT_API bool emipc_start_stub_socket()
49 {
50         bool ret = true;
51
52         ret = emipc_init_email_socket(&stub_socket);
53         if (!ret) {
54                 EM_DEBUG_EXCEPTION("emipc_init_email_socket failed");
55                 return ret;
56         }
57
58         ret = emipc_start_stub_socket_thread();
59         if (!ret) {
60                 EM_DEBUG_EXCEPTION("emipc_start_stub_socket_thread failed");
61                 return ret;
62         }
63
64         ret = emipc_start_task_thread();
65         if (!ret) {
66                 EM_DEBUG_EXCEPTION("emipc_start_task_thread failed");
67                 return ret;
68         }
69
70         return ret;
71 }
72
73 EXPORT_API bool emipc_start_stub_socket_thread()
74 {
75         EM_DEBUG_LOG("[IPCLib] emipc_email_stub_socket_thread start");
76         if (stub_socket_thread)
77                 return true;
78                 
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");
84                 return false;
85         }
86         return true;
87 }
88
89 EXPORT_API bool emipc_stop_stub_socket_thread()
90 {
91         if (stub_socket_thread)
92                 stop_thread = true;
93
94         return true;
95 }
96
97 static void *emipc_stub_socket_thread_proc()
98 {
99         emipc_wait_for_ipc_request();
100         stub_socket_thread = 0;
101         return NULL;
102 }
103
104 EXPORT_API void emipc_wait_for_ipc_request()
105 {
106         struct epoll_event ev = {0};
107         struct epoll_event events[MAX_EPOLL_EVENT] = {{0}, };
108         int epfd = 0;
109         int event_num = 0;
110
111         if (!stub_socket) {
112                 EM_DEBUG_EXCEPTION("Server Socket is not initialized");
113                 return;
114         }
115
116         emipc_open_email_socket(stub_socket, EM_SOCKET_PATH);
117         
118         epfd = epoll_create(MAX_EPOLL_EVENT);
119         if (epfd < 0) {
120                 EM_DEBUG_EXCEPTION("epoll_ctl: %s[%d]", strerror(errno), errno);
121                 EM_DEBUG_CRITICAL_EXCEPTION("epoll_create: %s[%d]", strerror(errno), errno);
122                 abort();
123         }
124
125         ev.events = EPOLLIN;
126         ev.data.fd = stub_socket;
127         
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);        
131         }
132         while (1) {
133                 int i = 0;
134
135                 event_num = epoll_wait(epfd, events, MAX_EPOLL_EVENT, -1);
136                 
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*/
141                         else abort();
142                 } else {
143                         for (i = 0; i < event_num; i++) {
144                                 int event_fd = events[i].data.fd;
145
146                                 if (event_fd == stub_socket) { /*  if it is socket connection request */
147                                         int cfd = emipc_accept_email_socket(stub_socket);
148                                         if (cfd < 0) {
149                                                 EM_DEBUG_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
150                                                 EM_DEBUG_CRITICAL_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
151                                                 /*  abort(); */
152                                         }
153                                         ev.events = EPOLLIN;
154                                         ev.data.fd = cfd;
155                                         epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
156                                 } else {
157                                         int recv_len;
158                                         char *sz_buf = NULL;
159                                         
160                                         recv_len = emipc_recv_email_socket(event_fd, &sz_buf);
161                                         
162                                         if(recv_len > 0) {
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("====================================================================");
166
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);
170                                                 } else
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);
175                                                 close(event_fd);
176                                         } 
177                                         EM_SAFE_FREE(sz_buf);
178                                 }
179                         }
180                 }
181         }       
182 }
183
184 EXPORT_API bool emipc_end_stub_socket()
185 {
186         EM_DEBUG_FUNC_BEGIN();
187         
188         if (stub_socket) {
189                 emipc_close_email_socket(&stub_socket);
190         }
191
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;
196         }
197
198         if (!emipc_stop_task_thread()) {
199                 EM_DEBUG_EXCEPTION("emipc_stop_task_thread failed");
200                 return false;   
201         }
202                 
203         return true;
204 }
205
206 EXPORT_API int emipc_send_stub_socket(int sock_fd, void *data, int len)
207 {
208         EM_DEBUG_FUNC_BEGIN("Stub socket sending %d bytes", len);
209
210         int sending_bytes = emipc_send_email_socket(sock_fd, data, len);
211         
212         EM_DEBUG_FUNC_END("sending_bytes = %d", sending_bytes);
213         return sending_bytes;
214 }
215 /* stub socket accpet, recv, send */
216