4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
16 * http://www.apache.org/licenses/LICENSE-2.0
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
29 #include <stdio.h> // for fopen, fprintf
30 #include <stdlib.h> // for atexit
31 #include <sys/types.h> // for open
32 #include <sys/stat.h> // for open
33 #include <sys/socket.h> // for socket
34 #include <sys/un.h> // for sockaddr_un
35 #include <arpa/inet.h> // for sockaddr_in, socklen_t
37 #include <signal.h> // for signal
38 #include <unistd.h> // for unlink
39 #include <fcntl.h> // for open, fcntl
41 #include <attr/xattr.h> // for fsetxattr
44 #include "da_protocol.h"
49 #define SINGLETON_LOCKFILE "/tmp/lockfile.da"
50 #define PORTFILE "/tmp/port.da"
51 #define UDS_NAME "/tmp/da.socket"
53 #define INIT_PORT 8001
54 #define LIMIT_PORT 8100
57 // initialize global variable
58 __da_manager manager =
60 // TODO: rewrite this with . notation
61 NULL, -1, -1, // portfile pointer, host / target server socket
64 -1, // app launch timerfd
65 -1, // sampling_thread handle
67 -1, // transfer_thread
70 {-1, -1, PTHREAD_MUTEX_INITIALIZER}, // host
75 // ==============================================================================
77 // ==============================================================================
79 static void writeToPortfile(int code)
81 if(unlikely(manager.portfile == 0))
84 fprintf(manager.portfile, "%d", code);
87 // ==============================================================================
89 // ==============================================================================
91 void _close_server_socket(void)
93 LOGI("close_server_socket\n");
94 // close server socket
95 if(manager.host_server_socket != -1)
96 close(manager.host_server_socket);
97 if(manager.target_server_socket != -1)
98 close(manager.target_server_socket);
101 static void _unlink_file(void)
103 LOGI("unlink files\n");
105 unlink(SINGLETON_LOCKFILE);
108 void unlink_portfile(void)
113 // ===============================================================================
115 // ===============================================================================
117 // return 0 for normal case
118 static int makeTargetServerSocket()
120 struct sockaddr_un serverAddrUn;
122 if(manager.target_server_socket != -1)
123 return -1; // should be never happend
125 // remove existed unix domain socket file
128 if ((manager.target_server_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
130 LOGE("Target server socket creation failed\n");
135 // set smack attribute for certification
136 fsetxattr(manager.target_server_socket, "security.SMACK64IPIN", "*", 1, 0);
137 fsetxattr(manager.target_server_socket, "security.SMACK64IPOUT", "*", 1, 0);
138 #endif /* LOCALTEST */
140 bzero(&serverAddrUn, sizeof(serverAddrUn));
141 serverAddrUn.sun_family = AF_UNIX;
142 sprintf(serverAddrUn.sun_path, "%s", UDS_NAME);
144 if (-1 == bind(manager.target_server_socket, (struct sockaddr*) &serverAddrUn,
145 sizeof(serverAddrUn)))
147 LOGE("Target server socket binding failed\n");
151 chmod(serverAddrUn.sun_path, 0777);
153 if (-1 == listen(manager.target_server_socket, 5))
155 LOGE("Target server socket listening failed\n");
159 LOGI("Created TargetSock %d\n", manager.target_server_socket);
163 // return port number for normal case
164 // return negative value for error case
165 static int makeHostServerSocket()
167 struct sockaddr_in serverAddrIn;
171 if(manager.host_server_socket != -1)
172 return -1; // should be never happened
174 if ((manager.host_server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
176 LOGE("Host server socket creation failed\n");
180 setsockopt(manager.host_server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
181 memset(&serverAddrIn, 0, sizeof(serverAddrIn));
182 serverAddrIn.sin_family = AF_INET;
183 serverAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);
185 // bind address to server socket
186 for(port = INIT_PORT; port < LIMIT_PORT; port++)
188 serverAddrIn.sin_port = htons(port);
189 if (0 == bind(manager.host_server_socket, (struct sockaddr*) &serverAddrIn, sizeof(serverAddrIn)))
193 if(port == LIMIT_PORT)
195 LOGE("Host server socket binding failed\n");
199 // enter listen state from client
200 if (-1 == listen(manager.host_server_socket, 5))
202 LOGE("Host server socket listening failed\n");
206 LOGI("Created HostSock %d\n", manager.host_server_socket);
210 // ===============================================================================
211 // initializing / finalizing functions
212 // ===============================================================================
214 static int singleton(void)
219 fd = open(SINGLETON_LOCKFILE, O_RDWR | O_CREAT, 0600);
222 writeToPortfile(ERR_LOCKFILE_CREATE_FAILED);
223 LOGE("singleton lock file creation failed");
230 fl.l_whence = SEEK_SET;
231 if(fcntl(fd, F_SETLK, &fl) < 0)
233 writeToPortfile(ERR_ALREADY_RUNNING);
234 LOGE("another instance of daemon is already running");
243 // return 0 for normal case
244 static int initializeManager()
249 if (init_buf() != 0) {
250 LOGE("Cannot init buffer\n");
254 atexit(_close_server_socket);
255 if(initialize_system_info() < 0)
257 writeToPortfile(ERR_INITIALIZE_SYSTEM_INFO_FAILED);
261 // make server socket
262 if(makeTargetServerSocket() != 0)
264 writeToPortfile(ERR_TARGET_SERVER_SOCKET_CREATE_FAILED);
268 i = makeHostServerSocket();
271 writeToPortfile(ERR_HOST_SERVER_SOCKET_CREATE_FAILED);
274 else // host server socket creation succeed
279 // initialize signal mask
280 sigemptyset(&newsigmask);
281 sigaddset(&newsigmask, SIGALRM);
282 sigaddset(&newsigmask, SIGUSR1);
283 if(pthread_sigmask(SIG_BLOCK, &newsigmask, NULL) != 0)
285 writeToPortfile(ERR_SIGNAL_MASK_SETTING_FAILED);
289 LOGI("SUCCESS to write port\n");
291 // initialize target client sockets
292 for (i = 0; i < MAX_TARGET_COUNT; i++)
294 manager.target[i].pid = -1;
295 manager.target[i].socket = -1;
296 manager.target[i].event_fd = -1;
297 manager.target[i].recv_thread = -1;
298 manager.target[i].initial_log = 0;
299 manager.target[i].allocmem = 0;
300 manager.target[i].starttime = 0;
302 manager.target_count = 0;
304 // initialize sendMutex
305 pthread_mutex_init(&(manager.host.data_socket_mutex), NULL);
310 static int finalizeManager()
312 LOGI("Finalize daemon\n");
314 LOGI("finalize system info\n");
315 finalize_system_info();
318 // close host client socket
319 if(manager.host.control_socket != -1){
320 LOGI("close host control socket (%d)\n", manager.host.control_socket);
321 close(manager.host.control_socket);
323 if(manager.host.data_socket != -1){
324 LOGI("close host data socket (%d)\n", manager.host.data_socket);
325 close(manager.host.data_socket);
341 LOGE("da_started\n");
342 atexit(_unlink_file);
344 manager.portfile = fopen(PORTFILE, "w");
345 if(manager.portfile == NULL)
347 LOGE("cannot create portfile");
355 signal(SIGHUP, SIG_IGN);
361 // initialize manager
362 result = initializeManager();
363 fclose(manager.portfile);
367 //FIX ME remove samplingThread it is only for debug
368 //samplingThread(NULL);