summaryrefslogtreecommitdiffstats
path: root/bta/sys/ptim.c
diff options
context:
space:
mode:
Diffstat (limited to 'bta/sys/ptim.c')
-rw-r--r--bta/sys/ptim.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/bta/sys/ptim.c b/bta/sys/ptim.c
new file mode 100644
index 0000000..9dffc66
--- /dev/null
+++ b/bta/sys/ptim.c
@@ -0,0 +1,162 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2003-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Protocol timer services.
+ *
+ ******************************************************************************/
+
+#include "bt_target.h"
+#include "gki.h"
+#include "ptim.h"
+#include "bta_sys.h"
+
+/*******************************************************************************
+**
+** Function ptim_init
+**
+** Description Initialize a protocol timer control block. Parameter
+** period is the GKI timer period in milliseconds. Parameter
+** timer_id is the GKI timer id.
+**
+** Returns void
+**
+*******************************************************************************/
+void ptim_init(tPTIM_CB *p_cb, UINT16 period, UINT8 timer_id)
+{
+ GKI_init_timer_list(&p_cb->timer_queue);
+ p_cb->period = period;
+ p_cb->timer_id = timer_id;
+}
+
+/*******************************************************************************
+**
+** Function ptim_timer_update
+**
+** Description Update the protocol timer list and handle expired timers.
+** This function is called from the task running the protocol
+** timers when the periodic GKI timer expires.
+**
+** Returns void
+**
+*******************************************************************************/
+void ptim_timer_update(tPTIM_CB *p_cb)
+{
+ TIMER_LIST_ENT *p_tle;
+ BT_HDR *p_msg;
+ UINT32 new_ticks_count;
+ INT32 period_in_ticks;
+
+ /* To handle the case when the function is called less frequently than the period
+ we must convert determine the number of ticks since the last update, then
+ convert back to milliseconds before updating timer list */
+ new_ticks_count = GKI_get_tick_count();
+
+ /* Check for wrapped condition */
+ if (new_ticks_count >= p_cb->last_gki_ticks)
+ {
+ period_in_ticks = (INT32)(new_ticks_count - p_cb->last_gki_ticks);
+ }
+ else
+ {
+ period_in_ticks = (INT32)(((UINT32)0xffffffff - p_cb->last_gki_ticks)
+ + new_ticks_count + 1);
+ }
+
+ /* update timer list */
+ GKI_update_timer_list(&p_cb->timer_queue, GKI_TICKS_TO_MS(period_in_ticks));
+
+ p_cb->last_gki_ticks = new_ticks_count;
+
+ /* while there are expired timers */
+ while((p_cb->timer_queue.p_first) && (p_cb->timer_queue.p_first->ticks <= 0))
+ {
+ /* removed expired timer from list */
+ p_tle = p_cb->timer_queue.p_first;
+ GKI_remove_from_timer_list(&p_cb->timer_queue, p_tle);
+
+ /* call timer callback */
+ if(p_tle->p_cback)
+ {
+ (*p_tle->p_cback)(p_tle);
+ }
+ else if(p_tle->event)
+ {
+ if ((p_msg = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
+ {
+ p_msg->event = p_tle->event;
+ p_msg->layer_specific = 0;
+ bta_sys_sendmsg(p_msg);
+ }
+ }
+ }
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ GKI_stop_timer(p_cb->timer_id);
+ }
+}
+
+/*******************************************************************************
+**
+** Function ptim_start_timer
+**
+** Description Start a protocol timer for the specified amount
+** of time in seconds.
+**
+** Returns void
+**
+*******************************************************************************/
+void ptim_start_timer(tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
+{
+ /* if timer list is currently empty, start periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ p_cb->last_gki_ticks = GKI_get_tick_count();
+ GKI_start_timer(p_cb->timer_id, GKI_MS_TO_TICKS(p_cb->period), TRUE);
+ }
+
+ GKI_remove_from_timer_list(&p_cb->timer_queue, p_tle);
+
+ p_tle->event = type;
+ p_tle->ticks = timeout;
+
+ GKI_add_to_timer_list(&p_cb->timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function ptim_stop_timer
+**
+** Description Stop a protocol timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void ptim_stop_timer(tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle)
+{
+ GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle);
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (p_cb->timer_queue.p_first == NULL)
+ {
+ GKI_stop_timer(p_cb->timer_id);
+ }
+}