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(1, sizeof(struct tcore_hal_type));
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 if (hal->power_state == FALSE)
285 return TCORE_RETURN_FAILURE;
287 qlen = tcore_queue_get_length(hal->queue);
288 tcore_queue_push(hal->queue, pending);
290 tcore_pending_get_priority(pending, &priority);
291 if (priority == TCORE_PENDING_PRIORITY_IMMEDIATELY) {
292 dbg("IMMEDIATELY pending !!");
296 if (tcore_queue_get_length(hal->queue) == 1) {
297 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL);
301 return TCORE_RETURN_SUCCESS;
304 TReturn tcore_hal_send_force(TcoreHal *hal)
307 return TCORE_RETURN_EINVAL;
311 return TCORE_RETURN_SUCCESS;
314 TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id,
315 unsigned int data_len, const void *data)
317 TcorePending *p = NULL;
320 return TCORE_RETURN_EINVAL;
322 if (data_len > 0 && data == NULL)
323 return TCORE_RETURN_EINVAL;
325 if (hal->mode == TCORE_HAL_MODE_AT) {
327 ret = tcore_at_process(hal->at, data_len, data);
329 /* Send next request in queue */
330 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL );
334 if(hal->mode == TCORE_HAL_MODE_CUSTOM) {
335 dbg("TCORE_HAL_MODE_CUSTOM");
336 p = tcore_queue_pop_by_id(hal->queue, id);
338 dbg("unknown pending (id=0x%x)", id);
339 return TCORE_RETURN_PENDING_WRONG_ID;
342 tcore_pending_emit_response_callback(p, data_len, data);
343 tcore_user_request_free(tcore_pending_ref_user_request(p));
344 tcore_pending_free(p);
346 else if(hal->mode == TCORE_HAL_MODE_TRANSPARENT) {
347 dbg("TCORE_HAL_MODE_TRANSPARENT");
349 /* Invoke CMUX receive API for decoding */
350 tcore_cmux_rcv_from_hal((unsigned char *)data, data_len);
352 /* Send next request in queue */
353 g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL );
356 return TCORE_RETURN_SUCCESS;
359 TReturn tcore_hal_add_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func,
362 struct recv_callback_item_type *item;
365 return TCORE_RETURN_EINVAL;
367 item = calloc(1, sizeof(struct recv_callback_item_type));
369 return TCORE_RETURN_ENOMEM;
372 item->user_data = user_data;
374 hal->callbacks = g_slist_append(hal->callbacks, item);
376 return TCORE_RETURN_SUCCESS;
379 TReturn tcore_hal_remove_recv_callback(TcoreHal *hal, TcoreHalReceiveCallback func)
381 struct recv_callback_item_type *item;
385 return TCORE_RETURN_EINVAL;
387 for (list = hal->callbacks; list; list = list->next) {
393 if (item->func == func) {
394 hal->callbacks = g_slist_remove(hal->callbacks, item);
399 list = hal->callbacks;
403 return TCORE_RETURN_SUCCESS;
406 TReturn tcore_hal_emit_recv_callback(TcoreHal *hal, unsigned int data_len,
410 struct recv_callback_item_type *item;
413 return TCORE_RETURN_EINVAL;
415 for (list = hal->callbacks; list; list = list->next) {
419 item->func(hal, data_len, data, item->user_data);
423 return TCORE_RETURN_SUCCESS;
427 TReturn tcore_hal_add_send_hook(TcoreHal *hal, TcoreHalSendHook func, void *user_data)
429 struct hook_send_type *hook;
432 return TCORE_RETURN_EINVAL;
434 hook = calloc(1, sizeof(struct hook_send_type));
436 return TCORE_RETURN_ENOMEM;
439 hook->user_data = user_data;
441 hal->hook_list_send = g_slist_append(hal->hook_list_send, hook);
443 return TCORE_RETURN_SUCCESS;
446 TReturn tcore_hal_remove_send_hook(TcoreHal *hal, TcoreHalSendHook func)
448 struct hook_send_type *hook;
452 return TCORE_RETURN_EINVAL;
454 for (list = hal->hook_list_send; list; list = list->next) {
460 if (hook->func == func) {
461 hal->hook_list_send = g_slist_remove(hal->hook_list_send, hook);
463 list = hal->hook_list_send;
467 return TCORE_RETURN_SUCCESS;
470 TcoreQueue *tcore_hal_ref_queue(TcoreHal *hal)
478 TcorePlugin *tcore_hal_ref_plugin(TcoreHal *hal)
483 return hal->parent_plugin;
486 TReturn tcore_hal_set_power_state(TcoreHal *hal, gboolean flag)
489 return TCORE_RETURN_EINVAL;
491 hal->power_state = flag;
493 return TCORE_RETURN_SUCCESS;
496 gboolean tcore_hal_get_power_state(TcoreHal *hal)
501 return hal->power_state;
504 TReturn tcore_hal_set_power(TcoreHal *hal, gboolean flag)
506 if (!hal || !hal->ops || !hal->ops->power)
507 return TCORE_RETURN_EINVAL;
509 return hal->ops->power(hal, flag);
512 TReturn tcore_hal_setup_netif(TcoreHal *hal, CoreObject *co,
513 TcoreHalSetupNetifCallback func,
514 void *user_data, unsigned int cid,
517 if (!hal || !hal->ops || !hal->ops->setup_netif)
518 return TCORE_RETURN_EINVAL;
520 return hal->ops->setup_netif(co, func, user_data, cid, enable);