tizen 2.3 release
[apps/livebox/data-provider-master.git] / src / notification_service.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include <stdio.h>
17
18 #include <Eina.h>
19
20 #include <dlog.h>
21 #if defined(HAVE_LIVEBOX)
22 #include <dynamicbox_errno.h>
23 #else
24 #include "lite-errno.h"
25 #endif
26 #include <packet.h>
27
28 #include <sys/smack.h>
29 #include <security-server.h>
30
31 #include <vconf.h>
32 #include <notification.h>
33 #include <notification_internal.h>
34 #include <notification_ipc.h>
35 #include <notification_noti.h>
36 #include <notification_setting_service.h>
37
38 #include "service_common.h"
39 #include "debug.h"
40 #include "util.h"
41 #include "conf.h"
42
43 #ifndef NOTIFICATION_DEL_PACKET_UNIT
44 #define NOTIFICATION_DEL_PACKET_UNIT 10
45 #endif
46
47 static struct info {
48         Eina_List *context_list;
49         struct service_context *svc_ctx;
50 } s_info = {
51         .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
52         .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
53 };
54
55 struct context {
56         struct tcb *tcb;
57         double seq;
58 };
59
60 struct noti_service {
61         const char *cmd;
62         void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
63         const char *rule;
64         const char *access;
65         void (*handler_access_error)(struct tcb *tcb, struct packet *packet);
66 };
67
68 static inline char *_string_get(char *string)
69 {
70         if (string == NULL) {
71                 return NULL;
72         }
73         if (string[0] == '\0') {
74                 return NULL;
75         }
76
77         return string;
78 }
79
80 /*!
81  * FUNCTIONS to create packets
82  */
83 static inline int _priv_id_get_from_list(int num_data, int *list, int index) {
84         if (index < num_data) {
85                 return *(list + index);
86         } else {
87                 return -1;
88         }
89 }
90
91 static inline struct packet *_packet_create_with_list(int op_num, int *list, int start_index) {
92         return packet_create(
93                         "del_noti_multiple",
94                         "iiiiiiiiiii",
95                         ((op_num - start_index) > NOTIFICATION_DEL_PACKET_UNIT) ? NOTIFICATION_DEL_PACKET_UNIT : op_num - start_index,
96                         _priv_id_get_from_list(op_num, list, start_index),
97                         _priv_id_get_from_list(op_num, list, start_index + 1),
98                         _priv_id_get_from_list(op_num, list, start_index + 2),
99                         _priv_id_get_from_list(op_num, list, start_index + 3),
100                         _priv_id_get_from_list(op_num, list, start_index + 4),
101                         _priv_id_get_from_list(op_num, list, start_index + 5),
102                         _priv_id_get_from_list(op_num, list, start_index + 6),
103                         _priv_id_get_from_list(op_num, list, start_index + 7),
104                         _priv_id_get_from_list(op_num, list, start_index + 8),
105                         _priv_id_get_from_list(op_num, list, start_index + 9)
106                         );
107 }
108
109 /*!
110  * SERVICE HANDLER
111  */
112 static void _handler_insert_noti(struct tcb *tcb, struct packet *packet, notification_h noti, void *data)
113 {
114         int ret = 0, ret_p = 0;
115         int priv_id = 0;
116         struct packet *packet_reply = NULL;
117         struct packet *packet_service = NULL;
118
119         ret = notification_noti_insert(noti);
120         notification_get_id(noti, NULL, &priv_id);
121         DbgPrint("priv_id: [%d]\n", priv_id);
122         packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
123         if (packet_reply) {
124                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
125                         ErrPrint("failed to send reply packet: %d\n", ret_p);
126                 }
127                 packet_destroy(packet_reply);
128         } else {
129                 ErrPrint("failed to create a reply packet\n");
130         }
131
132         if (ret != NOTIFICATION_ERROR_NONE) {
133                 ErrPrint("failed to insert a notification: %d\n", ret);
134                 return ;
135         }
136
137         packet_service = notification_ipc_make_packet_from_noti(noti, "add_noti", 2);
138         if (packet_service != NULL) {
139                 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
140                         ErrPrint("failed to send a multicast packet: %d\n", ret_p);
141                 }
142                 packet_destroy(packet_service);
143         } else {
144                 ErrPrint("failed to create a multicats packet\n");
145         }
146 }
147
148 /*static void _handler_insert(struct tcb *tcb, struct packet *packet, void *data) // not used
149   {
150   notification_h noti = NULL;
151
152   noti = notification_create(NOTIFICATION_TYPE_NOTI);
153   if (noti != NULL) {
154   if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
155   _handler_insert_noti(tcb, packet, noti, data);
156   } else {
157   ErrPrint("Failed to create the packet");
158   }
159   notification_free(noti);
160   }
161   }*/
162
163 static void _handler_update_noti(struct tcb *tcb, struct packet *packet, notification_h noti, void *data)
164 {
165         int ret = 0, ret_p = 0;
166         int priv_id = 0;
167         struct packet *packet_reply = NULL;
168         struct packet *packet_service = NULL;
169
170         ret = notification_noti_update(noti);
171
172         notification_get_id(noti, NULL, &priv_id);
173         DbgPrint("priv_id: [%d]\n", priv_id);
174         packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
175         if (packet_reply) {
176                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
177                         ErrPrint("failed to send reply packet:%d\n", ret_p);
178                 }
179                 packet_destroy(packet_reply);
180         } else {
181                 ErrPrint("failed to create a reply packet\n");
182         }
183
184         if (ret != NOTIFICATION_ERROR_NONE) {
185                 ErrPrint("failed to update a notification:%d\n", ret);
186                 return ;
187         }
188
189         packet_service = notification_ipc_make_packet_from_noti(noti, "update_noti", 2);
190         if (packet_service != NULL) {
191                 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
192                         ErrPrint("failed to send a multicast packet: %d\n", ret_p);
193                 }
194                 packet_destroy(packet_service);
195         }
196 }
197
198 static void _handler_update(struct tcb *tcb, struct packet *packet, void *data)
199 {
200         notification_h noti = NULL;
201
202         noti = notification_create(NOTIFICATION_TYPE_NOTI);
203         if (noti != NULL) {
204                 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
205                         _handler_update_noti(tcb, packet, noti, data);
206                 } else {
207                         ErrPrint("Failed to create the packet");
208                 }
209                 notification_free(noti);
210         }
211 }
212
213 static void _handler_check_noti_by_tag(struct tcb *tcb, struct packet *packet, void *data)
214 {
215         int ret = 0;
216         notification_h noti = NULL;
217
218         noti = notification_create(NOTIFICATION_TYPE_NOTI);
219         if (noti != NULL) {
220                 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
221                         ret = notification_noti_check_tag(noti);
222                         if (ret == NOTIFICATION_ERROR_NOT_EXIST_ID) {
223                                 _handler_insert_noti(tcb, packet, noti, data);
224                         } else if (ret == NOTIFICATION_ERROR_ALREADY_EXIST_ID) {
225                                 _handler_update_noti(tcb, packet, noti, data);
226                         }
227                 }
228                 notification_free(noti);
229         }
230 }
231
232 static void _handler_load_noti_by_tag(struct tcb *tcb, struct packet *packet, void *data)
233 {
234         int ret = 0, ret_p = 0;
235         char* tag;
236         char* pkgname;
237         struct packet *packet_reply = NULL;
238         notification_h noti = NULL;
239
240         noti = notification_create(NOTIFICATION_TYPE_NOTI);
241         if (noti != NULL) {
242                 if (packet_get(packet, "ss", &pkgname, &tag) == 2) {
243                         ret = notification_noti_get_by_tag(noti, pkgname, tag);
244                         packet_reply = notification_ipc_make_reply_packet_from_noti(noti, packet);
245                         if (packet_reply) {
246                                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
247                                         ErrPrint("failed to send reply packet: %d\n", ret_p);
248                                 }
249                                 packet_destroy(packet_reply);
250                         } else {
251                                 ErrPrint("failed to create a reply packet\n");
252                         }
253
254                         if (ret != NOTIFICATION_ERROR_NONE) {
255                                 ErrPrint("failed to load_noti_by_tag : %d\n", ret);
256                                 notification_free(noti);
257                                 return ;
258                         }
259                 } else {
260                         ErrPrint("Failed to create the packet");
261                 }
262                 notification_free(noti);
263         }
264 }
265
266
267 static void _handler_refresh(struct tcb *tcb, struct packet *packet, void *data)
268 {
269         int ret = 0;
270         struct packet *packet_reply = NULL;
271
272         packet_reply = packet_create_reply(packet, "i", ret);
273         if (packet_reply) {
274                 if ((ret = service_common_unicast_packet(tcb, packet_reply)) < 0) {
275                         ErrPrint("failed to send reply packet:%d\n", ret);
276                 }
277                 packet_destroy(packet_reply);
278         } else {
279                 ErrPrint("failed to create a reply packet\n");
280         }
281
282         if ((ret = service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE)) < 0) {
283                 ErrPrint("failed to send a multicast packet:%d\n", ret);
284         }
285 }
286
287 static void _handler_delete_single(struct tcb *tcb, struct packet *packet, void *data)
288 {
289         int num_changes = 0;
290         int ret = 0, ret_p = 0;
291         int priv_id = 0;
292         struct packet *packet_reply = NULL;
293         struct packet *packet_service = NULL;
294         char *pkgname = NULL;
295
296         if (packet_get(packet, "si", &pkgname, &priv_id) == 2) {
297                 pkgname = _string_get(pkgname);
298
299                 ret = notification_noti_delete_by_priv_id_get_changes(pkgname, priv_id, &num_changes);
300
301                 DbgPrint("priv_id: [%d] num_delete:%d\n", priv_id, num_changes);
302                 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
303                 if (packet_reply) {
304                         if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
305                                 ErrPrint("failed to send reply packet:%d\n", ret_p);
306                         }
307                         packet_destroy(packet_reply);
308                 } else {
309                         ErrPrint("failed to create a reply packet\n");
310                 }
311
312                 if (ret != NOTIFICATION_ERROR_NONE || num_changes <= 0) {
313                         ErrPrint("failed to delete a notification:%d %d\n", ret, num_changes);
314                         return ;
315                 }
316
317                 packet_service = packet_create("del_noti_single", "ii", 1, priv_id);
318                 if (packet_service != NULL) {
319                         if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
320                                 ErrPrint("failed to send a multicast packet: %d\n", ret_p);
321                         }
322                         packet_destroy(packet_service);
323                 }
324         } else {
325                 ErrPrint("Failed to get data from the packet");
326         }
327 }
328
329 static void _handler_delete_multiple(struct tcb *tcb, struct packet *packet, void *data)
330 {
331         int ret = 0, ret_p = 0;
332         struct packet *packet_reply = NULL;
333         struct packet *packet_service = NULL;
334         char *pkgname = NULL;
335         notification_type_e type = 0;
336         int num_deleted = 0;
337         int *list_deleted = NULL;
338
339         if (packet_get(packet, "si", &pkgname, &type) == 2) {
340                 pkgname = _string_get(pkgname);
341                 DbgPrint("pkgname: [%s] type: [%d]\n", pkgname, type);
342
343                 ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted);
344                 DbgPrint("ret: [%d] num_deleted: [%d]\n", ret, num_deleted);
345
346                 packet_reply = packet_create_reply(packet, "ii", ret, num_deleted);
347                 if (packet_reply) {
348                         if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
349                                 ErrPrint("failed to send reply packet:%d\n", ret_p);
350                         }
351                         packet_destroy(packet_reply);
352                 } else {
353                         ErrPrint("failed to create a reply packet\n");
354                 }
355
356                 if (ret != NOTIFICATION_ERROR_NONE) {
357                         ErrPrint("failed to delete notifications:%d\n", ret);
358                         if (list_deleted != NULL) {
359                                 DbgFree(list_deleted);
360                         }
361                         return ;
362                 }
363
364                 if (num_deleted > 0) {
365                         if (num_deleted <= NOTIFICATION_DEL_PACKET_UNIT) {
366                                 packet_service = _packet_create_with_list(num_deleted, list_deleted, 0);
367
368                                 if (packet_service) {
369                                         if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
370                                                 ErrPrint("failed to send a multicast packet: %d\n", ret_p);
371                                         }
372                                         packet_destroy(packet_service);
373                                 } else {
374                                         ErrPrint("failed to create a multicast packet\n");
375                                 }
376                         } else {
377                                 int set = 0;
378                                 int set_total = num_deleted / NOTIFICATION_DEL_PACKET_UNIT;
379
380                                 for (set = 0; set <= set_total; set++) {
381                                         packet_service = _packet_create_with_list(num_deleted,
382                                                         list_deleted, set * NOTIFICATION_DEL_PACKET_UNIT);
383
384                                         if (packet_service) {
385                                                 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
386                                                         ErrPrint("failed to send a multicast packet:%d\n", ret_p);
387                                                 }
388                                                 packet_destroy(packet_service);
389                                         } else {
390                                                 ErrPrint("failed to create a multicast packet\n");
391                                         }
392                                 }
393                         }
394                 }
395
396                 if (list_deleted != NULL) {
397                         DbgFree(list_deleted);
398                         list_deleted = NULL;
399                 }
400         } else {
401                 ErrPrint("Failed to get data from the packet");
402         }
403 }
404
405 static void _handler_noti_property_set(struct tcb *tcb, struct packet *packet, void *data)
406 {
407         int ret = 0, ret_p = 0;
408         struct packet *packet_reply = NULL;
409         char *pkgname = NULL;
410         char *property = NULL;
411         char *value = NULL;
412
413         if (packet_get(packet, "sss", &pkgname, &property, &value) == 3) {
414                 pkgname = _string_get(pkgname);
415                 property = _string_get(property);
416                 value = _string_get(value);
417
418                 ret = notification_setting_db_set(pkgname, property, value);
419
420                 packet_reply = packet_create_reply(packet, "ii", ret, ret);
421                 if (packet_reply) {
422                         if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
423                                 ErrPrint("failed to send reply packet:%d\n", ret_p);
424                         }
425                         packet_destroy(packet_reply);
426                 } else {
427                         ErrPrint("failed to create a reply packet\n");
428                 }
429
430                 if (ret != NOTIFICATION_ERROR_NONE) {
431                         ErrPrint("failed to set noti property:%d\n", ret);
432                 }
433         } else {
434                 ErrPrint("Failed to get data from the packet");
435         }
436 }
437
438 static void _handler_noti_property_get(struct tcb *tcb, struct packet *packet, void *data)
439 {
440         int ret = 0, ret_p = 0;
441         struct packet *packet_reply = NULL;
442         char *pkgname = NULL;
443         char *property = NULL;
444         char *value = NULL;
445
446         if (packet_get(packet, "sss", &pkgname, &property) == 2) {
447                 pkgname = _string_get(pkgname);
448                 property = _string_get(property);
449
450                 ret = notification_setting_db_get(pkgname, property, &value);
451
452                 packet_reply = packet_create_reply(packet, "is", ret, value);
453                 if (packet_reply) {
454                         if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
455                                 ErrPrint("failed to send reply packet:%d\n", ret_p);
456                         }
457                         packet_destroy(packet_reply);
458                 } else {
459                         ErrPrint("failed to create a reply packet\n");
460                 }
461
462                 if (value != NULL) {
463                         DbgFree(value);
464                 }
465         }
466 }
467
468 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
469 {
470         int ret = 0;
471         struct packet *packet_reply;
472
473         ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
474
475         packet_reply = packet_create_reply(packet, "i", ret);
476         if (packet_reply) {
477                 if ((ret = service_common_unicast_packet(tcb, packet_reply)) < 0) {
478                         ErrPrint("failed to send reply packet:%d\n", ret);
479                 }
480                 packet_destroy(packet_reply);
481         } else {
482                 ErrPrint("failed to create a reply packet\n");
483         }
484 }
485
486 static void _handler_post_toast_message(struct tcb *tcb, struct packet *packet, void *data)
487 {
488         int ret = 0;
489         struct packet *packet_reply = NULL;
490
491         packet_reply = packet_create_reply(packet, "i", ret);
492         if (packet_reply) {
493                 if ((ret = service_common_unicast_packet(tcb, packet_reply)) < 0) {
494                         ErrPrint("failed to send reply packet:%d\n", ret);
495                 }
496                 packet_destroy(packet_reply);
497         } else {
498                 ErrPrint("failed to create a reply packet\n");
499         }
500
501         if ((ret = service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE)) < 0) {
502                 ErrPrint("failed to send a multicast packet:%d\n", ret);
503         }
504
505 }
506
507 /*!
508  * SERVICE PERMISSION CHECK
509  */
510 static void _permission_check_common(struct tcb *tcb, struct packet *packet)
511 {
512         int ret_p = 0;
513         struct packet *packet_reply = NULL;
514
515         packet_reply = packet_create_reply(packet, "ii", NOTIFICATION_ERROR_PERMISSION_DENIED, 0);
516         if (packet_reply) {
517                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
518                         ErrPrint("Failed to send a reply packet:%d", ret_p);
519                 }
520                 packet_destroy(packet_reply);
521         } else {
522                 ErrPrint("Failed to create a reply packet");
523         }
524 }
525
526 static void _permission_check_refresh(struct tcb *tcb, struct packet *packet)
527 {
528         int ret_p = 0;
529         struct packet *packet_reply = NULL;
530
531         packet_reply = packet_create_reply(packet, "i", NOTIFICATION_ERROR_PERMISSION_DENIED);
532         if (packet_reply) {
533                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
534                         ErrPrint("Failed to send a reply packet:%d", ret_p);
535                 }
536                 packet_destroy(packet_reply);
537         } else {
538                 ErrPrint("Failed to create a reply packet");
539         }
540 }
541
542 static void _permission_check_property_get(struct tcb *tcb, struct packet *packet)
543 {
544         int ret_p = 0;
545         struct packet *packet_reply = NULL;
546
547         packet_reply = packet_create_reply(packet, "is", NOTIFICATION_ERROR_PERMISSION_DENIED, NULL);
548         if (packet_reply) {
549                 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
550                         ErrPrint("Failed to send a reply packet:%d", ret_p);
551                 }
552                 packet_destroy(packet_reply);
553         } else {
554                 ErrPrint("Failed to create a reply packet");
555         }
556 }
557
558 static int _persmission_check(int fd, struct noti_service *service)
559 {
560         int ret;
561
562         if (service->rule != NULL && service->access != NULL) {
563                 ret = security_server_check_privilege_by_sockfd(fd, service->rule, service->access);
564                 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
565                         ErrPrint("SMACK:Access denied\n");
566                         return 0;
567                 }
568         }
569
570         return 1;
571 }
572
573 /*!
574  * NOTIFICATION SERVICE INITIALIZATION
575  */
576 static void _notification_data_init(void)
577 {
578         int property = 0;
579         int priv_id = 0;
580         char *noti_pkgname = NULL;
581         notification_h noti = NULL;
582         notification_list_h noti_list = NULL;
583         notification_list_h noti_list_head = NULL;
584         notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
585
586         notification_get_list(NOTIFICATION_TYPE_NONE, -1, &noti_list);
587         noti_list_head = noti_list;
588
589         while (noti_list != NULL) {
590                 noti = notification_list_get_data(noti_list);
591                 if (noti) {
592                         notification_get_id(noti, NULL, &priv_id);
593                         notification_get_pkgname(noti, &noti_pkgname);
594                         notification_get_property(noti, &property);
595                         notification_get_type(noti, &noti_type);
596
597                         if (noti_type == NOTIFICATION_TYPE_ONGOING
598                                         || property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
599                                 notification_noti_delete_by_priv_id(noti_pkgname, priv_id);
600                         }
601                 }
602                 noti_list = notification_list_get_next(noti_list);
603         }
604
605         if (noti_list_head != NULL) {
606                 notification_free_list(noti_list_head);
607         }
608 }
609
610 static void _notification_init(void) {
611         int ret = -1;
612         int restart_count = 0;
613
614         ret = vconf_get_int(VCONFKEY_MASTER_RESTART_COUNT, &restart_count);
615         if (ret == 0 && restart_count <= 1) {
616                 _notification_data_init();
617         }
618 }
619
620 /*!
621  * SERVICE THREAD
622  */
623 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
624 {
625         int i = 0;
626         const char *command;
627
628         static struct noti_service service_req_table[] = {
629                 {
630                         .cmd = "add_noti",
631                         .handler = _handler_check_noti_by_tag,
632                         .rule = "data-provider-master::notification.client",
633                         .access = "w",
634                         .handler_access_error = _permission_check_common,
635                 },
636                 {
637                         .cmd = "update_noti",
638                         .handler = _handler_update,
639                         .rule = "data-provider-master::notification.client",
640                         .access = "w",
641                         .handler_access_error = _permission_check_common,
642                 },
643                 {
644                         .cmd = "load_noti_by_tag",
645                         .handler = _handler_load_noti_by_tag,
646                         .rule = "data-provider-master::notification.client",
647                         .access = "r",
648                         .handler_access_error = _permission_check_common,
649                 },
650                 {
651                         .cmd = "refresh_noti",
652                         .handler = _handler_refresh,
653                         .rule = "data-provider-master::notification.client",
654                         .access = "w",
655                         .handler_access_error = _permission_check_refresh,
656                 },
657                 {
658                         .cmd = "del_noti_single",
659                         .handler = _handler_delete_single,
660                         .rule = "data-provider-master::notification.client",
661                         .access = "w",
662                         .handler_access_error = _permission_check_common,
663                 },
664                 {
665                         .cmd = "del_noti_multiple",
666                         .handler = _handler_delete_multiple,
667                         .rule = "data-provider-master::notification.client",
668                         .access = "w",
669                         .handler_access_error = _permission_check_common,
670                 },
671                 {
672                         .cmd = "set_noti_property",
673                         .handler = _handler_noti_property_set,
674                         .rule = "data-provider-master::notification.client",
675                         .access = "w",
676                         .handler_access_error = _permission_check_common,
677                 },
678                 {
679                         .cmd = "get_noti_property",
680                         .handler = _handler_noti_property_get,
681                         .rule = "data-provider-master::notification.client",
682                         .access = "r",
683                         .handler_access_error = _permission_check_property_get,
684                 },
685                 {
686                         .cmd = "service_register",
687                         .handler = _handler_service_register,
688                         .rule = NULL,
689                         .access = NULL,
690                         .handler_access_error = NULL,
691                 },
692                 {
693                         .cmd = "post_toast",
694                         .handler = _handler_post_toast_message,
695                         .rule = NULL,
696                         .access = NULL,
697                         .handler_access_error = NULL,
698                 },
699                 {
700                         .cmd = NULL,
701                         .handler = NULL,
702                         .rule = NULL,
703                         .access = NULL,
704                         .handler_access_error = NULL,
705                 },
706         };
707
708         if (!packet) {
709                 DbgPrint("TCB: %p is terminated\n", tcb);
710                 return 0;
711         }
712
713         command = packet_command(packet);
714         if (!command) {
715                 ErrPrint("Invalid command\n");
716                 return -EINVAL;
717         }
718
719         switch (packet_type(packet)) {
720         case PACKET_REQ:
721                 /* Need to send reply packet */
722                 DbgPrint("%p REQ: Command: [%s]\n", tcb, command);
723
724                 for (i = 0; service_req_table[i].cmd; i++) {
725                         if (strcmp(service_req_table[i].cmd, command)) {
726                                 continue;
727                         }
728
729                         if (_persmission_check(tcb_fd(tcb), &(service_req_table[i])) == 1) {
730                                 service_req_table[i].handler(tcb, packet, data);
731                         } else {
732                                 if (service_req_table[i].handler_access_error != NULL) {
733                                         service_req_table[i].handler_access_error(tcb, packet);
734                                 }
735                         }
736                         break;
737                 }
738
739                 break;
740         case PACKET_REQ_NOACK:
741                 break;
742         case PACKET_ACK:
743                 break;
744         default:
745                 ErrPrint("Packet type is not valid[%s]\n", command);
746                 return -EINVAL;
747         }
748
749         /*!
750          * return value has no meanning,
751          * it will be printed by dlogutil.
752          */
753         return 0;
754 }
755
756
757 /*!
758  * MAIN THREAD
759  * Do not try to do anyother operation in these functions
760  */
761 HAPI int notification_service_init(void)
762 {
763         if (s_info.svc_ctx) {
764                 ErrPrint("Already initialized\n");
765                 return DBOX_STATUS_ERROR_ALREADY;
766         }
767
768         _notification_init();
769
770         s_info.svc_ctx = service_common_create(NOTIFICATION_SOCKET, service_thread_main, NULL);
771         if (!s_info.svc_ctx) {
772                 ErrPrint("Unable to activate service thread\n");
773                 return DBOX_STATUS_ERROR_FAULT;
774         }
775
776         if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
777                 if (errno != EOPNOTSUPP) {
778                         ErrPrint("Unable to set SMACK label(%d)\n", errno);
779                         service_common_destroy(s_info.svc_ctx);
780                         s_info.svc_ctx = NULL;
781                         return DBOX_STATUS_ERROR_FAULT;
782                 }
783         }
784
785         if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), NOTIFICATION_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
786                 if (errno != EOPNOTSUPP) {
787                         ErrPrint("Unable to set SMACK label(%d)\n", errno);
788                         service_common_destroy(s_info.svc_ctx);
789                         s_info.svc_ctx = NULL;
790                         return DBOX_STATUS_ERROR_FAULT;
791                 }
792         }
793
794         DbgPrint("Successfully initiated\n");
795         return DBOX_STATUS_ERROR_NONE;
796 }
797
798 HAPI int notification_service_fini(void)
799 {
800         if (!s_info.svc_ctx) {
801                 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
802         }
803
804         service_common_destroy(s_info.svc_ctx);
805         s_info.svc_ctx = NULL;
806         DbgPrint("Successfully Finalized\n");
807         return DBOX_STATUS_ERROR_NONE;
808 }
809
810 /* End of a file */