2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <notification_ipc.h>
21 #include <notification_noti.h>
22 #include <notification_error.h>
24 #include "service_common.h"
26 #ifndef NOTIFICATION_ADDR
27 #define NOTIFICATION_ADDR "/tmp/.notification.service"
30 #ifndef NOTIFICATION_DEL_PACKET_UNIT
31 #define NOTIFICATION_DEL_PACKET_UNIT 10
35 Eina_List *context_list;
36 struct service_context *svc_ctx;
38 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
39 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
49 void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
53 * FUNCTIONS to handle notifcation
55 static inline int get_priv_id(int num_deleted, int *list_deleted, int index) {
56 if (index < num_deleted) {
57 return *(list_deleted + index);
63 static inline char *get_string(char *string)
68 if (string[0] == '\0') {
75 static inline struct packet *create_packet_from_deleted_list(int op_num, int *list, int start_index) {
79 ((op_num - start_index) > NOTIFICATION_DEL_PACKET_UNIT) ? NOTIFICATION_DEL_PACKET_UNIT : op_num - start_index,
80 get_priv_id(op_num, list, start_index),
81 get_priv_id(op_num, list, start_index + 1),
82 get_priv_id(op_num, list, start_index + 2),
83 get_priv_id(op_num, list, start_index + 3),
84 get_priv_id(op_num, list, start_index + 4),
85 get_priv_id(op_num, list, start_index + 5),
86 get_priv_id(op_num, list, start_index + 6),
87 get_priv_id(op_num, list, start_index + 7),
88 get_priv_id(op_num, list, start_index + 8),
89 get_priv_id(op_num, list, start_index + 9)
96 static void _handler_insert(struct tcb *tcb, struct packet *packet, void *data)
100 struct packet *packet_reply = NULL;
101 struct packet *packet_service = NULL;
102 notification_h noti = NULL;
104 noti = notification_create(NOTIFICATION_TYPE_NOTI);
106 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
107 ret = notification_noti_insert(noti);
108 if (ret != NOTIFICATION_ERROR_NONE) {
109 notification_free(noti);
113 notification_get_id(noti, NULL, &priv_id);
114 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
116 service_common_unicast_packet(tcb, packet_reply);
117 packet_destroy(packet_reply);
120 packet_service = notification_ipc_make_packet_from_noti(noti, "add_noti", 2);
121 if (packet_service != NULL) {
122 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
123 packet_destroy(packet_service);
126 notification_free(noti);
130 static void _handler_update(struct tcb *tcb, struct packet *packet, void *data)
134 struct packet *packet_reply = NULL;
135 struct packet *packet_service = NULL;
136 notification_h noti = NULL;
138 noti = notification_create(NOTIFICATION_TYPE_NOTI);
140 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
141 ret = notification_noti_update(noti);
142 if (ret != NOTIFICATION_ERROR_NONE) {
143 notification_free(noti);
147 notification_get_id(noti, NULL, &priv_id);
148 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
150 service_common_unicast_packet(tcb, packet_reply);
151 packet_destroy(packet_reply);
154 packet_service = notification_ipc_make_packet_from_noti(noti, "update_noti", 2);
155 if (packet_service != NULL) {
156 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
157 packet_destroy(packet_service);
160 notification_free(noti);
164 static void _handler_refresh(struct tcb *tcb, struct packet *packet, void *data)
166 int ret = NOTIFICATION_ERROR_NONE;
167 struct packet *packet_reply = NULL;
169 packet_reply = packet_create_reply(packet, "i", ret);
171 service_common_unicast_packet(tcb, packet_reply);
172 packet_destroy(packet_reply);
175 service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE);
178 static void _handler_delete_single(struct tcb *tcb, struct packet *packet, void *data)
182 struct packet *packet_reply = NULL;
183 struct packet *packet_service = NULL;
184 char *pkgname = NULL;
186 if (packet_get(packet, "si", &pkgname, &priv_id) == 2) {
187 pkgname = get_string(pkgname);
189 ret = notification_noti_delete_by_priv_id(pkgname, priv_id);
191 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
193 service_common_unicast_packet(tcb, packet_reply);
194 packet_destroy(packet_reply);
197 packet_service = packet_create("del_noti_single", "ii", 1, priv_id);
198 if (packet_service != NULL) {
199 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
200 packet_destroy(packet_service);
205 static void _handler_delete_multiple(struct tcb *tcb, struct packet *packet, void *data)
208 struct packet *packet_reply = NULL;
209 struct packet *packet_service = NULL;
210 char *pkgname = NULL;
211 notification_type_e type = 0;
213 int *list_deleted = NULL;
215 if (packet_get(packet, "si", &pkgname, &type) == 2) {
216 pkgname = get_string(pkgname);
218 ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted);
220 packet_reply = packet_create_reply(packet, "ii", ret, num_deleted);
222 service_common_unicast_packet(tcb, packet_reply);
223 packet_destroy(packet_reply);
226 if (num_deleted > 0) {
227 if (num_deleted <= NOTIFICATION_DEL_PACKET_UNIT) {
228 packet_service = create_packet_from_deleted_list(num_deleted, list_deleted, 0);
230 if (packet_service) {
231 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
232 packet_destroy(packet_service);
236 int set_total = num_deleted / NOTIFICATION_DEL_PACKET_UNIT;
238 for (set = 0; set <= set_total; set++) {
239 packet_service = create_packet_from_deleted_list(num_deleted,
240 list_deleted, set * NOTIFICATION_DEL_PACKET_UNIT);
242 if (packet_service) {
243 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
244 packet_destroy(packet_service);
250 if (list_deleted != NULL) {
257 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
259 struct packet *packet_reply;
262 ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
264 packet_reply = packet_create_reply(packet, "i", ret);
266 service_common_unicast_packet(tcb, packet_reply);
267 packet_destroy(packet_reply);
274 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
278 static struct noti_service service_req_table[] = {
281 .handler = _handler_insert,
284 .cmd = "update_noti",
285 .handler = _handler_update,
288 .cmd = "refresh_noti",
289 .handler = _handler_refresh,
292 .cmd = "del_noti_single",
293 .handler = _handler_delete_single,
296 .cmd = "del_noti_multiple",
297 .handler = _handler_delete_multiple,
300 .cmd = "service_register",
301 .handler = _handler_service_register,
313 command = packet_command(packet);
318 switch (packet_type(packet)) {
320 /* Need to send reply packet */
321 if (!check_cynara(tcb)) {
324 for (i = 0; service_req_table[i].cmd; i++) {
325 if (strcmp(service_req_table[i].cmd, command))
328 service_req_table[i].handler(tcb, packet, data);
333 case PACKET_REQ_NOACK:
342 * return value has no meanning,
343 * it will be printed by dlogutil.
351 * Do not try to do anyother operation in these functions
353 int notification_service_init(void)
355 if (s_info.svc_ctx) {
359 s_info.svc_ctx = service_common_create(NOTIFICATION_ADDR, service_thread_main, NULL);
360 if (!s_info.svc_ctx) {
367 int notification_service_fini(void)
372 service_common_destroy(s_info.svc_ctx);