Various patches are applied
[platform/framework/web/data-provider-master.git] / src / shortcut_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 #include <livebox-errno.h>
22 #include <packet.h>
23
24 #include <Eina.h>
25
26 #include "service_common.h"
27 #include "debug.h"
28 #include "util.h"
29 #include "conf.h"
30
31 #define SHORTCUT_ADDR   "/tmp/.shortcut.service"
32
33 static struct info {
34         Eina_List *context_list;
35         struct service_context *svc_ctx;
36 } s_info = {
37         .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
38         .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
39 };
40
41 struct context {
42         struct tcb *tcb;
43         double seq;
44 };
45
46 /*!
47  * SERVICE THREAD
48  */
49 static inline int put_reply_context(struct tcb *tcb, double seq)
50 {
51         struct context *ctx;
52
53         ctx = malloc(sizeof(*ctx));
54         if (!ctx) {
55                 ErrPrint("Heap: %s\n", strerror(errno));
56                 return -ENOMEM;
57         }
58
59         ctx->tcb = tcb;
60         ctx->seq = seq; /* Could we this sequence value is uniq? */
61
62         s_info.context_list = eina_list_append(s_info.context_list, ctx);
63         return 0;
64 }
65
66 /*!
67  * SERVICE THREAD
68  */
69 static inline struct tcb *get_reply_context(double seq)
70 {
71         Eina_List *l;
72         Eina_List *n;
73         struct context *ctx;
74         struct tcb *tcb;
75
76         tcb = NULL;
77         EINA_LIST_FOREACH_SAFE(s_info.context_list, l, n, ctx) {
78                 if (ctx->seq != seq)
79                         continue;
80
81                 s_info.context_list = eina_list_remove(s_info.context_list, ctx);
82                 tcb = ctx->tcb;
83                 free(ctx);
84                 break;
85         }
86
87         return tcb;
88 }
89
90 /*!
91  * SERVICE THREAD
92  */
93 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
94 {
95         const char *command;
96
97         DbgPrint("TCB: %p, Packet: %p\n", tcb, packet);
98
99         command = packet_command(packet);
100         if (!command) {
101                 ErrPrint("Invalid command\n");
102                 return -EINVAL;
103         }
104         DbgPrint("Command: %s, Packet type[%d]\n", command, packet_type(packet));
105
106         switch (packet_type(packet)) {
107         case PACKET_REQ:
108                 /* Need to send reply packet */
109                 DbgPrint("REQ: Command: [%s]\n", command);
110                 if (service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE) < 0)
111                         ErrPrint("Unable to send service request packet\n");
112                 else
113                         (void)put_reply_context(tcb, packet_seq(packet));
114                 break;
115         case PACKET_REQ_NOACK:
116                 /* Doesn't need to send reply packet */
117                 DbgPrint("REQ_NOACK: Command: [%s]\n", command);
118                 if (!strcmp(command, "service_register")) {
119                         tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
120                         break;
121                 }
122
123                 if (service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE) < 0)
124                         ErrPrint("Unable to send service reuqest packet\n");
125                 break;
126         case PACKET_ACK:
127                 /* Okay, client(or app) send a reply packet to us. */
128                 DbgPrint("ACK: Command: [%s]\n", command);
129                 tcb = get_reply_context(packet_seq(packet));
130                 if (!tcb) {
131                         ErrPrint("There is no proper context\n");
132                         break;
133                 }
134
135                 if (service_common_unicast_packet(tcb, packet) < 0)
136                         ErrPrint("Unable to send reply packet\n");
137                 break;
138         default:
139                 ErrPrint("Packet type is not valid[%s]\n", command);
140                 return -EINVAL;
141         }
142
143         /*!
144          * return value has no meanning,
145          * it will be printed by dlogutil.
146          */
147         return 0;
148 }
149
150
151 /*!
152  * MAIN THREAD
153  * Do not try to do anyother operation in these functions
154  */
155
156 HAPI int shortcut_service_init(void)
157 {
158         if (s_info.svc_ctx) {
159                 ErrPrint("Already initialized\n");
160                 return LB_STATUS_ERROR_ALREADY;
161         }
162
163         s_info.svc_ctx = service_common_create(SHORTCUT_ADDR, service_thread_main, NULL);
164         if (!s_info.svc_ctx) {
165                 ErrPrint("Unable to activate service thread\n");
166                 return LB_STATUS_ERROR_FAULT;
167         }
168
169         DbgPrint("Successfully initiated\n");
170         return LB_STATUS_SUCCESS;
171 }
172
173 HAPI int shortcut_service_fini(void)
174 {
175         if (!s_info.svc_ctx)
176                 return LB_STATUS_ERROR_INVALID;
177
178         service_common_destroy(s_info.svc_ctx);
179         DbgPrint("Successfully Finalized\n");
180         return LB_STATUS_SUCCESS;
181 }
182
183 /* End of a file */