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.
24 #include <com-core_packet.h>
26 #include <dynamicbox_errno.h>
27 #include <dynamicbox_conf.h>
28 #include <dynamicbox_service.h>
30 #include "client_life.h"
32 #include "client_rpc.h"
41 * Static component information structure.
44 Eina_List *command_list; /*!< Packet Q: Before sending the request, all request commands will stay here */
45 Ecore_Timer *command_consumer; /*!< This timer will consuming the command Q. sending them to the specified client */
48 .command_consumer = NULL,
52 int handle; /*!< Handler for communication with client */
56 struct packet *packet;
57 struct client_node *client; /*!< Target client. who should receive this command */
62 * Creating or Destroying command object
64 static inline struct command *create_command(struct client_node *client, struct packet *packet)
66 struct command *command;
68 command = calloc(1, sizeof(*command));
70 ErrPrint("Heap: %s\n", strerror(errno));
74 command->packet = packet_ref(packet);
75 command->client = client_ref(client);
80 static inline void destroy_command(struct command *command)
82 client_unref(command->client);
83 packet_unref(command->packet);
87 static inline int count_command(void)
89 return eina_list_count(s_info.command_list);
92 static inline struct command *pop_command(void)
94 struct command *command;
96 command = eina_list_nth(s_info.command_list, 0);
101 s_info.command_list = eina_list_remove(s_info.command_list, command);
105 static Eina_Bool command_consumer_cb(void *data)
107 struct command *command;
108 struct client_rpc *rpc;
111 command = pop_command();
113 s_info.command_consumer = NULL;
114 return ECORE_CALLBACK_CANCEL;
117 if (!command->client) {
118 DbgPrint("Has no client\n");
122 if (client_is_faulted(command->client)) {
123 ErrPrint("Client[%p] is faulted, discard command\n", command->client);
127 rpc = client_data(command->client, RPC_TAG);
129 ErrPrint("Client is not activated\n");
133 if (rpc->handle < 0) {
134 DbgPrint("RPC is not initialized\n");
138 ret = com_core_packet_send_only(rpc->handle, command->packet);
140 ErrPrint("Failed to send packet %d\n", ret);
144 destroy_command(command);
145 return ECORE_CALLBACK_RENEW;
148 static inline void push_command(struct command *command)
150 s_info.command_list = eina_list_append(s_info.command_list, command);
152 if (s_info.command_consumer) {
156 s_info.command_consumer = ecore_timer_add(DYNAMICBOX_CONF_PACKET_TIME, command_consumer_cb, NULL);
157 if (!s_info.command_consumer) {
158 ErrPrint("Failed to add command consumer\n");
159 s_info.command_list = eina_list_remove(s_info.command_list, command);
160 destroy_command(command);
164 HAPI int client_rpc_async_request(struct client_node *client, struct packet *packet)
166 struct command *command;
167 struct client_rpc *rpc;
169 if (!client || !packet) {
170 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
173 if (client_is_faulted(client)) {
174 ErrPrint("Client[%p] is faulted\n", client);
175 packet_unref(packet);
176 return DBOX_STATUS_ERROR_FAULT;
179 rpc = client_data(client, RPC_TAG);
181 ErrPrint("Client[%p] is not ready for communication (%s)\n", client, packet_command(packet));
184 command = create_command(client, packet);
186 packet_unref(packet);
187 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
190 push_command(command);
191 packet_unref(packet);
192 return DBOX_STATUS_ERROR_NONE;
195 static int deactivated_cb(struct client_node *client, void *data)
197 struct client_rpc *rpc;
198 struct command *command;
202 rpc = client_data(client, RPC_TAG);
204 ErrPrint("client is not valid\n");
205 return DBOX_STATUS_ERROR_NONE;
208 DbgPrint("Reset handle for %d\n", client_pid(client));
211 DbgPrint("Begin: Destroying command\n");
212 EINA_LIST_FOREACH_SAFE(s_info.command_list, l, n, command) {
213 if (command->client == client) {
214 s_info.command_list = eina_list_remove(s_info.command_list, command);
215 destroy_command(command);
218 DbgPrint("End: Destroying command\n");
220 return DBOX_STATUS_ERROR_NONE;
223 HAPI int client_rpc_init(struct client_node *client, int handle)
225 struct client_rpc *rpc;
228 rpc = calloc(1, sizeof(*rpc));
230 ErrPrint("Heap: %s\n", strerror(errno));
231 return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
234 ret = client_set_data(client, RPC_TAG, rpc);
236 ErrPrint("Failed to set \"rpc\" for client\n");
241 DbgPrint("CLIENT: New handle assigned for %d, %d (old: %d)\n", client_pid(client), handle, rpc->handle);
242 rpc->handle = handle;
244 ret = client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, deactivated_cb, NULL);
246 struct client_rpc *weird;
248 weird = client_del_data(client, RPC_TAG);
250 ErrPrint("What happens? (%p <> %p)\n", weird, rpc);
258 HAPI int client_rpc_fini(struct client_node *client)
260 struct client_rpc *rpc;
262 rpc = client_del_data(client, RPC_TAG);
264 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
267 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, deactivated_cb, NULL);
269 return DBOX_STATUS_ERROR_NONE;
272 HAPI int client_rpc_handle(struct client_node *client)
274 struct client_rpc *rpc;
276 rpc = client_data(client, RPC_TAG);
278 DbgPrint("Client has no RPC\n");
279 return DBOX_STATUS_ERROR_INVALID_PARAMETER;