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.
21 #include <livebox-errno.h>
24 #include <notification_ipc.h>
25 #include <notification_noti.h>
26 #include <notification_error.h>
28 #include "service_common.h"
33 #ifndef NOTIFICATION_ADDR
34 #define NOTIFICATION_ADDR "/tmp/.notification.service"
37 #ifndef NOTIFICATION_DEL_PACKET_UNIT
38 #define NOTIFICATION_DEL_PACKET_UNIT 10
42 Eina_List *context_list;
43 struct service_context *svc_ctx;
45 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
46 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
56 void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
60 * FUNCTIONS to handle notifcation
62 static inline int get_priv_id(int num_deleted, int *list_deleted, int index) {
63 if (index < num_deleted) {
64 return *(list_deleted + index);
70 static inline char *get_string(char *string)
75 if (string[0] == '\0') {
82 static inline struct packet *create_packet_from_deleted_list(int op_num, int *list, int start_index) {
86 ((op_num - start_index) > NOTIFICATION_DEL_PACKET_UNIT) ? NOTIFICATION_DEL_PACKET_UNIT : op_num - start_index,
87 get_priv_id(op_num, list, start_index),
88 get_priv_id(op_num, list, start_index + 1),
89 get_priv_id(op_num, list, start_index + 2),
90 get_priv_id(op_num, list, start_index + 3),
91 get_priv_id(op_num, list, start_index + 4),
92 get_priv_id(op_num, list, start_index + 5),
93 get_priv_id(op_num, list, start_index + 6),
94 get_priv_id(op_num, list, start_index + 7),
95 get_priv_id(op_num, list, start_index + 8),
96 get_priv_id(op_num, list, start_index + 9)
103 static void _handler_insert(struct tcb *tcb, struct packet *packet, void *data)
107 struct packet *packet_reply = NULL;
108 struct packet *packet_service = NULL;
109 notification_h noti = NULL;
111 noti = notification_create(NOTIFICATION_TYPE_NOTI);
113 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
114 ret = notification_noti_insert(noti);
115 if (ret != NOTIFICATION_ERROR_NONE) {
116 ErrPrint("failed to insert a notification\n");
117 notification_free(noti);
121 notification_get_id(noti, NULL, &priv_id);
122 DbgPrint("priv_id: [%d]\n", priv_id);
123 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
125 service_common_unicast_packet(tcb, packet_reply);
126 packet_destroy(packet_reply);
129 packet_service = notification_ipc_make_packet_from_noti(noti, "add_noti", 2);
130 if (packet_service != NULL) {
131 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
132 packet_destroy(packet_service);
135 ErrPrint("Failed to create the packet");
137 notification_free(noti);
141 static void _handler_update(struct tcb *tcb, struct packet *packet, void *data)
145 struct packet *packet_reply = NULL;
146 struct packet *packet_service = NULL;
147 notification_h noti = NULL;
149 noti = notification_create(NOTIFICATION_TYPE_NOTI);
151 if (notification_ipc_make_noti_from_packet(noti, packet) == NOTIFICATION_ERROR_NONE) {
152 ret = notification_noti_update(noti);
153 if (ret != NOTIFICATION_ERROR_NONE) {
154 ErrPrint("failed to update a notification\n");
155 notification_free(noti);
159 notification_get_id(noti, NULL, &priv_id);
160 DbgPrint("priv_id: [%d]\n", priv_id);
161 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
163 service_common_unicast_packet(tcb, packet_reply);
164 packet_destroy(packet_reply);
167 packet_service = notification_ipc_make_packet_from_noti(noti, "update_noti", 2);
168 if (packet_service != NULL) {
169 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
170 packet_destroy(packet_service);
173 ErrPrint("Failed to create the packet");
175 notification_free(noti);
179 static void _handler_refresh(struct tcb *tcb, struct packet *packet, void *data)
181 int ret = NOTIFICATION_ERROR_NONE;
182 struct packet *packet_reply = NULL;
184 packet_reply = packet_create_reply(packet, "i", ret);
186 service_common_unicast_packet(tcb, packet_reply);
187 packet_destroy(packet_reply);
190 service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE);
193 static void _handler_delete_single(struct tcb *tcb, struct packet *packet, void *data)
197 struct packet *packet_reply = NULL;
198 struct packet *packet_service = NULL;
199 char *pkgname = NULL;
201 if (packet_get(packet, "si", &pkgname, &priv_id) == 2) {
202 pkgname = get_string(pkgname);
204 ret = notification_noti_delete_by_priv_id(pkgname, priv_id);
206 DbgPrint("priv_id: [%d]\n", priv_id);
207 packet_reply = packet_create_reply(packet, "ii", ret, priv_id);
209 service_common_unicast_packet(tcb, packet_reply);
210 packet_destroy(packet_reply);
213 packet_service = packet_create("del_noti_single", "ii", 1, priv_id);
214 if (packet_service != NULL) {
215 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
216 packet_destroy(packet_service);
219 ErrPrint("Failed to get data from the packet");
223 static void _handler_delete_multiple(struct tcb *tcb, struct packet *packet, void *data)
226 struct packet *packet_reply = NULL;
227 struct packet *packet_service = NULL;
228 char *pkgname = NULL;
229 notification_type_e type = 0;
231 int *list_deleted = NULL;
233 if (packet_get(packet, "si", &pkgname, &type) == 2) {
234 pkgname = get_string(pkgname);
235 DbgPrint("pkgname: [%s] type: [%d]\n", pkgname, type);
237 ret = notification_noti_delete_all(type, pkgname, &num_deleted, &list_deleted);
238 DbgPrint("ret: [%d] num_deleted: [%d]\n", ret, num_deleted);
240 packet_reply = packet_create_reply(packet, "ii", ret, num_deleted);
242 service_common_unicast_packet(tcb, packet_reply);
243 packet_destroy(packet_reply);
246 if (num_deleted > 0) {
247 if (num_deleted <= NOTIFICATION_DEL_PACKET_UNIT) {
248 packet_service = create_packet_from_deleted_list(num_deleted, list_deleted, 0);
250 if (packet_service) {
251 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
252 packet_destroy(packet_service);
256 int set_total = num_deleted / NOTIFICATION_DEL_PACKET_UNIT;
258 for (set = 0; set <= set_total; set++) {
259 packet_service = create_packet_from_deleted_list(num_deleted,
260 list_deleted, set * NOTIFICATION_DEL_PACKET_UNIT);
262 if (packet_service) {
263 service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE);
264 packet_destroy(packet_service);
270 if (list_deleted != NULL) {
275 ErrPrint("Failed to get data from the packet");
279 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
281 struct packet *packet_reply;
284 ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
286 packet_reply = packet_create_reply(packet, "i", ret);
288 service_common_unicast_packet(tcb, packet_reply);
289 packet_destroy(packet_reply);
296 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
300 static struct noti_service service_req_table[] = {
303 .handler = _handler_insert,
306 .cmd = "update_noti",
307 .handler = _handler_update,
310 .cmd = "refresh_noti",
311 .handler = _handler_refresh,
314 .cmd = "del_noti_single",
315 .handler = _handler_delete_single,
318 .cmd = "del_noti_multiple",
319 .handler = _handler_delete_multiple,
322 .cmd = "service_register",
323 .handler = _handler_service_register,
331 DbgPrint("TCB: %p, Packet: %p\n", tcb, packet);
333 command = packet_command(packet);
335 ErrPrint("Invalid command\n");
338 DbgPrint("Command: %s, Packet type[%d]\n", command, packet_type(packet));
340 switch (packet_type(packet)) {
342 /* Need to send reply packet */
343 DbgPrint("REQ: Command: [%s]\n", command);
345 for (i = 0; service_req_table[i].cmd; i++) {
346 if (strcmp(service_req_table[i].cmd, command))
349 service_req_table[i].handler(tcb, packet, data);
354 case PACKET_REQ_NOACK:
359 ErrPrint("Packet type is not valid[%s]\n", command);
364 * return value has no meanning,
365 * it will be printed by dlogutil.
373 * Do not try to do anyother operation in these functions
375 HAPI int notification_service_init(void)
377 if (s_info.svc_ctx) {
378 ErrPrint("Already initialized\n");
379 return LB_STATUS_ERROR_ALREADY;
382 s_info.svc_ctx = service_common_create(NOTIFICATION_ADDR, service_thread_main, NULL);
383 if (!s_info.svc_ctx) {
384 ErrPrint("Unable to activate service thread\n");
385 return LB_STATUS_ERROR_FAULT;
388 DbgPrint("Successfully initiated\n");
389 return LB_STATUS_SUCCESS;
392 HAPI int notification_service_fini(void)
395 return LB_STATUS_ERROR_INVALID;
397 service_common_destroy(s_info.svc_ctx);
398 DbgPrint("Successfully Finalized\n");
399 return LB_STATUS_SUCCESS;