3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #include <sys/types.h>
21 #include <sys/socket.h>
27 #include <glib/gprintf.h>
29 #include "utility/sync_util.h"
30 #include "data-adapter/agent_handler_manager.h"
31 #include "fsapi/operation.h"
33 #include "event/util.h"
34 #include "event/data_accessor.h"
35 #include "event/data_accessor_internal.h"
36 #include "event/config.h"
37 #include "event/handler.h"
39 #define EVENT_RETRY_COUNT 2000
42 #define EXPORT_API __attribute__ ((visibility("default")))
45 #ifndef SYNC_AGENT_LOG
47 #define LOG_TAG "AF_EVENT"
50 static int _event_server_socket_id = 0;
52 static pthread_t event_handler_thread_id;
54 static void *_event_listener(void *arg);
56 static void __dispatch_event(int event_num, sync_agent_event_data_s * request, sync_agent_event_data_s * response);
58 EXPORT_API sync_agent_event_error_e sync_agent_run_event_handler(unsigned long int *thread_id)
62 _DEBUG_INFO("sync_agent_run_event_handler() start\n");
64 int status_thread_create = 0;
65 status_thread_create = pthread_create(&event_handler_thread_id, 0, _event_listener, 0);
66 if(status_thread_create != 0) {
67 _DEBUG_WARNING("pthread_create [%d]", status_thread_create );
69 return SYNC_AGENT_EVENT_FAIL;
72 *thread_id = event_handler_thread_id;
76 return SYNC_AGENT_EVENT_SUCCESS;
79 EXPORT_API sync_agent_event_error_e sync_agent_clean_event_handler()
83 sync_agent_event_error_e event_err = event_clean_event_spec();
84 if (event_err != SYNC_AGENT_EVENT_SUCCESS) {
85 _DEBUG_ERROR("Fail event_clean_event_spec : %d", event_err);
87 _DEBUG_INFO("Success event_clean_event_spec : %d", event_err);
89 event_err = event_clean_noti_spec();
90 if (event_err != SYNC_AGENT_EVENT_SUCCESS) {
91 _DEBUG_ERROR("Fail event_clean_noti_spec : %d", event_err);
93 _DEBUG_INFO("Success event_clean_noti_spec : %d", event_err);
96 if (_event_server_socket_id != 0) {
97 close(_event_server_socket_id);
98 _event_server_socket_id = 0;
101 pthread_cancel(event_handler_thread_id);
105 return SYNC_AGENT_EVENT_SUCCESS;
108 EXPORT_API sync_agent_event_error_e sync_agent_set_event_callback(int event_num, sync_agent_event_cb callback)
114 return event_register_event_callback(event_num, callback);
117 EXPORT_API sync_agent_event_data_s *sync_agent_create_noti(int noti_num)
121 sync_agent_event_data_s *noti = (sync_agent_event_data_s *) calloc(1, sizeof(sync_agent_event_data_s));
123 _DEBUG_ERROR("Memory malloc FAILED. [noti]");
126 noti->event_num = noti_num;
129 char *serialized_data = (char *)calloc(EVENT_MAX_STREAM_SIZE, sizeof(char));
130 if (serialized_data == NULL) {
131 _DEBUG_ERROR("CALLOC failed !!!");
132 sync_agent_free_event_data(noti);
135 noti->size = serialized_data;
136 noti->data = serialized_data + 1;
138 sync_agent_append_event_data_param(noti, SYNC_AGENT_EVENT_PARAM_TYPE_INTEGER, ¬i_num);
145 EXPORT_API sync_agent_event_data_s *sync_agent_send_noti(const char *noti_key, sync_agent_event_data_s * noti, sync_agent_confirm_ipc_cancel_cb confirm_cancel, void *user_data, sync_agent_event_error_e * error)
149 if (noti_key == NULL) {
150 _DEBUG_ERROR("noti key is NULL !!");
151 *error = SYNC_AGENT_EVENT_IPC_ERR;
156 _DEBUG_ERROR("sync_agent_event_data_s is NULL !!");
157 *error = SYNC_AGENT_EVENT_IPC_ERR;
161 *error = SYNC_AGENT_EVENT_SUCCESS;
162 const char *communication_path = NULL;
164 noti_type_e noti_type = event_get_noti_type(noti_key, noti->event_num);
167 case NOTI_TYPE_SIMPLE:
168 communication_path = event_get_noti_path(noti_key);
171 *error = SYNC_AGENT_EVENT_IPC_ERR;
176 _DEBUG_INFO("noti num : %d", noti->event_num);
177 _DEBUG_INFO("noti_type : %d", noti_type);
178 _DEBUG_INFO("communication_path : %s", communication_path);
180 sync_agent_event_data_s *reply_msg = NULL;
181 int send_data_size = (noti->data - noti->size) + 1;
183 if (sync_agent_is_existing_fs(communication_path)) {
185 fp = fopen(communication_path, "w");
187 if (fwrite((void *)(noti->size), sizeof(char), send_data_size, fp) <= 0) {
188 _DEBUG_ERROR("fwrite() failed !!");
189 *error = SYNC_AGENT_EVENT_IPC_ERR;
193 _DEBUG_INFO("fwrite() success !!");
197 _DEBUG_ERROR("fopen( %s ) failed !!", communication_path);
198 *error = SYNC_AGENT_EVENT_IPC_ERR;
202 _DEBUG_ERROR("file ( %s ) does not exist !!", communication_path);
203 *error = SYNC_AGENT_EVENT_IPC_ERR;
212 EXPORT_API void sync_agent_free_noti(sync_agent_event_data_s * noti)
217 sync_agent_free_event_data(noti);
223 static void *_event_listener(void *arg)
227 signal(SIGPIPE, SIG_IGN);
229 int client_sockfd = -1;
231 socklen_t client_len;
232 struct sockaddr_un clientaddr, serveraddr;
236 const char *communication_path = event_get_event_path();
237 _DEBUG_TRACE("event_path : %s", communication_path);
239 if (sync_agent_is_existing_fs(communication_path)) {
240 _DEBUG_TRACE("%s file is exist !!");
241 if (unlink(communication_path) == -1) { /* when file exist, remove previous file */
242 _DEBUG_ERROR("unlink failed ( %s ), ERROR NUM [%d] !!", communication_path, errno);
245 _DEBUG_TRACE("unlink success !!");
248 _DEBUG_TRACE("%s file is not exist !!");
251 client_len = sizeof(clientaddr);
252 _DEBUG_INFO("_event_listener - client_len: [%d]",client_len);
253 if ((_event_server_socket_id = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
257 bzero(&serveraddr, sizeof(serveraddr));
258 serveraddr.sun_family = AF_UNIX;
259 if (communication_path != NULL) {
260 buf_len = g_strlcpy(serveraddr.sun_path, communication_path, sizeof(serveraddr.sun_path));
261 if (buf_len >= sizeof(serveraddr.sun_path)) {
262 _DEBUG_ERROR("serveraddr.sun_path buffer overflow !!");
266 _DEBUG_ERROR("communication_path is NULL !!");
270 state = bind(_event_server_socket_id, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
272 _DEBUG_ERROR("bind failed !!");
276 mode_t sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
277 if (chmod(communication_path, sock_mode) == -1) {
278 _DEBUG_ERROR("chmod failed !! ( err : %d )", errno);
282 state = listen(_event_server_socket_id, 5);
284 _DEBUG_ERROR("listen failed !!");
289 _DEBUG_TRACE("In EventHandler loop=\n");
292 char * outbuf = NULL;
293 inbuf = (char*)malloc(sizeof(char)*(EVENT_MAX_STREAM_SIZE + 1));
295 _DEBUG_ERROR("inbuf malloc failed!!");
299 outbuf= (char*)malloc(sizeof(char)*(EVENT_MAX_STREAM_SIZE + 1));
301 _DEBUG_ERROR("outbuf malloc failed!!");
305 memset(inbuf, 0x00, EVENT_MAX_STREAM_SIZE + 1);
306 memset(outbuf, 0x00, EVENT_MAX_STREAM_SIZE + 1);
307 sync_agent_event_data_s request = {0,NULL,NULL};
308 sync_agent_event_data_s response = {0,NULL,NULL};
310 request.data = inbuf;
311 response.data = outbuf;
312 event_init_event_data_iter(&request);
313 event_init_event_data_iter(&response);
315 client_sockfd = accept(_event_server_socket_id, (struct sockaddr *)&clientaddr, &client_len);
317 if (client_sockfd < 0) {
318 _DEBUG_ERROR("socket accept() failed !!");
321 _DEBUG_TRACE("accept() was called\n");
322 _DEBUG_INFO("_event_listener - client_sockfd: [%d]",client_sockfd);
324 result = read(client_sockfd, (void *)inbuf, EVENT_MAX_STREAM_SIZE);
325 if (result <= 0 || result > EVENT_MAX_STREAM_SIZE) {
326 _DEBUG_ERROR("read failed !!");
330 _DEBUG_INFO("read result [%d]", result);
333 for( print_i = 0; print_i < result ; print_i++)
335 _DEBUG_INFO(" 0x%x ", inbuf[print_i]);
337 _DEBUG_INFO("request.event_num [%d]", request.event_num);
338 _DEBUG_INFO("request.size [ox%x]", *(request.size));
339 _DEBUG_INFO("request.data [0x%x]", *(request.data));
343 sync_agent_get_event_data_param_int(&request, &event_num);
344 _DEBUG_TRACE("Received Event Number : %d\n", event_num);
346 __dispatch_event(event_num, &request, &response);
348 // need synchronous response case
349 event_type_e event_type = event_get_event_type(event_num);
350 if (event_type == EVENT_TYPE_NEED_RESPONSE) {
351 if (event_get_event_data_element_size(&response) > 0) {
352 int byte_size = event_get_event_data_byte_size(&response);
353 int write_ret = write(client_sockfd, outbuf, byte_size);
354 if (write_ret != byte_size) {
355 _DEBUG_ERROR("write() failed !!");
372 if (client_sockfd >= 0 )
373 close(client_sockfd);
381 static void __dispatch_event(int event_num, sync_agent_event_data_s * request, sync_agent_event_data_s * response)
385 retm_if(request == NULL, "sync_agent_event_data_s is NULL !!");
386 retm_if(response == NULL, "sync_agent_event_data_s is NULL !!");
388 sync_agent_event_cb event_callback = event_get_event_callback(event_num);
389 retm_if(event_callback == NULL, "event_get_event_callback return value is NULL !!");
391 event_callback(request, response);