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.
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 ErrPrint("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;
178 command->ret_cb(command->handler, packet, command->data);
180 destroy_command(command);
184 static inline void push_command(struct command *command)
186 s_info.cmd_list = dlist_append(s_info.cmd_list, command);
187 master_rpc_check_and_fire_consumer();
192 * "handler" could be NULL
194 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)
196 struct command *command;
198 command = create_command(handler, packet);
200 ErrPrint("Failed to create a command\n");
201 packet_unref(packet);
202 return LB_STATUS_ERROR_FAULT;
205 command->ret_cb = ret_cb;
206 command->data = data;
207 command->ttl = DEFAULT_TTL;
208 command->type = TYPE_ACK;
211 prepend_command(command);
213 push_command(command);
215 packet_unref(packet);
216 return LB_STATUS_SUCCESS;
219 int master_rpc_request_only(struct livebox *handler, struct packet *packet)
221 struct command *command;
223 command = create_command(handler, packet);
225 ErrPrint("Failed to create a command\n");
226 packet_unref(packet);
227 return LB_STATUS_ERROR_FAULT;
230 command->ret_cb = NULL;
231 command->data = NULL;
233 command->type = TYPE_NOACK;
235 push_command(command);
236 packet_unref(packet);
237 return LB_STATUS_SUCCESS;
240 int master_rpc_clear_fault_package(const char *pkgname)
244 struct command *command;
247 return LB_STATUS_ERROR_INVALID;
249 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
250 if (!command->handler)
253 if (!strcmp(command->handler->pkgname, pkgname)) {
254 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
256 command->ret_cb(command->handler, NULL, command->data);
258 destroy_command(command);
265 int master_rpc_clear_all_request(void)
267 struct command *command;
271 dlist_foreach_safe(s_info.cmd_list, l, n, command) {
272 s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
275 command->ret_cb(command->handler, NULL, command->data);
277 destroy_command(command);
283 int master_rpc_sync_request(struct packet *packet)
285 struct packet *result;
288 result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f);
290 if (packet_get(result, "i", &ret) != 1) {
291 ErrPrint("Invalid result packet\n");
292 ret = LB_STATUS_ERROR_INVALID;
295 packet_unref(result);
297 ErrPrint("Failed to send a sync request\n");
298 ret = LB_STATUS_ERROR_FAULT;
301 packet_unref(packet);