4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
35 #include "user_request.h"
40 //#define IDLE_SEND_PRIORITY G_PRIORITY_DEFAULT
41 #define IDLE_SEND_PRIORITY G_PRIORITY_HIGH
43 struct hook_send_type {
44 TcoreHalSendHook func;
48 struct recv_callback_item_type {
49 TcoreHalReceiveCallback func;
53 struct tcore_hal_type {
54 TcorePlugin *parent_plugin;
57 struct tcore_hal_operations *ops;
61 GSList *hook_list_send;
63 enum tcore_hal_mode mode;
67 static gboolean _hal_idle_send(void *user_data)
69 TcoreHal *h = user_data;
70 TcorePending *p = NULL;
74 unsigned int data_len = 0;
75 gboolean renew = FALSE;
80 msg("--[Queue SEND]-------------------");
82 p = tcore_queue_ref_next_pending(h->queue);
84 dbg("next pending is NULL. no send, queue len=%d", tcore_queue_get_length(h->queue));
88 data = tcore_pending_ref_request_data(p, &data_len);
89 dbg("queue len=%d, pending=0x%x, id=0x%x, data_len=%d",
90 tcore_queue_get_length(h->queue), (unsigned int)p, tcore_pending_get_id(p), data_len);
92 if (h->mode == TCORE_HAL_MODE_AT) {
93 ret = tcore_at_set_request(h->at, data, TRUE);
96 ret = tcore_hal_send_data(h, data_len, data);
99 if (ret == TCORE_RETURN_SUCCESS) {
100 tcore_pending_emit_send_callback(p, TRUE);
103 tcore_pending_emit_send_callback(p, FALSE);
106 if (ret != TCORE_RETURN_HOOK_STOP) {
107 if (tcore_pending_get_auto_free_status_after_sent(p)) {
108 q = tcore_hal_ref_queue(h);
109 tcore_queue_pop_by_pending(q, p);
110 tcore_pending_free(p);
117 if (ret != TCORE_RETURN_SUCCESS) {
119 q = tcore_hal_ref_queue(h);
120 p = tcore_queue_pop(q);
121 tcore_pending_free(p);
127 msg("--[Queue SEND FINISH]------------\n");
131 TcoreHal *tcore_hal_new(TcorePlugin *plugin, const char *name,
132 struct tcore_hal_operations *hops,
133 enum tcore_hal_mode mode)
140 h = calloc(sizeof(struct tcore_hal_type), 1);
144 h->parent_plugin = plugin;
146 h->name = strdup(name);
147 h->queue = tcore_queue_new(h);
150 if (mode == TCORE_HAL_MODE_AT)
151 h->at = tcore_at_new(h);
154 tcore_server_add_hal(tcore_plugin_ref_server(plugin), h);
159 void tcore_hal_free(TcoreHal *hal)
164 dbg("hal=%s", hal->name);
170 g_slist_free(hal->callbacks);
173 tcore_queue_free(hal->queue);
176 tcore_at_free(hal->at);
181 TReturn tcore_hal_set_name(TcoreHal *hal, const char *name)
184 return TCORE_RETURN_EINVAL;
192 hal->name = strdup(name);
194 return TCORE_RETURN_SUCCESS;
197 char *tcore_hal_get_name(TcoreHal *hal)
203 return strdup(hal->name);
208 TcoreAT *tcore_hal_get_at(TcoreHal *hal)
216 enum tcore_hal_mode tcore_hal_get_mode(TcoreHal *hal)
219 return TCORE_HAL_MODE_UNKNOWN;
224 TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode)
227 return TCORE_RETURN_EINVAL;
231 return TCORE_RETURN_SUCCESS;
234 TReturn tcore_hal_link_user_data(TcoreHal *hal, void *user_data)
237 return TCORE_RETURN_EINVAL;
239 hal->user_data = user_data;
241 return TCORE_RETURN_SUCCESS;
244 void *tcore_hal_ref_user_data(TcoreHal *hal)
249 return hal->user_data;
252 /* Send data without Queue */
253 TReturn tcore_hal_send_data(TcoreHal *hal, unsigned int data_len, void *data)
255 struct hook_send_type *hook;
258 if (!hal || !hal->ops || !hal->ops->send)
259 return TCORE_RETURN_EINVAL;
261 for (list = hal->hook_list_send; list; list = list->next) {
267 if (hook->func(hal, data_len, data, hook->user_data) == TCORE_HOOK_RETURN_STOP_PROPAGATION) {
268 return TCORE_RETURN_HOOK_STOP;
272 return hal->ops->send(hal, data_len, data);
275 /* Send data by Queue */
276 TReturn tcore_hal_send_request(TcoreHal *hal, TcorePending *pending)
279 enum tcore_pending_priority priority;
281 if (!hal || !pending)
282 return TCORE_RETURN_EINVAL;
284 qlen = tcore_queue_get_length(hal->queue);
285 tcore_queue_push(hal->queue, pending);
287 tcore_pending_get_priority(pending, &priority);
288 if (priority == TCORE_PENDING_PRIORITY_IMMEDIATELY) {
289 dbg("IMMEDIATELY pending !!");
293 if (tcore_queue_get_length(hal->queue) == 1) {
294 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL);
298 return TCORE_RETURN_SUCCESS;
301 TReturn tcore_hal_send_force(TcoreHal *hal)
304 return TCORE_RETURN_EINVAL;
308 return TCORE_RETURN_SUCCESS;
311 TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id,
312 unsigned int data_len, const void *data)
314 TcorePending *p = NULL;
317 return TCORE_RETURN_EINVAL;
319 if (data_len > 0 && data == NULL)
320 return TCORE_RETURN_EINVAL;
322 if (hal->mode == TCORE_HAL_MODE_AT) {
324 ret = tcore_at_process(hal->at, data_len, data);
326 /* Send next request in queue */
327 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL );
331 if(hal->mode == TCORE_HAL_MODE_CUSTOM) {
332 dbg("TCORE_HAL_MODE_CUSTOM");
333 p = tcore_queue_pop_by_id(hal->queue, id);
335 dbg("unknown pending (id=0x%x)", id);
336 return TCORE_RETURN_PENDING_WRONG_ID;
339 tcore_pending_emit_response_callback(p, data_len, data);
340 tcore_user_request_free(tcore_pending_ref_user_request(p));
341 tcore_pending_free(p);
343 else if(hal->mode == TCORE_HAL_MODE_TRANSPARENT) {
344 dbg("TCORE_HAL_MODE_TRANSPARENT");
346 /* Invoke CMUX receive API for decoding */
347 tcore_cmux_rcv_from_hal((unsigned char *)data, data_len);
349 /* Send next request in queue */
350 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL );
353 return TCORE_RETURN_SUCCESS;
356 TReturn tcore_hal_add_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func,
359 struct recv_callback_item_type *item;
362 return TCORE_RETURN_EINVAL;
364 item = calloc(sizeof(struct recv_callback_item_type), 1);
366 return TCORE_RETURN_ENOMEM;
369 item->user_data = user_data;
371 hal->callbacks = g_slist_append(hal->callbacks, item);
373 return TCORE_RETURN_SUCCESS;
376 TReturn tcore_hal_remove_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func)
378 struct recv_callback_item_type *item;
382 return TCORE_RETURN_EINVAL;
384 for (list = hal->callbacks; list; list = list->next) {
390 if (item->func == func) {
391 hal->callbacks = g_slist_remove(hal->callbacks, item);
393 list = hal->callbacks;
397 return TCORE_RETURN_SUCCESS;
400 TReturn tcore_hal_emit_recv_callback(TcoreHal *hal, unsigned int data_len,
404 struct recv_callback_item_type *item;
407 return TCORE_RETURN_EINVAL;
409 for (list = hal->callbacks; list; list = list->next) {
413 item->func(hal, data_len, data, item->user_data);
417 return TCORE_RETURN_SUCCESS;
421 TReturn tcore_hal_add_send_hook(TcoreHal *hal, TcoreHalSendHook func, void *user_data)
423 struct hook_send_type *hook;
426 return TCORE_RETURN_EINVAL;
428 hook = calloc(sizeof(struct hook_send_type), 1);
430 return TCORE_RETURN_ENOMEM;
433 hook->user_data = user_data;
435 hal->hook_list_send = g_slist_append(hal->hook_list_send, hook);
437 return TCORE_RETURN_SUCCESS;
440 TReturn tcore_hal_remove_send_hook(TcoreHal *hal, TcoreHalSendHook func)
442 struct hook_send_type *hook;
446 return TCORE_RETURN_EINVAL;
448 for (list = hal->hook_list_send; list; list = list->next) {
454 if (hook->func == func) {
455 hal->hook_list_send = g_slist_remove(hal->hook_list_send, hook);
457 list = hal->hook_list_send;
461 return TCORE_RETURN_SUCCESS;
464 TcoreQueue *tcore_hal_ref_queue(TcoreHal *hal)
472 TcorePlugin *tcore_hal_ref_plugin(TcoreHal *hal)
477 return hal->parent_plugin;
480 TReturn tcore_hal_set_power_state(TcoreHal *hal, gboolean flag)
483 return TCORE_RETURN_EINVAL;
485 hal->power_state = flag;
487 return TCORE_RETURN_SUCCESS;
490 gboolean tcore_hal_get_power_state(TcoreHal *hal)
495 return hal->power_state;
498 TReturn tcore_hal_set_power(TcoreHal *hal, gboolean flag)
500 if (!hal || !hal->ops || !hal->ops->power)
501 return TCORE_RETURN_EINVAL;
503 return hal->ops->power(hal, flag);