2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.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.
26 #include <com-core_packet.h>
27 #include <livebox-errno.h>
32 #include "livebox_internal.h"
33 #include "master_rpc.h"
37 #define DEFAULT_TTL 10
38 #define REQUEST_DELAY 10
42 struct packet *packet;
43 struct livebox *handler;
44 void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data);
56 struct dlist *cmd_list;
62 static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data);
64 static inline struct command *pop_command(void)
67 struct command *command;
69 l = dlist_nth(s_info.cmd_list, 0);
73 command = dlist_data(l);
74 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
78 static inline struct command *create_command(struct livebox *handler, struct packet *packet)
80 struct command *command;
82 command = malloc(sizeof(*command));
84 ErrPrint("Failed to allocate mem for command\n");
88 command->handler = lb_ref(handler);
89 command->packet = packet_ref(packet);
93 static inline void destroy_command(struct command *command)
95 packet_unref(command->packet);
96 lb_unref(command->handler);
100 static gboolean cmd_consumer(gpointer user_data)
102 struct command *command;
104 command = pop_command();
106 s_info.cmd_timer = 0;
112 * Item will be deleted in the "done_cb"
114 * item->param be release by the g_dbus_proxy_call
115 * so to use it again from the done_cb function,
116 * increate the reference counter of the item->param
118 if (command->type == TYPE_NOACK) {
119 if (com_core_packet_send_only(client_fd(), command->packet) < 0)
120 ErrPrint("Failed to send a packet to master\n");
122 destroy_command(command);
124 if (com_core_packet_async_send(client_fd(), command->packet, 0u, done_cb, command) < 0) {
125 DbgPrint("Failed to send a packet to master\n");
127 command->ret_cb(command->handler, NULL, command->data);
128 destroy_command(command);
134 static inline void prepend_command(struct command *command)
136 s_info.cmd_list = dlist_prepend(s_info.cmd_list, command);
137 master_rpc_check_and_fire_consumer();
140 void master_rpc_check_and_fire_consumer(void)
142 if (!s_info.cmd_list || s_info.cmd_timer || client_fd() < 0)
145 s_info.cmd_timer = g_timeout_add(REQUEST_DELAY, cmd_consumer, NULL);
146 if (!s_info.cmd_timer)
147 ErrPrint("Failed to add timer\n");
150 static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data)
152 struct command *command;
159 * Release resource even if
160 * we failed to finish the method call
163 if (command->ttl > 0) {
164 prepend_command(command);
171 if (packet_get(packet, "i", &ret) != 1) {
172 ErrPrint("Invalid result packet\n");
173 ret = LB_STATUS_ERROR_INVALID;
176 DbgPrint("[%s] Returns: %d\n", packet_command(packet), ret);
180 command->ret_cb(command->handler, packet, command->data);
182 destroy_command(command);
186 static inline void push_command(struct command *command)
188 s_info.cmd_list = dlist_append(s_info.cmd_list, command);
189 master_rpc_check_and_fire_consumer();
194 * "handler" could be NULL
196 int master_rpc_async_request(struct livebox *handler, struct packet *packet, int urgent, void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data), void *data)
198 struct command *command;
200 command = create_command(handler, packet);
202 ErrPrint("Failed to create a command\n");
203 packet_unref(packet);
204 return LB_STATUS_ERROR_FAULT;
207 command->ret_cb = ret_cb;
208 command->data = data;
209 command->ttl = DEFAULT_TTL;
210 command->type = TYPE_ACK;
213 prepend_command(command);
215 push_command(command);
217 packet_unref(packet);
218 return LB_STATUS_SUCCESS;
221 int master_rpc_request_only(struct livebox *handler, struct packet *packet)
223 struct command *command;
225 command = create_command(handler, packet);
227 ErrPrint("Failed to create a command\n");
228 packet_unref(packet);
229 return LB_STATUS_ERROR_FAULT;
232 command->ret_cb = NULL;
233 command->data = NULL;
235 command->type = TYPE_NOACK;
237 push_command(command);
238 packet_unref(packet);
239 return LB_STATUS_SUCCESS;
242 int master_rpc_clear_fault_package(const char *pkgname)
246 struct command *command;
249 return LB_STATUS_ERROR_INVALID;
251 DbgPrint("Clear requests of the fault package(%s)\n", pkgname);
253 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
254 if (!command->handler)
257 if (!strcmp(command->handler->pkgname, pkgname)) {
258 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
260 command->ret_cb(command->handler, NULL, command->data);
262 destroy_command(command);
269 int master_rpc_clear_all_request(void)
271 struct command *command;
275 DbgPrint("Clear all pended requests\n");
277 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
278 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
281 command->ret_cb(command->handler, NULL, command->data);
283 destroy_command(command);
289 int master_rpc_sync_request(struct packet *packet)
291 struct packet *result;
294 result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f);
296 if (packet_get(result, "i", &ret) != 1) {
297 ErrPrint("Invalid result packet\n");
298 ret = LB_STATUS_ERROR_INVALID;
301 packet_unref(result);
303 ErrPrint("Failed to send a sync request\n");
304 ret = LB_STATUS_ERROR_FAULT;
307 packet_unref(packet);