2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include <notification_ipc.h>
20 #include <notification_noti.h>
21 #include <notification_error.h>
23 #include "service_common.h"
25 #ifndef NOTIFICATION_ADDR
26 #define NOTIFICATION_ADDR "/tmp/.notification.service"
29 #ifndef NOTIFICATION_DEL_PACKET_UNIT
30 #define NOTIFICATION_DEL_PACKET_UNIT 10
34 Eina_List *context_list;
35 struct service_context *svc_ctx;
37 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
38 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
48 void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
52 * FUNCTIONS to handle notifcation
54 static inline int get_priv_id(int num_deleted, int *list_deleted, int index) {
55 if (index < num_deleted) {
56 return *(list_deleted + index);
62 static inline char *get_string(char *string)
67 if (string[0] == '\0') {
74 static inline struct packet *create_packet_from_deleted_list(int op_num, int *list, int start_index) {
78 ((op_num - start_index) > NOTIFICATION_DEL_PACKET_UNIT) ? NOTIFICATION_DEL_PACKET_UNIT : op_num - start_index,
79 get_priv_id(op_num, list, start_index),
80 get_priv_id(op_num, list, start_index + 1),
81 get_priv_id(op_num, list, start_index + 2),
82 get_priv_id(op_num, list, start_index + 3),
83 get_priv_id(op_num, list, start_index + 4),
84 get_priv_id(op_num, list, start_index + 5),
85 get_priv_id(op_num, list, start_index + 6),
86 get_priv_id(op_num, list, start_index + 7),
87 get_priv_id(op_num, list, start_index + 8),
88 get_priv_id(op_num, list, start_index + 9)
95 static void _handler_insert(struct tcb *tcb, struct packet *packet, void *data)
99 struct packet *packet_reply = NULL;
100 struct packet *packet_service = NULL;
101 notification_h noti = NULL;
103 noti = notification_create(NOTIFICATION_TYPE_NOTI);
105 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
106 ret = notification_noti_insert(noti);
107 if (ret != NOTIFICATION_ERROR_NONE) {
108 notification_free(noti);
112 notification_get_id(noti, NULL, &priv_id);
113 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
115 service_common_unicast_packet(tcb, packet_reply);
116 packet_destroy(packet_reply);
119 packet_service = notification_ipc_make_packet_from_noti(noti, "add_noti", 2);
120 if (packet_service != NULL) {
121 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
122 packet_destroy(packet_service);
125 notification_free(noti);
129 static void _handler_update(struct tcb *tcb, struct packet *packet, void *data)
133 struct packet *packet_reply = NULL;
134 struct packet *packet_service = NULL;
135 notification_h noti = NULL;
137 noti = notification_create(NOTIFICATION_TYPE_NOTI);
139 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
140 ret = notification_noti_update(noti);
141 if (ret != NOTIFICATION_ERROR_NONE) {
142 notification_free(noti);
146 notification_get_id(noti, NULL, &priv_id);
147 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
149 service_common_unicast_packet(tcb, packet_reply);
150 packet_destroy(packet_reply);
153 packet_service = notification_ipc_make_packet_from_noti(noti, "update_noti", 2);
154 if (packet_service != NULL) {
155 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
156 packet_destroy(packet_service);
159 notification_free(noti);
163 static void _handler_refresh(struct tcb *tcb, struct packet *packet, void *data)
165 int ret = NOTIFICATION_ERROR_NONE;
166 struct packet *packet_reply = NULL;
168 packet_reply = packet_create_reply(packet, "i", ret);
170 service_common_unicast_packet(tcb, packet_reply);
171 packet_destroy(packet_reply);
174 service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE);
177 static void _handler_delete_single(struct tcb *tcb, struct packet *packet, void *data)
181 struct packet *packet_reply = NULL;
182 struct packet *packet_service = NULL;
183 char *pkgname = NULL;
185 if (packet_get(packet, "si", &pkgname, &priv_id) == 2) {
186 pkgname = get_string(pkgname);
188 ret = notification_noti_delete_by_priv_id(pkgname, priv_id);
190 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
192 service_common_unicast_packet(tcb, packet_reply);
193 packet_destroy(packet_reply);
196 packet_service = packet_create("del_noti_single", "ii", 1, priv_id);
197 if (packet_service != NULL) {
198 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
199 packet_destroy(packet_service);
204 static void _handler_delete_multiple(struct tcb *tcb, struct packet *packet, void *data)
207 struct packet *packet_reply = NULL;
208 struct packet *packet_service = NULL;
209 char *pkgname = NULL;
210 notification_type_e type = 0;
212 int *list_deleted = NULL;
214 if (packet_get(packet, "si", &pkgname, &type) == 2) {
215 pkgname = get_string(pkgname);
217 ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted);
219 packet_reply = packet_create_reply(packet, "ii", ret, num_deleted);
221 service_common_unicast_packet(tcb, packet_reply);
222 packet_destroy(packet_reply);
225 if (num_deleted > 0) {
226 if (num_deleted <= NOTIFICATION_DEL_PACKET_UNIT) {
227 packet_service = create_packet_from_deleted_list(num_deleted, list_deleted, 0);
229 if (packet_service) {
230 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
231 packet_destroy(packet_service);
235 int set_total = num_deleted / NOTIFICATION_DEL_PACKET_UNIT;
237 for (set = 0; set <= set_total; set++) {
238 packet_service = create_packet_from_deleted_list(num_deleted,
239 list_deleted, set * NOTIFICATION_DEL_PACKET_UNIT);
241 if (packet_service) {
242 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
243 packet_destroy(packet_service);
249 if (list_deleted != NULL) {
256 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
258 struct packet *packet_reply;
261 ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
263 packet_reply = packet_create_reply(packet, "i", ret);
265 service_common_unicast_packet(tcb, packet_reply);
266 packet_destroy(packet_reply);
273 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
277 static struct noti_service service_req_table[] = {
280 .handler = _handler_insert,
283 .cmd = "update_noti",
284 .handler = _handler_update,
287 .cmd = "refresh_noti",
288 .handler = _handler_refresh,
291 .cmd = "del_noti_single",
292 .handler = _handler_delete_single,
295 .cmd = "del_noti_multiple",
296 .handler = _handler_delete_multiple,
299 .cmd = "service_register",
300 .handler = _handler_service_register,
312 command = packet_command(packet);
317 switch (packet_type(packet)) {
319 /* Need to send reply packet */
320 for (i = 0; service_req_table[i].cmd; i++) {
321 if (strcmp(service_req_table[i].cmd, command))
324 service_req_table[i].handler(tcb, packet, data);
329 case PACKET_REQ_NOACK:
338 * return value has no meanning,
339 * it will be printed by dlogutil.
347 * Do not try to do anyother operation in these functions
349 int notification_service_init(void)
351 if (s_info.svc_ctx) {
355 s_info.svc_ctx = service_common_create(NOTIFICATION_ADDR, service_thread_main, NULL);
356 if (!s_info.svc_ctx) {
363 int notification_service_fini(void)
368 service_common_destroy(s_info.svc_ctx);