5ede5cd6984ce1e75bea834e1a36ee92ad06ad6c
[platform/core/system/sync-agent.git] / src / framework / event / config.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <glib.h>
22 #include <glib/gprintf.h>
23
24 #include "utility/sync_util.h"
25 #include "event/config.h"
26
27 #ifndef SYNC_AGENT_LOG
28 #undef LOG_TAG
29 #define LOG_TAG "AF_EVENT"
30 #endif
31
32 static int current_event_count = 0;
33 static event_spec_s *event_spec_list[EVENT_MAX_EVENT_COUNT] = { 0 };
34
35 static int current_noti_bag_count = 0;
36 noti_spec_bag_s *noti_spec_bag_list[EVENT_MAX_NOTI_COUNT] = { 0 };
37
38 static char *__communication_path_event = NULL;
39
40 static int _find_noti_spec_bag(const char *noti_key);
41
42 static int _find_event_spec(int event_num);
43 static int _find_noti_spec(int noti_spec_bag_num, int noti_num);
44
45 const char *event_get_noti_path(const char *noti_key)
46 {
47         _EXTERN_FUNC_ENTER;
48
49         if (noti_key == NULL) {
50                 if (noti_spec_bag_list[0] != NULL) {
51                         return noti_spec_bag_list[0]->communication_path_noti;
52                 } else {
53                         return NULL;
54                 }
55         }
56
57         int index = _find_noti_spec_bag(noti_key);
58
59         _EXTERN_FUNC_EXIT;
60
61         return noti_spec_bag_list[index]->communication_path_noti;
62 }
63
64 const char *event_get_event_path()
65 {
66         _EXTERN_FUNC_ENTER;
67
68         _EXTERN_FUNC_EXIT;
69
70         return __communication_path_event;
71 }
72
73 sync_agent_event_error_e event_set_event_spec_from_config_file(const char *event_key, const char *config_file)
74 {
75         _EXTERN_FUNC_ENTER;
76
77         retvm_if(event_key == NULL, SYNC_AGENT_EVENT_FAIL, "event key is NULL !!");
78         retvm_if(config_file == NULL, SYNC_AGENT_EVENT_FAIL, "config file is NULL !!");
79
80         FILE *fp = fopen(config_file, "r");
81         if (fp == NULL) {
82                 _DEBUG_ERROR("file open failed [%s]\n", config_file);
83                 return SYNC_AGENT_EVENT_FAIL;
84         }
85
86         while (!feof(fp)) {
87                 event_spec_s *event_spec = (event_spec_s *) malloc(sizeof(event_spec_s));
88                 if (event_spec == NULL) {
89                         _DEBUG_ERROR("MALLOC failed !!!");
90                         if (fp != NULL)
91                                 fclose(fp);
92                         return SYNC_AGENT_EVENT_FAIL;
93                 } else {
94                         memset(event_spec, 0, sizeof(event_spec_s));
95                 }
96
97                 char description[1000];
98                 int fscanf_ret = fscanf(fp, "%d, %d, %d, %d, %999s\n", &(event_spec->event_num), (int *)(&(event_spec->event_type)), &(event_spec->relational_noti_num), &(event_spec->pendingtime), (char *)(&description));
99                 if (fscanf_ret == -1) {
100                         _DEBUG_ERROR("fscanf failed !!");
101                         if (fp != NULL)
102                                 fclose(fp);
103                         free(event_spec);
104                         return SYNC_AGENT_EVENT_FAIL;
105                 }
106
107                 event_spec_list[current_event_count] = event_spec;
108                 current_event_count++;
109         }
110
111         fclose(fp);
112
113         if (__communication_path_event == NULL) {
114                 int comm_path_event_len = strlen(EVENT_COMMUNICATION_PATH_EVENT) + strlen(event_key) + 1;
115                 int len = 0;
116                 __communication_path_event = (char *)calloc(comm_path_event_len, sizeof(char));
117
118                 if (__communication_path_event != NULL) {
119                         len = g_strlcat(__communication_path_event, EVENT_COMMUNICATION_PATH_EVENT, comm_path_event_len);
120                         len = g_strlcat(__communication_path_event, event_key, comm_path_event_len);
121
122                         if (len >= comm_path_event_len) {
123                                 _DEBUG_ERROR("__communication_path_event buffer overflow !!");
124                                 free(__communication_path_event);
125                                 return SYNC_AGENT_EVENT_FAIL;
126                         }
127
128                         _DEBUG_INFO("EVENT_COMMUNICATION_PATH_EVENT : %s", __communication_path_event);
129                 } else {
130                         _DEBUG_ERROR("__communication_path_event is NULL");
131                         return SYNC_AGENT_EVENT_FAIL;
132                 }
133         }
134
135         _EXTERN_FUNC_EXIT;
136
137         return SYNC_AGENT_EVENT_SUCCESS;
138 }
139
140 sync_agent_event_error_e event_clean_event_spec()
141 {
142         _EXTERN_FUNC_ENTER;
143
144         _DEBUG_INFO("Start: current_event_count = %d", current_event_count);
145         int i = 0;
146         for (; i < current_event_count; i++) {
147                 event_spec_s *event_spec = event_spec_list[i];
148                 if (event_spec != NULL) {
149                         free(event_spec);
150                 }
151
152                 event_spec_list[i] = 0;
153         }
154
155         current_event_count = 0;
156         _DEBUG_INFO("End: current_event_count = %d", current_event_count);
157
158         _EXTERN_FUNC_EXIT;
159
160         return SYNC_AGENT_EVENT_SUCCESS;
161 }
162
163 sync_agent_event_error_e event_set_noti_spec_from_config_file(const char *noti_key, const char *config_file)
164 {
165         _EXTERN_FUNC_ENTER;
166
167         if (noti_key == NULL || config_file == NULL) {
168                 return SYNC_AGENT_EVENT_FAIL;
169         }
170
171         FILE *fp = fopen(config_file, "r");
172         if (fp == NULL) {
173                 _DEBUG_ERROR("file open failed [%s]\n", config_file);
174                 return SYNC_AGENT_EVENT_FAIL;
175         }
176
177         /*
178          * Create Noti Spec Bag
179          */
180         noti_spec_bag_s *noti_spec_bag = (noti_spec_bag_s *) calloc(1, sizeof(noti_spec_bag_s));
181         if (noti_spec_bag == NULL) {
182                 _DEBUG_ERROR("CALLOC failed !!!");
183                 if (fp != NULL)
184                         fclose(fp);
185                 return SYNC_AGENT_EVENT_FAIL;
186         }
187         noti_spec_bag->noti_count = 0;
188
189         /*
190          * Setting noti_spec_list
191          */
192         while (!feof(fp)) {
193                 noti_spec_s *noti_spec = (noti_spec_s *) calloc(1, sizeof(noti_spec_s));
194                 if (noti_spec == NULL) {
195                         if (fp != NULL)
196                                 fclose(fp);
197                         _DEBUG_ERROR("CALLOC failed !!!");
198                         free(noti_spec_bag);
199                         return SYNC_AGENT_EVENT_FAIL;
200                 } else {
201                         memset(noti_spec, 0, sizeof(noti_spec_s));
202                 }
203
204                 char description[1000] = { 0, };
205                 int fscanf_ret = fscanf(fp, "%d, %d, %d, %d, %999s\n", &(noti_spec->noti_num), (int *)(&(noti_spec->noti_type)), &(noti_spec->relational_event_num), &(noti_spec->pendingtime), (char *)(&description));
206                 if (fscanf_ret == -1) {
207                         _DEBUG_ERROR("fscanf failed !!");
208                         if (fp != NULL)
209                                 fclose(fp);
210                         free(noti_spec_bag);
211                         free(noti_spec);
212                         return SYNC_AGENT_EVENT_FAIL;
213                 }
214
215                 noti_spec_bag->noti_spec_list[noti_spec_bag->noti_count] = noti_spec;
216                 noti_spec_bag->noti_count++;
217         }
218         fclose(fp);
219
220         /*
221          * Setting noti_key
222          */
223         noti_spec_bag->noti_key = strdup(noti_key);
224
225         /*
226          * Setting communication_path_noti
227          */
228         if (noti_spec_bag->communication_path_noti == NULL) {
229                 int comm_path_noti_len = strlen(EVENT_COMMUNICATION_PATH_NOTI) + strlen(noti_key) + 1;
230                 int len = 0;
231                 noti_spec_bag->communication_path_noti = (char *)calloc(comm_path_noti_len, sizeof(char));
232
233                 if (noti_spec_bag->communication_path_noti != NULL) {
234                         len = g_strlcat(noti_spec_bag->communication_path_noti, EVENT_COMMUNICATION_PATH_NOTI, comm_path_noti_len);
235                         len = g_strlcat(noti_spec_bag->communication_path_noti, noti_key, comm_path_noti_len);
236
237                         if (len >= comm_path_noti_len) {
238                                 _DEBUG_ERROR("noti_spec_bag->communication_path_noti buffer overflow !!");
239                                 free(noti_spec_bag->communication_path_noti);
240                                 free(noti_spec_bag);
241                                 return SYNC_AGENT_EVENT_FAIL;
242                         }
243
244                         _DEBUG_INFO("EVENT_COMMUNICATION_PATH_NOTI : %s", noti_spec_bag->communication_path_noti);
245                 } else {
246                         _DEBUG_ERROR("noti_spec_bag->communication_path_not is NULL");
247                         free(noti_spec_bag);
248                         return SYNC_AGENT_EVENT_FAIL;
249                 }
250         }
251
252         /*
253          * Setting communication_path_reply_noti
254          */
255         if (noti_spec_bag->communication_path_reply_noti == NULL) {
256                 int comm_path_reply_noti_len = strlen(EVENT_REPLY_COMMUNICATION_PATH_NOTI) + strlen(noti_key) + 1;
257                 int len = 0;
258                 noti_spec_bag->communication_path_reply_noti = (char *)calloc(comm_path_reply_noti_len, sizeof(char));
259
260                 if (noti_spec_bag->communication_path_reply_noti != NULL) {
261                         len = g_strlcat(noti_spec_bag->communication_path_reply_noti, EVENT_REPLY_COMMUNICATION_PATH_NOTI, comm_path_reply_noti_len);
262                         len = g_strlcat(noti_spec_bag->communication_path_reply_noti, noti_key, comm_path_reply_noti_len);
263
264                         if (len >= comm_path_reply_noti_len) {
265                                 _DEBUG_ERROR("noti_spec_bag->communication_path_reply_noti buffer overflow !!");
266                                 free(noti_spec_bag->communication_path_reply_noti);
267                                 free(noti_spec_bag);
268                                 return SYNC_AGENT_EVENT_FAIL;
269                         }
270
271                         _DEBUG_INFO("EVENT_REPLY_COMMUNICATION_PATH_NOTI : %s", noti_spec_bag->communication_path_reply_noti);
272                 } else {
273                         _DEBUG_ERROR("noti_spec_bag->communication_path_reply_noti is NULL");
274                         free(noti_spec_bag);
275                         return SYNC_AGENT_EVENT_FAIL;
276                 }
277         }
278
279         _DEBUG_INFO("before: current_noti_bag_count = %d", current_noti_bag_count);
280         noti_spec_bag_list[current_noti_bag_count] = noti_spec_bag;
281         current_noti_bag_count++;
282         _DEBUG_INFO("after: current_noti_bag_count = %d", current_noti_bag_count);
283
284         _EXTERN_FUNC_EXIT;
285
286         return SYNC_AGENT_EVENT_SUCCESS;
287 }
288
289 sync_agent_event_error_e event_clean_noti_spec()
290 {
291         _EXTERN_FUNC_ENTER;
292
293         _DEBUG_INFO("Start: current_noti_bag_count = %d", current_noti_bag_count);
294         int i = 0;
295         for (; i < current_noti_bag_count; i++) {
296                 noti_spec_bag_s *noti_spec_bag = noti_spec_bag_list[i];
297                 if (noti_spec_bag != NULL) {
298                         _DEBUG_INFO("noti_key = %s, communication_path_noti = %s, communication_path_reply_noti = %s", noti_spec_bag->noti_key, noti_spec_bag->communication_path_noti, noti_spec_bag->communication_path_reply_noti);
299                         free(noti_spec_bag->noti_key);
300                         free(noti_spec_bag->communication_path_noti);
301                         free(noti_spec_bag->communication_path_reply_noti);
302
303                         int k = 0;
304                         for (; k < noti_spec_bag->noti_count; k++) {
305                                 noti_spec_s *noti_spec = noti_spec_bag->noti_spec_list[k];
306                                 if (noti_spec != NULL) {
307                                         free(noti_spec);
308                                 }
309                         }
310
311                         noti_spec_bag_list[i] = 0;
312                 }
313         }
314
315         current_noti_bag_count = 0;
316         _DEBUG_INFO("End: current_noti_bag_count = %d", current_noti_bag_count);
317
318         _EXTERN_FUNC_EXIT;
319
320         return SYNC_AGENT_EVENT_SUCCESS;
321 }
322
323 sync_agent_event_error_e event_register_event_callback(int event_num, sync_agent_event_cb callback)
324 {
325         _EXTERN_FUNC_ENTER;
326
327         int index = _find_event_spec(event_num);
328         if (index == -1) {
329                 return SYNC_AGENT_EVENT_FAIL;
330         }
331
332         event_spec_list[index]->callback = callback;
333
334         _EXTERN_FUNC_EXIT;
335
336         return SYNC_AGENT_EVENT_SUCCESS;
337 }
338
339 sync_agent_event_error_e event_register_noti_callback(int noti_num, sync_agent_noti_cb callback, void *data)
340 {
341         _EXTERN_FUNC_ENTER;
342
343         int index = _find_noti_spec(0, noti_num);
344         if (index == -1) {
345                 return SYNC_AGENT_EVENT_FAIL;
346         }
347
348         noti_spec_bag_list[0]->noti_spec_list[index]->callback = callback;
349         noti_spec_bag_list[0]->noti_spec_list[index]->additional_param = data;
350
351         _EXTERN_FUNC_EXIT;
352
353         return SYNC_AGENT_EVENT_SUCCESS;
354 }
355
356 sync_agent_event_cb event_get_event_callback(int event_num)
357 {
358         _EXTERN_FUNC_ENTER;
359
360         int index = _find_event_spec(event_num);
361         if (index == -1) {
362                 return NULL;
363         }
364
365         _EXTERN_FUNC_EXIT;
366
367         return event_spec_list[index]->callback;
368 }
369
370 sync_agent_noti_cb event_get_noti_callback(int noti_num)
371 {
372         _EXTERN_FUNC_ENTER;
373
374         int index = _find_noti_spec(0, noti_num);
375         if (index == -1) {
376                 return NULL;
377         }
378
379         _EXTERN_FUNC_EXIT;
380
381         return noti_spec_bag_list[0]->noti_spec_list[index]->callback;
382 }
383
384 void *event_get_noti_callback_additional_param(int noti_num)
385 {
386         _EXTERN_FUNC_ENTER;
387
388         int index = _find_noti_spec(0, noti_num);
389         if (index == -1) {
390                 return NULL;
391         }
392
393         _EXTERN_FUNC_EXIT;
394
395         return noti_spec_bag_list[0]->noti_spec_list[index]->additional_param;
396 }
397
398 event_type_e event_get_event_type(int event_num)
399 {
400         _EXTERN_FUNC_ENTER;
401
402         int index = _find_event_spec(event_num);
403         if (index == -1) {
404                 return 0;
405         }
406
407         _EXTERN_FUNC_EXIT;
408
409         return event_spec_list[index]->event_type;
410 }
411
412 noti_type_e event_get_noti_type(const char *noti_key, int noti_num)
413 {
414         _EXTERN_FUNC_ENTER;
415
416         retvm_if(noti_key == NULL, NOTI_TYPE_UNKNOWN, "noti key is NULL !!");
417
418         int noti_spec_bag_num = _find_noti_spec_bag(noti_key);
419
420         int noti_index = _find_noti_spec(noti_spec_bag_num, noti_num);
421         if (noti_index == -1) {
422                 return 0;
423         }
424
425         _EXTERN_FUNC_EXIT;
426
427         return noti_spec_bag_list[noti_spec_bag_num]->noti_spec_list[noti_index]->noti_type;
428 }
429
430 static int _find_noti_spec_bag(const char *noti_key)
431 {
432         _INNER_FUNC_ENTER;
433
434         retvm_if(noti_key == NULL, 0, "noti key is NULL !!");
435
436         int i = 0;
437         for (; i < current_noti_bag_count; i++) {
438                 noti_spec_bag_s *noti_spec_bag = noti_spec_bag_list[i];
439                 if (noti_spec_bag != NULL) {
440                         if (!strcmp(noti_spec_bag->noti_key, noti_key)) {
441                                 _INNER_FUNC_EXIT;
442                                 return i;
443                         }
444                 }
445         }
446
447         return 0;
448 }
449
450 static int _find_event_spec(int event_num)
451 {
452         _INNER_FUNC_ENTER;
453
454         int i = 0;
455         for (; i < current_event_count; i++) {
456                 if (event_spec_list[i]->event_num == event_num) {
457                         _INNER_FUNC_EXIT;
458                         return i;
459                 }
460         }
461
462         return -1;
463 }
464
465 static int _find_noti_spec(int noti_spec_bag_num, int noti_num)
466 {
467         _INNER_FUNC_ENTER;
468
469         noti_spec_bag_s *noti_spec_bag = noti_spec_bag_list[noti_spec_bag_num];
470
471         int i = 0;
472         for (; i < noti_spec_bag->noti_count; i++) {
473                 if ((noti_spec_bag->noti_spec_list[i])->noti_num == noti_num) {
474                         _INNER_FUNC_EXIT;
475                         return i;
476                 }
477         }
478
479         return -1;
480 }