tizen 2.3.1 release
[apps/home/minicontrol.git] / src / minicontrol-internal-handler.c
1 /*
2  * Copyright (c)  2013-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <time.h>
19 #include <dbus/dbus.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include "minicontrol-error.h"
24 #include "minicontrol-type.h"
25 #include "minicontrol-internal.h"
26 #include "minicontrol-monitor.h"
27 #include "minicontrol-log.h"
28 #include "minicontrol-handler.h"
29
30 #define BUNDLE_KEY_PID "__KEY_PID__"
31 #define BUNDLE_KEY_STATE "__KEY_STATE__"
32 #define BUNDLE_KEY_SERVICE_NAME "__KEY_SERVICE_NAME__"
33 #define BUNDLE_KEY_CATEGORY "__KEY_CATEGORY__"
34 #define BUNDLE_KEY_OPERATION "__KEY_OPERATION__"
35 #define BUNDLE_KEY_PRIORITY "__KEY_PRIORITY__"
36 #define BUNDLE_KEY_TIMESTAMP "__KEY_TIMESTAMP__"
37
38 /*!
39  * bundle utility
40  */
41 static int _bundle_set_byte(bundle *b, const char *key, void *value, int length)
42 {
43         int ret = 0;
44         size_t ret_size = 0;
45         void *ret_byte = NULL;
46
47         ret = bundle_get_byte(b, key, &ret_byte, &ret_size);
48         if (ret == 0 && ret_byte != NULL) {
49                 if(bundle_del(b, key) != 0) {
50                         ERR("Failed to del a previous value(key):%s", key);
51                         return MINICONTROL_ERROR_INVALID_PARAMETER;
52                 }
53         }
54
55         if (value == NULL) {
56                 return MINICONTROL_ERROR_INVALID_PARAMETER;
57         }
58
59         if (bundle_add_byte(b, key, value, length) != 0) {
60                 ERR("Failed to set a new value(key):%s", key);
61                 return MINICONTROL_ERROR_BUNDLE;
62         }
63
64         return MINICONTROL_ERROR_NONE;
65 }
66
67 static int _bundle_set_str(bundle *b, const char *key, const char *value)
68 {
69         const char *val = NULL;
70
71         val = bundle_get_val(b, key);
72         if(val != NULL){
73                 if(bundle_del(b, key) != 0) {
74                         ERR("Failed to del a previous value(key):%s", key);
75                         return MINICONTROL_ERROR_BUNDLE;
76                 }
77         }
78
79         if(value == NULL) {
80                 return MINICONTROL_ERROR_INVALID_PARAMETER;
81         }
82
83         if(bundle_add(b, key, value) != 0){
84                 ERR("Failed to set a new value(key):%s", key);
85                 return MINICONTROL_ERROR_BUNDLE;
86         }
87
88         return MINICONTROL_ERROR_NONE;
89 }
90
91 /*!
92  * handler utility
93  */
94 static int _handler_validation_check(minicontrol_h handler) {
95         if (handler != NULL) {
96                 if (handler->data != NULL) {
97                         return MINICONTROL_ERROR_NONE;
98                 }
99         }
100         return MINICONTROL_ERROR_INVALID_PARAMETER;
101 }
102
103 static int _handler_extradata_key_validation_check(const char *key) {
104         if (key != NULL) {
105                 if (strcmp(key, BUNDLE_KEY_PID) == 0) {
106                         return MINICONTROL_ERROR_INVALID_PARAMETER;
107
108                 } else if (strcmp(key, BUNDLE_KEY_SERVICE_NAME) == 0) {
109                         return MINICONTROL_ERROR_INVALID_PARAMETER;
110
111                 } else if (strcmp(key, BUNDLE_KEY_SERVICE_NAME) == 0) {
112                         return MINICONTROL_ERROR_INVALID_PARAMETER;
113
114                 } else if (strcmp(key, BUNDLE_KEY_OPERATION) == 0) {
115                         return MINICONTROL_ERROR_INVALID_PARAMETER;
116
117                 } else if (strcmp(key, BUNDLE_KEY_PRIORITY) == 0) {
118                         return MINICONTROL_ERROR_INVALID_PARAMETER;
119
120                 } else if (strcmp(key, BUNDLE_KEY_TIMESTAMP) == 0) {
121                         return MINICONTROL_ERROR_INVALID_PARAMETER;
122                 }
123
124                 return MINICONTROL_ERROR_INVALID_PARAMETER;
125         }
126
127         return MINICONTROL_ERROR_INVALID_PARAMETER;
128 }
129
130 /*!
131  * handler bundle utility
132  */
133 static minicontrol_error_e __set_str_to_handler(minicontrol_h handler, const char *key, const char *value)
134 {
135         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE
136                 || key == NULL) {
137                 return MINICONTROL_ERROR_INVALID_PARAMETER;
138         }
139
140         if (value != NULL) {
141                 return _bundle_set_str(handler->data, key, value);
142         } else {
143                 bundle_del(handler->data, key);
144         }
145
146         return MINICONTROL_ERROR_NONE;
147 }
148
149 static minicontrol_error_e __get_str_from_handler(minicontrol_h handler, const char *key, char **value)
150 {
151         const char *data_value;
152
153         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE
154                 || key == NULL
155                 || value == NULL) {
156                 return MINICONTROL_ERROR_INVALID_PARAMETER;;
157         }
158
159         data_value = bundle_get_val(handler->data, key);
160         if (data_value == NULL)  {
161                 if (errno == ENOTSUP) {
162                         return MINICONTROL_ERROR_BUNDLE;
163                 } else {
164                         return MINICONTROL_ERROR_NO_DATA;
165                 }
166         }
167
168         *value = strdup(data_value);
169
170         return MINICONTROL_ERROR_NONE;
171 }
172
173 /*!
174  * handler APIs
175  */
176 minicontrol_error_e _minictrl_handler_create(minicontrol_h *handler)
177 {
178         minicontrol_h handler_new = NULL;
179         if (handler == NULL) {
180                 return MINICONTROL_ERROR_INVALID_PARAMETER;
181         }
182
183         handler_new = calloc(1, sizeof(struct _minicontrol_h));
184         if (handler_new == NULL) {
185                 ERR("Failed to create a handler");
186                 return MINICONTROL_ERROR_OUT_OF_MEMORY;
187         }
188
189         handler_new->data = bundle_create();
190         if (handler_new->data == NULL)
191         {
192                 free(handler_new);
193                 ERR("Failed to create a bundle");
194                 return MINICONTROL_ERROR_OUT_OF_MEMORY;
195         }
196
197         if (_minictrl_handler_set_pid(handler_new) != MINICONTROL_ERROR_NONE) {
198                 ERR("Failed to set PID to handler");
199         }
200         if (_minictrl_handler_set_state(handler_new, 0) != MINICONTROL_ERROR_NONE) {
201                 ERR("Failed to set state to handler");
202         }
203         if (_minictrl_handler_set_category(handler_new, MINICONTROL_HDL_CATEGORY_UNKNOWN) != MINICONTROL_ERROR_NONE) {
204                 ERR("Failed to set category to handler");
205         }
206
207         *handler = handler_new;
208
209         return MINICONTROL_ERROR_NONE;
210 }
211
212 minicontrol_error_e _minictrl_handler_destroy(minicontrol_h handler)
213 {
214         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE) {
215                 return MINICONTROL_ERROR_INVALID_PARAMETER;
216         }
217
218         bundle_free(handler->data);
219         handler->data = NULL;
220         free(handler);
221
222         return MINICONTROL_ERROR_NONE;
223 }
224
225 minicontrol_error_e _minictrl_handler_clone(minicontrol_h handler, minicontrol_h *handler_new)
226 {
227         int ret = 0;
228
229         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE || handler_new == NULL) {
230                 return MINICONTROL_ERROR_INVALID_PARAMETER;
231         }
232
233         if ((ret = _minictrl_handler_create(handler_new)) == MINICONTROL_ERROR_NONE) {
234                 (*handler_new)->data = bundle_dup(handler->data);
235                 if ((*handler_new)->data == NULL) {
236                         _minictrl_handler_destroy(*handler_new);
237                         return MINICONTROL_ERROR_OUT_OF_MEMORY;
238                 }
239         } else {
240                 return ret;
241         }
242
243         return MINICONTROL_ERROR_NONE;
244 }
245
246 minicontrol_error_e _minictrl_handler_check_validation(minicontrol_h handler)
247 {
248         return _handler_validation_check(handler);
249 }
250
251 minicontrol_error_e _minictrl_handler_set_service_name(minicontrol_h handler, const char *name)
252 {
253         return __set_str_to_handler(handler, BUNDLE_KEY_SERVICE_NAME, name);
254 }
255
256 minicontrol_error_e _minictrl_handler_get_service_name(minicontrol_h handler, char **name)
257 {
258         return __get_str_from_handler(handler, BUNDLE_KEY_SERVICE_NAME, name);
259 }
260
261 minicontrol_error_e _minictrl_handler_set_category(minicontrol_h handler, const char *category)
262 {
263         return __set_str_to_handler(handler, BUNDLE_KEY_CATEGORY, category);
264 }
265
266 minicontrol_error_e _minictrl_handler_get_category(minicontrol_h handler, char **category)
267 {
268         return __get_str_from_handler(handler, BUNDLE_KEY_CATEGORY, category);
269 }
270
271 minicontrol_error_e _minictrl_handler_set_operation(minicontrol_h handler, const char *operation)
272 {
273         return __set_str_to_handler(handler, BUNDLE_KEY_OPERATION, operation);
274 }
275
276 minicontrol_error_e _minictrl_handler_get_operation(minicontrol_h handler, char **operation)
277 {
278         return __get_str_from_handler(handler, BUNDLE_KEY_OPERATION, operation);
279 }
280
281 minicontrol_error_e _minictrl_handler_set_priority(minicontrol_h handler, const char *priority)
282 {
283         return __set_str_to_handler(handler, BUNDLE_KEY_PRIORITY, priority);
284 }
285
286 minicontrol_error_e _minictrl_handler_get_priority(minicontrol_h handler, char **priority)
287 {
288         return __get_str_from_handler(handler, BUNDLE_KEY_PRIORITY, priority);
289 }
290
291 minicontrol_error_e _minictrl_handler_set_timestamp(minicontrol_h handler, time_t timestamp)
292 {
293         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE) {
294                 return MINICONTROL_ERROR_INVALID_PARAMETER;
295         }
296
297         if (timestamp > 0) {
298                 return _bundle_set_byte(handler->data, BUNDLE_KEY_TIMESTAMP, (void *)&timestamp, sizeof(time_t));
299         } else {
300                 bundle_del(handler->data, BUNDLE_KEY_TIMESTAMP);
301         }
302
303         return MINICONTROL_ERROR_NONE;
304 }
305
306 minicontrol_error_e _minictrl_handler_get_timestamp(minicontrol_h handler, time_t *timestamp)
307 {
308         int ret = 0;
309         size_t ret_size = 0;
310         void *ret_value = NULL;
311
312         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE || timestamp == NULL) {
313                 return MINICONTROL_ERROR_INVALID_PARAMETER;
314         }
315
316         ret = bundle_get_byte(handler->data, BUNDLE_KEY_TIMESTAMP, &ret_value, &ret_size);
317         if (ret == 0 && ret_value != NULL && ret_size == sizeof(time_t)) {
318                 *timestamp = *((time_t *)ret_value);
319         } else {
320                 *timestamp = 0;
321         }
322
323         return MINICONTROL_ERROR_NONE;
324 }
325
326 minicontrol_error_e _minictrl_handler_set_pid(minicontrol_h handler)
327 {
328         int pid = 0;
329         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE) {
330                 return MINICONTROL_ERROR_INVALID_PARAMETER;
331         }
332
333         pid = getpid();
334         if (pid > 0) {
335                 return _bundle_set_byte(handler->data, BUNDLE_KEY_PID, (void *)&pid, sizeof(int));
336         } else {
337                 bundle_del(handler->data, BUNDLE_KEY_PID);
338         }
339
340         return MINICONTROL_ERROR_NONE;
341 }
342
343 minicontrol_error_e _minictrl_handler_get_pid(minicontrol_h handler, int *pid)
344 {
345         int ret = 0;
346         size_t ret_size = 0;
347         void *ret_value = NULL;
348
349         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE || pid == NULL) {
350                 return MINICONTROL_ERROR_INVALID_PARAMETER;
351         }
352
353         ret = bundle_get_byte(handler->data, BUNDLE_KEY_PID, &ret_value, &ret_size);
354         if (ret == 0 && ret_value != NULL && ret_size == sizeof(int)) {
355                 *pid = *((int *)ret_value);
356         } else {
357                 *pid = 0;
358         }
359
360         return MINICONTROL_ERROR_NONE;
361 }
362
363 minicontrol_error_e _minictrl_handler_set_state(minicontrol_h handler, int state)
364 {
365         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE) {
366                 return MINICONTROL_ERROR_INVALID_PARAMETER;
367         }
368
369         if (state >= 0) {
370                 return _bundle_set_byte(handler->data, BUNDLE_KEY_STATE, (void *)&state, sizeof(int));
371         } else {
372                 bundle_del(handler->data, BUNDLE_KEY_STATE);
373         }
374
375         return MINICONTROL_ERROR_NONE;
376 }
377
378 minicontrol_error_e _minictrl_handler_get_state(minicontrol_h handler, int *state)
379 {
380         int ret = 0;
381         size_t ret_size = 0;
382         void *ret_value = NULL;
383
384         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE || state == NULL) {
385                 return MINICONTROL_ERROR_INVALID_PARAMETER;
386         }
387
388         ret = bundle_get_byte(handler->data, BUNDLE_KEY_STATE, &ret_value, &ret_size);
389         if (ret == 0 && ret_value != NULL && ret_size == sizeof(int)) {
390                 *state = *((int *)ret_value);
391         } else {
392                 *state = 0;
393         }
394
395         return MINICONTROL_ERROR_NONE;
396 }
397
398 minicontrol_error_e _minictrl_handler_add_extradata(minicontrol_h handler, const char *key, const char *value)
399 {
400         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE
401                 || _handler_extradata_key_validation_check(key) != MINICONTROL_ERROR_NONE
402                 || value == NULL) {
403                 return MINICONTROL_ERROR_INVALID_PARAMETER;;
404         }
405
406         return _bundle_set_str(handler->data, key, value);
407 }
408
409 minicontrol_error_e _minictrl_handler_remove_extradata(minicontrol_h handler, const char *key)
410 {
411         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE
412                 || _handler_extradata_key_validation_check(key) != MINICONTROL_ERROR_NONE) {
413                 return MINICONTROL_ERROR_INVALID_PARAMETER;;
414         }
415
416         if (bundle_del(handler->data, key)) {
417                 return MINICONTROL_ERROR_NO_DATA;
418         }
419
420         return MINICONTROL_ERROR_NONE;
421 }
422
423 minicontrol_error_e _minictrl_handler_get_extradata(minicontrol_h handler, const char *key, char **value)
424 {
425         const char *data_value;
426
427         if (_handler_validation_check(handler) != MINICONTROL_ERROR_NONE
428                 || _handler_extradata_key_validation_check(key) != MINICONTROL_ERROR_NONE
429                 || value == NULL) {
430                 return MINICONTROL_ERROR_INVALID_PARAMETER;;
431         }
432
433         data_value = bundle_get_val(handler->data, key);
434         if (data_value == NULL)  {
435                 if (errno == ENOTSUP) {
436                         return MINICONTROL_ERROR_BUNDLE;
437                 } else {
438                         return MINICONTROL_ERROR_NO_DATA;
439                 }
440         }
441
442         *value = strdup(data_value);
443
444         return MINICONTROL_ERROR_NONE;
445 }
446
447 minicontrol_error_e _minictrl_handler_get_raw_data(minicontrol_h handler, char **raw_data, int *length)
448 {
449         if (handler == NULL || raw_data == NULL || length == NULL) {
450                 return MINICONTROL_ERROR_INVALID_PARAMETER;
451         }
452
453         if (handler->data != NULL) {
454                 bundle_encode(handler->data,
455                               (bundle_raw **) raw_data, length);
456         } else {
457                 return MINICONTROL_ERROR_INVALID_PARAMETER;
458         }
459
460         return MINICONTROL_ERROR_NONE;
461 }
462
463 static void iterate_bundleforeach(const char *key,const int type, bundle_keyval_t *kv, void *data)
464 {
465         switch(type)
466         {
467                 case BUNDLE_TYPE_STR:
468                 {
469                         size_t size;
470                         char *basic_val = NULL;
471
472                         bundle_keyval_get_basic_val(kv,(void *)&basic_val,&size);
473                         ERR("Key: %s ---- Val: %s\n",key,basic_val);
474
475                         break;
476                 }
477                 case BUNDLE_TYPE_BYTE:
478                 {
479                         size_t size;
480                         char *basic_val = NULL;
481
482                         bundle_keyval_get_basic_val(kv,(void *)&basic_val,&size);
483                         ERR("Key: %s ---- Val: %d\n",key, *((int *)basic_val));
484
485                         break;
486                 }
487                 default:
488                 {
489                         DBG("\n no match found");
490                         DBG("Key: %s is of type %d\n",key, type);
491                         break;
492                 }
493         }
494 }
495
496 minicontrol_error_e _minictrl_handler_get_handler_from_raw_data(minicontrol_h *handler, char *raw_data, int length)
497 {
498         if (_minictrl_handler_create(handler) == MINICONTROL_ERROR_NONE) {
499                 (*handler)->data = bundle_decode((bundle_raw *)raw_data, length);
500                 bundle_foreach((*handler)->data,(void *)iterate_bundleforeach,NULL);
501         } else {
502                 return MINICONTROL_ERROR_INVALID_PARAMETER;
503         }
504
505         return MINICONTROL_ERROR_NONE;
506 }