blob: 1a4dc585b96e804fe133f81a909f87f38cdf1c23 [file] [log] [blame]
nxpandroidc7611652015-09-23 16:42:05 +05301/******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
nxpandroidc7611652015-09-23 16:42:05 +053018#include <errno.h>
nxf24591c1cbeab2018-02-21 17:32:26 +053019#include <malloc.h>
nxpandroid8f6d0532017-07-12 18:25:30 +053020#include <pthread.h> /* must be 1st header defined */
nxf24591c1cbeab2018-02-21 17:32:26 +053021
22#include <android-base/stringprintf.h>
23#include <base/logging.h>
24
nxpandroidc7611652015-09-23 16:42:05 +053025#include "gki_int.h"
nxf24591c1cbeab2018-02-21 17:32:26 +053026
27using android::base::StringPrintf;
28
29extern bool nfc_debug_enabled;
nxpandroidc7611652015-09-23 16:42:05 +053030
31/* Temp android logging...move to android tgt config file */
32
33#ifndef LINUX_NATIVE
nxpandroidc7611652015-09-23 16:42:05 +053034#else
nxpandroid8f6d0532017-07-12 18:25:30 +053035#define LOGV(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
36#define LOGE(format, ...) fprintf(stderr, LOG_TAG format, ##__VA_ARGS__)
37#define LOGI(format, ...) fprintf(stdout, LOG_TAG format, ##__VA_ARGS__)
nxpandroidc7611652015-09-23 16:42:05 +053038
39#define SCHED_NORMAL 0
40#define SCHED_FIFO 1
41#define SCHED_RR 2
42#define SCHED_BATCH 3
43
44#endif
45
46/* Define the structure that holds the GKI variables
47*/
nxpandroid8f6d0532017-07-12 18:25:30 +053048tGKI_CB gki_cb;
nxpandroidc7611652015-09-23 16:42:05 +053049
50#define NANOSEC_PER_MILLISEC (1000000)
nxpandroid8f6d0532017-07-12 18:25:30 +053051#define NSEC_PER_SEC (1000 * NANOSEC_PER_MILLISEC)
nxpandroidc7611652015-09-23 16:42:05 +053052
53/* works only for 1ms to 1000ms heart beat ranges */
nxpandroid8f6d0532017-07-12 18:25:30 +053054#define LINUX_SEC (1000 / TICKS_PER_SEC)
nxpandroidc7611652015-09-23 16:42:05 +053055// #define GKI_TICK_TIMER_DEBUG
56
nxpandroidc7611652015-09-23 16:42:05 +053057/* this kind of mutex go into tGKI_OS control block!!!! */
58/* static pthread_mutex_t GKI_sched_mutex; */
59/*static pthread_mutex_t thread_delay_mutex;
60static pthread_cond_t thread_delay_cond;
61static pthread_mutex_t gki_timer_update_mutex;
62static pthread_cond_t gki_timer_update_cond;
63*/
64#ifdef NO_GKI_RUN_RETURN
nxpandroid8f6d0532017-07-12 18:25:30 +053065static pthread_t timer_thread_id = 0;
nxpandroidc7611652015-09-23 16:42:05 +053066#endif
nxpandroidc7611652015-09-23 16:42:05 +053067
nxpandroid8f6d0532017-07-12 18:25:30 +053068typedef struct {
69 uint8_t task_id; /* GKI task id */
70 TASKPTR task_entry; /* Task entry function*/
71 uintptr_t params; /* Extra params to pass to task entry function */
72 pthread_cond_t* pCond; /* for android*/
73 pthread_mutex_t* pMutex; /* for android*/
nxpandroidc7611652015-09-23 16:42:05 +053074} gki_pthread_info_t;
75gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
76
77/*******************************************************************************
78**
79** Function gki_task_entry
80**
81** Description entry point of GKI created tasks
82**
83** Returns void
84**
85*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +053086void* gki_task_entry(void* params) {
nxpandroid8f6d0532017-07-12 18:25:30 +053087 pthread_t thread_id = pthread_self();
88 gki_pthread_info_t* p_pthread_info = (gki_pthread_info_t*)params;
nxf24591c1cbeab2018-02-21 17:32:26 +053089 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
90 "gki_task_entry task_id=%i, thread_id=%lx/%lx, pCond/pMutex=%p/%p",
91 p_pthread_info->task_id, gki_cb.os.thread_id[p_pthread_info->task_id],
92 pthread_self(), p_pthread_info->pCond, p_pthread_info->pMutex);
nxpandroidc7611652015-09-23 16:42:05 +053093
nxpandroid8f6d0532017-07-12 18:25:30 +053094 gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
95 /* Call the actual thread entry point */
96 (p_pthread_info->task_entry)(p_pthread_info->params);
nxpandroidc7611652015-09-23 16:42:05 +053097
nxf24591c1cbeab2018-02-21 17:32:26 +053098 LOG(ERROR) << StringPrintf("gki_task task_id=%i terminating",
99 p_pthread_info->task_id);
nxf24591e1fb2f92018-06-06 14:41:56 +0530100#if (NXP_EXTNS == TRUE)
101 memset(&(gki_cb.os.thread_id[p_pthread_info->task_id]), 0, sizeof(pthread_t));
102#else
nxpandroid8f6d0532017-07-12 18:25:30 +0530103 gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
nxf24591e1fb2f92018-06-06 14:41:56 +0530104#endif
nxpandroidc7611652015-09-23 16:42:05 +0530105
nxf24591c1cbeab2018-02-21 17:32:26 +0530106 return NULL;
nxpandroidc7611652015-09-23 16:42:05 +0530107}
108/* end android */
109
nxpandroidc7611652015-09-23 16:42:05 +0530110/*******************************************************************************
111**
112** Function GKI_init
113**
114** Description This function is called once at startup to initialize
115** all the timer structures.
116**
117** Returns void
118**
119*******************************************************************************/
120
nxpandroid8f6d0532017-07-12 18:25:30 +0530121void GKI_init(void) {
122 pthread_mutexattr_t attr;
123 tGKI_OS* p_os;
nxpandroid6154b732016-01-14 20:39:23 +0530124
nxf24591c1cbeab2018-02-21 17:32:26 +0530125 memset(&gki_cb, 0, sizeof(gki_cb));
126
127 gki_buffer_init();
nxpandroid8f6d0532017-07-12 18:25:30 +0530128 gki_timers_init();
nxf24591c1cbeab2018-02-21 17:32:26 +0530129 gki_cb.com.OSTicks = (uint32_t)times(0);
nxpandroidc7611652015-09-23 16:42:05 +0530130
nxpandroid8f6d0532017-07-12 18:25:30 +0530131 pthread_mutexattr_init(&attr);
nxpandroidc7611652015-09-23 16:42:05 +0530132
133#ifndef __CYGWIN__
nxpandroid8f6d0532017-07-12 18:25:30 +0530134 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
nxpandroidc7611652015-09-23 16:42:05 +0530135#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530136 p_os = &gki_cb.os;
137 pthread_mutex_init(&p_os->GKI_mutex, &attr);
nxf24591c1cbeab2018-02-21 17:32:26 +0530138 /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
nxpandroid8f6d0532017-07-12 18:25:30 +0530139 /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
140 /* pthread_cond_init (&thread_delay_cond, NULL); */
nxpandroidc7611652015-09-23 16:42:05 +0530141
nxpandroid8f6d0532017-07-12 18:25:30 +0530142 /* Initialiase GKI_timer_update suspend variables & mutexes to be in running
143 * state.
144 * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
145 p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
146 pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
147 pthread_cond_init(&p_os->gki_timer_cond, NULL);
nxpandroidc7611652015-09-23 16:42:05 +0530148}
149
nxpandroidc7611652015-09-23 16:42:05 +0530150/*******************************************************************************
151**
152** Function GKI_get_os_tick_count
153**
nxpandroid8f6d0532017-07-12 18:25:30 +0530154** Description This function is called to retrieve the native OS system
155** tick.
nxpandroidc7611652015-09-23 16:42:05 +0530156**
157** Returns Tick count of native OS.
158**
159*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530160uint32_t GKI_get_os_tick_count(void) {
161 /* TODO - add any OS specific code here
162 **/
163 return (gki_cb.com.OSTicks);
nxpandroidc7611652015-09-23 16:42:05 +0530164}
165
166/*******************************************************************************
167**
168** Function GKI_create_task
169**
170** Description This function is called to create a new OSS task.
171**
nxpandroid8f6d0532017-07-12 18:25:30 +0530172** Parameters: task_entry - (input) pointer to the entry function of the
173** task
nxpandroidc7611652015-09-23 16:42:05 +0530174** task_id - (input) Task id is mapped to priority
175** taskname - (input) name given to the task
nxpandroid8f6d0532017-07-12 18:25:30 +0530176** stack - (input) pointer to the top of the stack
177** (highest memory location)
178** stacksize - (input) size of the stack allocated for the
179** task
nxpandroidc7611652015-09-23 16:42:05 +0530180**
181** Returns GKI_SUCCESS if all OK, GKI_FAILURE if any problem
182**
183** NOTE This function take some parameters that may not be needed
184** by your particular OS. They are here for compatability
185** of the function prototype.
186**
187*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530188uint8_t GKI_create_task(TASKPTR task_entry, uint8_t task_id, int8_t* taskname,
189 uint16_t* stack, uint16_t stacksize, void* pCondVar,
190 void* pMutex) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530191 struct sched_param param;
192 int policy, ret = 0;
193 pthread_condattr_t attr;
194 pthread_attr_t attr1;
nxpandroidc7611652015-09-23 16:42:05 +0530195
nxpandroid8f6d0532017-07-12 18:25:30 +0530196 pthread_condattr_init(&attr);
197 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
nxf24591c1cbeab2018-02-21 17:32:26 +0530198 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
199 "GKI_create_task func=0x%p id=%d name=%s stack=0x%p stackSize=%d",
nxpandroid8f6d0532017-07-12 18:25:30 +0530200 task_entry, task_id, taskname, stack, stacksize);
nxpandroidc7611652015-09-23 16:42:05 +0530201
nxpandroid8f6d0532017-07-12 18:25:30 +0530202 if (task_id >= GKI_MAX_TASKS) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530203 DLOG_IF(INFO, nfc_debug_enabled)
204 << StringPrintf("Error! task ID > max task allowed");
nxpandroid8f6d0532017-07-12 18:25:30 +0530205 return (GKI_FAILURE);
206 }
nxpandroidc7611652015-09-23 16:42:05 +0530207
nxpandroid8f6d0532017-07-12 18:25:30 +0530208 gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
209 gki_cb.com.OSTName[task_id] = taskname;
210 gki_cb.com.OSWaitTmr[task_id] = 0;
211 gki_cb.com.OSWaitEvt[task_id] = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530212
nxpandroid8f6d0532017-07-12 18:25:30 +0530213 /* Initialize mutex and condition variable objects for events and timeouts */
214 pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
215 pthread_cond_init(&gki_cb.os.thread_evt_cond[task_id], &attr);
216 pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
217 pthread_cond_init(&gki_cb.os.thread_timeout_cond[task_id], &attr);
nxpandroidc7611652015-09-23 16:42:05 +0530218
nxpandroid8f6d0532017-07-12 18:25:30 +0530219 pthread_attr_init(&attr1);
220/* by default, pthread creates a joinable thread */
nxf24591c1cbeab2018-02-21 17:32:26 +0530221#if (FALSE == GKI_PTHREAD_JOINABLE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530222 pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
nxpandroidc7611652015-09-23 16:42:05 +0530223
nxf24591c1cbeab2018-02-21 17:32:26 +0530224 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
225 "GKI creating task %i, pCond/pMutex=%p/%p", task_id, pCondVar, pMutex);
nxpandroidc7611652015-09-23 16:42:05 +0530226#else
nxf24591c1cbeab2018-02-21 17:32:26 +0530227 DLOG_IF(INFO, nfc_debug_enabled)
228 << StringPrintf("GKI creating JOINABLE task %i", task_id);
nxpandroidc7611652015-09-23 16:42:05 +0530229#endif
230
nxpandroid8f6d0532017-07-12 18:25:30 +0530231 /* On Android, the new tasks starts running before
232 * 'gki_cb.os.thread_id[task_id]' is initialized */
233 /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id]
234 * for it calls GKI_wait */
235 gki_pthread_info[task_id].task_id = task_id;
236 gki_pthread_info[task_id].task_entry = task_entry;
237 gki_pthread_info[task_id].params = 0;
238 gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
239 gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
nxpandroidc7611652015-09-23 16:42:05 +0530240
nxf24591c1cbeab2018-02-21 17:32:26 +0530241 ret = pthread_create(&gki_cb.os.thread_id[task_id], &attr1, gki_task_entry,
242 &gki_pthread_info[task_id]);
243
nxpandroid8f6d0532017-07-12 18:25:30 +0530244 if (ret != 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530245 DLOG_IF(INFO, nfc_debug_enabled)
246 << StringPrintf("pthread_create failed(%d), %s!", ret, taskname);
nxpandroid8f6d0532017-07-12 18:25:30 +0530247 return GKI_FAILURE;
248 }
249
250 if (pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param) ==
251 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530252#if (PBS_SQL_TASK == TRUE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530253 if (task_id == PBS_SQL_TASK) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530254 DLOG_IF(INFO, nfc_debug_enabled)
255 << StringPrintf("PBS SQL lowest priority task");
nxpandroid8f6d0532017-07-12 18:25:30 +0530256 policy = SCHED_NORMAL;
257 } else
258#endif
nxpandroidc7611652015-09-23 16:42:05 +0530259 {
nxpandroid8f6d0532017-07-12 18:25:30 +0530260 policy = SCHED_RR;
261 param.sched_priority = 30 - task_id - 2;
nxpandroidc7611652015-09-23 16:42:05 +0530262 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530263 pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
264 }
nxpandroidc7611652015-09-23 16:42:05 +0530265
nxf24591c1cbeab2018-02-21 17:32:26 +0530266 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
267 "Leaving GKI_create_task %p %d %lx %s %p %d", task_entry, task_id,
268 gki_cb.os.thread_id[task_id], taskname, stack, stacksize);
nxpandroidc7611652015-09-23 16:42:05 +0530269
nxpandroid8f6d0532017-07-12 18:25:30 +0530270 return (GKI_SUCCESS);
nxpandroidc7611652015-09-23 16:42:05 +0530271}
272
273/*******************************************************************************
274**
275** Function GKI_shutdown
276**
nxpandroid8f6d0532017-07-12 18:25:30 +0530277** Description shutdowns the GKI tasks/threads in from max task id to 0 and
278** frees pthread resources!
279** IMPORTANT: in case of join method, GKI_shutdown must be
280** called outside a GKI thread context!
nxpandroidc7611652015-09-23 16:42:05 +0530281**
282** Returns void
283**
284*******************************************************************************/
285#define WAKE_LOCK_ID "brcm_nfca"
286#define PARTIAL_WAKE_LOCK 1
nxf24591c1cbeab2018-02-21 17:32:26 +0530287extern "C" int acquire_wake_lock(int lock, const char* id);
288extern "C" int release_wake_lock(const char* id);
nxpandroidc7611652015-09-23 16:42:05 +0530289
nxpandroid8f6d0532017-07-12 18:25:30 +0530290void GKI_shutdown(void) {
291 uint8_t task_id;
292 volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
293 int oldCOnd = 0;
nxf24591c1cbeab2018-02-21 17:32:26 +0530294#if (FALSE == GKI_PTHREAD_JOINABLE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530295 int i = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530296#else
nxpandroid8f6d0532017-07-12 18:25:30 +0530297 int result;
nxpandroidc7611652015-09-23 16:42:05 +0530298#endif
299
nxpandroid8f6d0532017-07-12 18:25:30 +0530300 /* release threads and set as TASK_DEAD. going from low to high priority fixes
301 * GKI_exception problem due to btu->hci sleep request events */
302 for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--) {
303 if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD) {
304 gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
nxpandroidc7611652015-09-23 16:42:05 +0530305
nxpandroid8f6d0532017-07-12 18:25:30 +0530306 /* paranoi settings, make sure that we do not execute any mailbox events
307 */
308 gki_cb.com.OSWaitEvt[task_id - 1] &=
309 ~(TASK_MBOX_0_EVT_MASK | TASK_MBOX_1_EVT_MASK | TASK_MBOX_2_EVT_MASK |
310 TASK_MBOX_3_EVT_MASK);
311 GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
nxpandroidc7611652015-09-23 16:42:05 +0530312
nxf24591c1cbeab2018-02-21 17:32:26 +0530313#if (FALSE == GKI_PTHREAD_JOINABLE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530314 i = 0;
nxf24591c1cbeab2018-02-21 17:32:26 +0530315
316 while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
317 usleep(100 * 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530318#else
nxpandroid8f6d0532017-07-12 18:25:30 +0530319 /* wait for proper Arnold Schwarzenegger task state */
320 result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
321 if (result < 0) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530322 DLOG_IF(INFO, nfc_debug_enabled)
323 << StringPrintf("FAILED: result: %d", result);
nxpandroid8f6d0532017-07-12 18:25:30 +0530324 }
nxpandroidc7611652015-09-23 16:42:05 +0530325#endif
nxf24591c1cbeab2018-02-21 17:32:26 +0530326 DLOG_IF(INFO, nfc_debug_enabled)
327 << StringPrintf("task %s dead", gki_cb.com.OSTName[task_id]);
nxpandroid8f6d0532017-07-12 18:25:30 +0530328 GKI_exit_task(task_id - 1);
nxpandroidc7611652015-09-23 16:42:05 +0530329 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530330 }
nxpandroidc7611652015-09-23 16:42:05 +0530331
nxpandroid8f6d0532017-07-12 18:25:30 +0530332 /* Destroy mutex and condition variable objects */
333 pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
334/* pthread_mutex_destroy(&GKI_sched_mutex); */
nxpandroid8f6d0532017-07-12 18:25:30 +0530335/* pthread_mutex_destroy(&thread_delay_mutex);
336 pthread_cond_destroy (&thread_delay_cond); */
nxf24591c1cbeab2018-02-21 17:32:26 +0530337#if (FALSE == GKI_PTHREAD_JOINABLE)
nxpandroid8f6d0532017-07-12 18:25:30 +0530338 i = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530339#endif
340
341#ifdef NO_GKI_RUN_RETURN
nxpandroid8f6d0532017-07-12 18:25:30 +0530342 shutdown_timer = 1;
nxpandroidc7611652015-09-23 16:42:05 +0530343#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530344 if (gki_cb.os.gki_timer_wake_lock_on) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530345 DLOG_IF(INFO, nfc_debug_enabled)
346 << StringPrintf("GKI_shutdown : release_wake_lock(brcm_btld)");
nxpandroid8f6d0532017-07-12 18:25:30 +0530347 release_wake_lock(WAKE_LOCK_ID);
348 gki_cb.os.gki_timer_wake_lock_on = 0;
349 }
350 oldCOnd = *p_run_cond;
351 *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
352 if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
353 pthread_cond_signal(&gki_cb.os.gki_timer_cond);
nxpandroidc7611652015-09-23 16:42:05 +0530354}
355
356/*******************************************************************************
357 **
358 ** Function GKI_run
359 **
360 ** Description This function runs a task
361 **
nxf24591c1cbeab2018-02-21 17:32:26 +0530362 ** Parameters: start: TRUE start system tick (again), FALSE stop
nxpandroidc7611652015-09-23 16:42:05 +0530363 **
364 ** Returns void
365 **
nxpandroid8f6d0532017-07-12 18:25:30 +0530366 ******************************************************************************/
367void gki_system_tick_start_stop_cback(bool start) {
368 tGKI_OS* p_os = &gki_cb.os;
369 volatile int* p_run_cond = &p_os->no_timer_suspend;
nxf24591c1cbeab2018-02-21 17:32:26 +0530370#ifdef GKI_TICK_TIMER_DEBUG
nxpandroid8f6d0532017-07-12 18:25:30 +0530371 static volatile int wake_lock_count;
nxf24591c1cbeab2018-02-21 17:32:26 +0530372#endif
373 if (start == false) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530374 /* this can lead to a race condition. however as we only read this variable
375 * in the timer loop
376 * we should be fine with this approach. otherwise uncomment below mutexes.
377 */
378 /* GKI_disable(); */
379 *p_run_cond = GKI_TIMER_TICK_STOP_COND;
380/* GKI_enable(); */
nxpandroidc7611652015-09-23 16:42:05 +0530381#ifdef GKI_TICK_TIMER_DEBUG
nxf24591c1cbeab2018-02-21 17:32:26 +0530382 DLOG_IF(INFO, nfc_debug_enabled)
383 << StringPrintf(">>> STOP wake_lock_count:%d", --wake_lock_count);
nxpandroidc7611652015-09-23 16:42:05 +0530384#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530385 release_wake_lock(WAKE_LOCK_ID);
386 gki_cb.os.gki_timer_wake_lock_on = 0;
387 } else {
388 /* restart GKI_timer_update() loop */
389 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
390 gki_cb.os.gki_timer_wake_lock_on = 1;
391 *p_run_cond = GKI_TIMER_TICK_RUN_COND;
392 pthread_mutex_lock(&p_os->gki_timer_mutex);
393 pthread_cond_signal(&p_os->gki_timer_cond);
394 pthread_mutex_unlock(&p_os->gki_timer_mutex);
nxpandroidc7611652015-09-23 16:42:05 +0530395
396#ifdef GKI_TICK_TIMER_DEBUG
nxf24591c1cbeab2018-02-21 17:32:26 +0530397 DLOG_IF(INFO, nfc_debug_enabled)
398 << StringPrintf(">>> START wake_lock_count:%d", ++wake_lock_count);
nxpandroidc7611652015-09-23 16:42:05 +0530399#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530400 }
nxpandroidc7611652015-09-23 16:42:05 +0530401}
402
nxpandroidc7611652015-09-23 16:42:05 +0530403/*******************************************************************************
404**
405** Function timer_thread
406**
407** Description Timer thread
408**
409** Parameters: id - (input) timer ID
410**
411** Returns void
412**
nxpandroid8f6d0532017-07-12 18:25:30 +0530413*******************************************************************************/
nxpandroidc7611652015-09-23 16:42:05 +0530414#ifdef NO_GKI_RUN_RETURN
nxpandroid8f6d0532017-07-12 18:25:30 +0530415void timer_thread(signed long id) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530416 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s enter", __func__);
nxpandroid8f6d0532017-07-12 18:25:30 +0530417 struct timespec delay;
418 int timeout = 1000; /* 10 ms per system tick */
419 int err;
nxpandroidc7611652015-09-23 16:42:05 +0530420
nxpandroid8f6d0532017-07-12 18:25:30 +0530421 while (!shutdown_timer) {
422 delay.tv_sec = timeout / 1000;
423 delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530424
nxpandroid8f6d0532017-07-12 18:25:30 +0530425 /* [u]sleep can't be used because it uses SIGALRM */
nxpandroidc7611652015-09-23 16:42:05 +0530426
nxpandroid8f6d0532017-07-12 18:25:30 +0530427 do {
428 err = nanosleep(&delay, &delay);
429 } while (err < 0 && errno == EINTR);
nxpandroidc7611652015-09-23 16:42:05 +0530430
nxpandroid8f6d0532017-07-12 18:25:30 +0530431 GKI_timer_update(1);
432 }
nxf24591c1cbeab2018-02-21 17:32:26 +0530433 LOG(ERROR) << StringPrintf("%s exit", __func__);
nxpandroid8f6d0532017-07-12 18:25:30 +0530434 return;
nxpandroidc7611652015-09-23 16:42:05 +0530435}
436#endif
437
438/*******************************************************************************
439**
440** Function GKI_run
441**
442** Description This function runs a task
443**
444** Parameters: p_task_id - (input) pointer to task id
445**
446** Returns void
447**
448** NOTE This function is only needed for operating systems where
449** starting a task is a 2-step process. Most OS's do it in
450** one step, If your OS does it in one step, this function
451** should be empty.
nxpandroid8f6d0532017-07-12 18:25:30 +0530452*******************************************************************************/
nxf24591c1cbeab2018-02-21 17:32:26 +0530453void GKI_run(__attribute__((unused)) void* p_task_id) {
454 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s enter", __func__);
nxpandroid8f6d0532017-07-12 18:25:30 +0530455 struct timespec delay;
456 int err = 0;
nxpandroid8f6d0532017-07-12 18:25:30 +0530457 volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
nxf24591c1cbeab2018-02-21 17:32:26 +0530458
nxpandroidc7611652015-09-23 16:42:05 +0530459#ifndef GKI_NO_TICK_STOP
nxpandroid8f6d0532017-07-12 18:25:30 +0530460 /* register start stop function which disable timer loop in GKI_run() when no
461 * timers are
462 * in any GKI/BTA/BTU this should save power when BTLD is idle! */
463 GKI_timer_queue_register_callback(gki_system_tick_start_stop_cback);
nxf24591c1cbeab2018-02-21 17:32:26 +0530464 DLOG_IF(INFO, nfc_debug_enabled)
465 << StringPrintf("Start/Stop GKI_timer_update_registered!");
nxpandroidc7611652015-09-23 16:42:05 +0530466#endif
467
468#ifdef NO_GKI_RUN_RETURN
nxf24591c1cbeab2018-02-21 17:32:26 +0530469 DLOG_IF(INFO, nfc_debug_enabled)
470 << StringPrintf("GKI_run == NO_GKI_RUN_RETURN");
nxpandroid8f6d0532017-07-12 18:25:30 +0530471 pthread_attr_t timer_attr;
nxpandroidc7611652015-09-23 16:42:05 +0530472
nxpandroid8f6d0532017-07-12 18:25:30 +0530473 shutdown_timer = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530474
nxpandroid8f6d0532017-07-12 18:25:30 +0530475 pthread_attr_init(&timer_attr);
476 pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
nxf24591c1cbeab2018-02-21 17:32:26 +0530477 if (pthread_create(&timer_thread_id, &timer_attr, timer_thread, NULL) != 0) {
478 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
479 "GKI_run: pthread_create failed to create timer_thread!");
nxpandroid8f6d0532017-07-12 18:25:30 +0530480 return GKI_FAILURE;
481 }
482#else
nxf24591c1cbeab2018-02-21 17:32:26 +0530483 DLOG_IF(INFO, nfc_debug_enabled)
484 << StringPrintf("GKI_run, run_cond(%p)=%d ", p_run_cond, *p_run_cond);
nxpandroid8f6d0532017-07-12 18:25:30 +0530485 for (; GKI_TIMER_TICK_EXIT_COND != *p_run_cond;) {
486 do {
487 /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this
488 * formula works only for
489 * 1-1000ms heart beat units! */
490 delay.tv_sec = LINUX_SEC / 1000;
491 delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
492
493 /* [u]sleep can't be used because it uses SIGALRM */
494 do {
495 err = nanosleep(&delay, &delay);
496 } while (err < 0 && errno == EINTR);
497
498 if (GKI_TIMER_TICK_RUN_COND != *p_run_cond) break; // GKI has shutdown
499
500 /* the unit should be alsways 1 (1 tick). only if you vary for some reason
501 * heart beat tick
502 * e.g. power saving you may want to provide more ticks
503 */
504 GKI_timer_update(1);
nxpandroid8f6d0532017-07-12 18:25:30 +0530505 } while (GKI_TIMER_TICK_RUN_COND == *p_run_cond);
506
507/* currently on reason to exit above loop is no_timer_suspend ==
508 * GKI_TIMER_TICK_STOP_COND
509 * block timer main thread till re-armed by */
510#ifdef GKI_TICK_TIMER_DEBUG
nxf24591c1cbeab2018-02-21 17:32:26 +0530511 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(">>> SUSPENDED");
nxpandroid6154b732016-01-14 20:39:23 +0530512#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530513 if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530514 pthread_mutex_lock(&gki_cb.os.gki_timer_mutex);
515 pthread_cond_wait(&gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex);
516 pthread_mutex_unlock(&gki_cb.os.gki_timer_mutex);
nxpandroid8f6d0532017-07-12 18:25:30 +0530517 }
518/* potentially we need to adjust os gki_cb.com.OSTicks */
nxpandroidc7611652015-09-23 16:42:05 +0530519
520#ifdef GKI_TICK_TIMER_DEBUG
nxf24591c1cbeab2018-02-21 17:32:26 +0530521 DLOG_IF(INFO, nfc_debug_enabled)
522 << StringPrintf(">>> RESTARTED run_cond: %d", *p_run_cond);
nxpandroidc7611652015-09-23 16:42:05 +0530523#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530524 } /* for */
nxpandroidc7611652015-09-23 16:42:05 +0530525#endif
nxf24591c1cbeab2018-02-21 17:32:26 +0530526 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s exit", __func__);
nxpandroidc7611652015-09-23 16:42:05 +0530527}
528
nxpandroidc7611652015-09-23 16:42:05 +0530529/*******************************************************************************
530**
531** Function GKI_stop
532**
533** Description This function is called to stop
534** the tasks and timers when the system is being stopped
535**
536** Returns void
537**
538** NOTE This function is NOT called by the Widcomm stack and
539** profiles. If you want to use it in your own implementation,
540** put specific code here.
541**
542*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530543void GKI_stop(void) {
544 uint8_t task_id;
nxpandroidc7611652015-09-23 16:42:05 +0530545
nxf24591c1cbeab2018-02-21 17:32:26 +0530546 /* gki_queue_timer_cback(FALSE); */
nxpandroid8f6d0532017-07-12 18:25:30 +0530547 /* TODO - add code here if needed*/
nxpandroidc7611652015-09-23 16:42:05 +0530548
nxpandroid8f6d0532017-07-12 18:25:30 +0530549 for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
550 if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD) {
551 GKI_exit_task(task_id);
nxpandroidc7611652015-09-23 16:42:05 +0530552 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530553 }
nxpandroidc7611652015-09-23 16:42:05 +0530554}
555
nxpandroidc7611652015-09-23 16:42:05 +0530556/*******************************************************************************
557**
558** Function GKI_wait
559**
560** Description This function is called by tasks to wait for a specific
561** event or set of events. The task may specify the duration
562** that it wants to wait for, or 0 if infinite.
563**
564** Parameters: flag - (input) the event or set of events to wait for
565** timeout - (input) the duration that the task wants to wait
566** for the specific events (in system ticks)
567**
568**
569** Returns the event mask of received events or zero if timeout
570**
571*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530572uint16_t GKI_wait(uint16_t flag, uint32_t timeout) {
573 uint16_t evt;
574 uint8_t rtask;
575 struct timespec abstime = {0, 0};
576 int sec;
577 int nano_sec;
nxpandroidc7611652015-09-23 16:42:05 +0530578
nxpandroid8f6d0532017-07-12 18:25:30 +0530579 rtask = GKI_get_taskid();
nxpandroid8f6d0532017-07-12 18:25:30 +0530580 if (rtask >= GKI_MAX_TASKS) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530581 LOG(ERROR) << StringPrintf("%s() Exiting thread; rtask %d >= %d", __func__,
582 rtask, GKI_MAX_TASKS);
nxpandroid8f6d0532017-07-12 18:25:30 +0530583 return EVENT_MASK(GKI_SHUTDOWN_EVT);
584 }
nxpandroidc7611652015-09-23 16:42:05 +0530585
nxpandroid8f6d0532017-07-12 18:25:30 +0530586 gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
587 if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
588 int ret;
nxf24591c1cbeab2018-02-21 17:32:26 +0530589 DLOG_IF(INFO, nfc_debug_enabled)
590 << StringPrintf("GKI_wait task=%i, pCond/pMutex = %p/%p", rtask,
591 p_pthread_info->pCond, p_pthread_info->pMutex);
nxpandroid8f6d0532017-07-12 18:25:30 +0530592 ret = pthread_mutex_lock(p_pthread_info->pMutex);
593 ret = pthread_cond_signal(p_pthread_info->pCond);
594 ret = pthread_mutex_unlock(p_pthread_info->pMutex);
595 p_pthread_info->pMutex = NULL;
596 p_pthread_info->pCond = NULL;
597 }
598 gki_cb.com.OSWaitForEvt[rtask] = flag;
nxpandroidc7611652015-09-23 16:42:05 +0530599
nxpandroid8f6d0532017-07-12 18:25:30 +0530600 /* protect OSWaitEvt[rtask] from modification from an other thread */
601 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
nxpandroidc7611652015-09-23 16:42:05 +0530602
nxpandroid8f6d0532017-07-12 18:25:30 +0530603#if 0 /* for clean scheduling we probably should always call \
604 pthread_cond_wait() */
nxpandroidc7611652015-09-23 16:42:05 +0530605 /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
606 has been modified. however this should only result in addtional call to pthread_cond_wait() but as
607 the cond is met, it will exit immediately (depending on schedulling) */
608 if (gki_cb.com.OSTaskQFirst[rtask][0])
609 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
610 if (gki_cb.com.OSTaskQFirst[rtask][1])
611 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
612 if (gki_cb.com.OSTaskQFirst[rtask][2])
613 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
614 if (gki_cb.com.OSTaskQFirst[rtask][3])
615 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
616#endif
617
nxpandroid8f6d0532017-07-12 18:25:30 +0530618 if (!(gki_cb.com.OSWaitEvt[rtask] & flag)) {
619 if (timeout) {
620 // timeout = GKI_MS_TO_TICKS(timeout); /* convert from
621 // milliseconds to ticks */
nxpandroidc7611652015-09-23 16:42:05 +0530622
nxpandroid8f6d0532017-07-12 18:25:30 +0530623 /* get current system time */
624 // clock_gettime(CLOCK_MONOTONIC, &currSysTime);
625 // abstime.tv_sec = currSysTime.time;
626 // abstime.tv_nsec = NANOSEC_PER_MILLISEC *
627 // currSysTime.millitm;
628 clock_gettime(CLOCK_MONOTONIC, &abstime);
nxpandroidc7611652015-09-23 16:42:05 +0530629
nxpandroid8f6d0532017-07-12 18:25:30 +0530630 /* add timeout */
631 sec = timeout / 1000;
632 nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
633 abstime.tv_nsec += nano_sec;
634 if (abstime.tv_nsec > NSEC_PER_SEC) {
635 abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
636 abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
637 }
638 abstime.tv_sec += sec;
nxpandroidc7611652015-09-23 16:42:05 +0530639
nxpandroid8f6d0532017-07-12 18:25:30 +0530640 pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
641 &gki_cb.os.thread_evt_mutex[rtask], &abstime);
nxpandroidc7611652015-09-23 16:42:05 +0530642
nxpandroid8f6d0532017-07-12 18:25:30 +0530643 } else {
644 pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask],
645 &gki_cb.os.thread_evt_mutex[rtask]);
nxpandroidc7611652015-09-23 16:42:05 +0530646 }
647
nxpandroid8f6d0532017-07-12 18:25:30 +0530648 /* TODO: check, this is probably neither not needed depending on
nxf24591c1cbeab2018-02-21 17:32:26 +0530649 phtread_cond_wait() implmentation,
nxpandroid8f6d0532017-07-12 18:25:30 +0530650 e.g. it looks like it is implemented as a counter in which case multiple
651 cond_signal
652 should NOT be lost! */
653 // we are waking up after waiting for some events, so refresh variables
654 // no need to call GKI_disable() here as we know that we will have some
655 // events as we've been waking up after condition pending or timeout
656 if (gki_cb.com.OSTaskQFirst[rtask][0])
657 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
658 if (gki_cb.com.OSTaskQFirst[rtask][1])
659 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
660 if (gki_cb.com.OSTaskQFirst[rtask][2])
661 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
662 if (gki_cb.com.OSTaskQFirst[rtask][3])
663 gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
nxpandroidc7611652015-09-23 16:42:05 +0530664
nxpandroid8f6d0532017-07-12 18:25:30 +0530665 if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
666 gki_cb.com.OSWaitEvt[rtask] = 0;
667 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond
668 * is met */
669 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
nxf24591c1cbeab2018-02-21 17:32:26 +0530670 LOG(ERROR) << StringPrintf("GKI TASK_DEAD received. exit thread %d...",
671 rtask);
nxf24591e1fb2f92018-06-06 14:41:56 +0530672#if (NXP_EXTNS == TRUE)
673 memset(&(gki_cb.os.thread_id[rtask]), 0, sizeof(pthread_t));
674#else
nxpandroid8f6d0532017-07-12 18:25:30 +0530675 gki_cb.os.thread_id[rtask] = 0;
nxf24591e1fb2f92018-06-06 14:41:56 +0530676#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530677 return (EVENT_MASK(GKI_SHUTDOWN_EVT));
678 }
679 }
nxpandroidc7611652015-09-23 16:42:05 +0530680
nxpandroid8f6d0532017-07-12 18:25:30 +0530681 /* Clear the wait for event mask */
682 gki_cb.com.OSWaitForEvt[rtask] = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530683
nxpandroid8f6d0532017-07-12 18:25:30 +0530684 /* Return only those bits which user wants... */
685 evt = gki_cb.com.OSWaitEvt[rtask] & flag;
686
687 /* Clear only those bits which user wants... */
688 gki_cb.com.OSWaitEvt[rtask] &= ~flag;
689
690 /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when
691 * cond is met */
692 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
nxpandroid8f6d0532017-07-12 18:25:30 +0530693 return (evt);
nxpandroidc7611652015-09-23 16:42:05 +0530694}
695
nxpandroidc7611652015-09-23 16:42:05 +0530696/*******************************************************************************
697**
698** Function GKI_delay
699**
700** Description This function is called by tasks to sleep unconditionally
nxpandroid8f6d0532017-07-12 18:25:30 +0530701** for a specified amount of time. The duration is in
702** milliseconds
nxpandroidc7611652015-09-23 16:42:05 +0530703**
704** Parameters: timeout - (input) the duration in milliseconds
705**
706** Returns void
707**
708*******************************************************************************/
709
nxpandroid8f6d0532017-07-12 18:25:30 +0530710void GKI_delay(uint32_t timeout) {
711 uint8_t rtask = GKI_get_taskid();
712 struct timespec delay;
713 int err;
nxpandroidc7611652015-09-23 16:42:05 +0530714
nxf24591c1cbeab2018-02-21 17:32:26 +0530715 DLOG_IF(INFO, nfc_debug_enabled)
716 << StringPrintf("GKI_delay %d %d", rtask, timeout);
nxpandroidc7611652015-09-23 16:42:05 +0530717
nxpandroid8f6d0532017-07-12 18:25:30 +0530718 delay.tv_sec = timeout / 1000;
719 delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
nxpandroidc7611652015-09-23 16:42:05 +0530720
nxpandroid8f6d0532017-07-12 18:25:30 +0530721 /* [u]sleep can't be used because it uses SIGALRM */
nxpandroidc7611652015-09-23 16:42:05 +0530722
nxpandroid8f6d0532017-07-12 18:25:30 +0530723 do {
724 err = nanosleep(&delay, &delay);
725 } while (err < 0 && errno == EINTR);
nxpandroidc7611652015-09-23 16:42:05 +0530726
nxpandroid8f6d0532017-07-12 18:25:30 +0530727 /* Check if task was killed while sleeping */
728 /* NOTE
729 ** if you do not implement task killing, you do not
730 ** need this check.
731 */
732 if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
733 }
nxpandroidc7611652015-09-23 16:42:05 +0530734
nxf24591c1cbeab2018-02-21 17:32:26 +0530735 DLOG_IF(INFO, nfc_debug_enabled)
736 << StringPrintf("GKI_delay %d %d done", rtask, timeout);
nxpandroid8f6d0532017-07-12 18:25:30 +0530737 return;
nxpandroidc7611652015-09-23 16:42:05 +0530738}
739
nxpandroidc7611652015-09-23 16:42:05 +0530740/*******************************************************************************
741**
742** Function GKI_send_event
743**
744** Description This function is called by tasks to send events to other
745** tasks. Tasks can also send events to themselves.
746**
nxpandroid8f6d0532017-07-12 18:25:30 +0530747** Parameters: task_id - (input) The id of the task to which the event has
748** to be sent
nxpandroidc7611652015-09-23 16:42:05 +0530749** event - (input) The event that has to be sent
750**
751**
752** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
753**
754*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530755uint8_t GKI_send_event(uint8_t task_id, uint16_t event) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530756 /* use efficient coding to avoid pipeline stalls */
757 if (task_id < GKI_MAX_TASKS) {
758 /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
759 pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
nxpandroidc7611652015-09-23 16:42:05 +0530760
nxpandroid8f6d0532017-07-12 18:25:30 +0530761 /* Set the event bit */
762 gki_cb.com.OSWaitEvt[task_id] |= event;
nxpandroidc7611652015-09-23 16:42:05 +0530763
nxpandroid8f6d0532017-07-12 18:25:30 +0530764 pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
nxpandroidc7611652015-09-23 16:42:05 +0530765
nxpandroid8f6d0532017-07-12 18:25:30 +0530766 pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
nxpandroidc7611652015-09-23 16:42:05 +0530767
nxpandroid8f6d0532017-07-12 18:25:30 +0530768 return (GKI_SUCCESS);
769 }
770 return (GKI_FAILURE);
nxpandroidc7611652015-09-23 16:42:05 +0530771}
772
nxpandroidc7611652015-09-23 16:42:05 +0530773/*******************************************************************************
774**
775** Function GKI_isend_event
776**
777** Description This function is called from ISRs to send events to other
nxpandroid8f6d0532017-07-12 18:25:30 +0530778** tasks. The only difference between this function and
779** GKI_send_event is that this function assumes interrupts are
780** already disabled.
nxpandroidc7611652015-09-23 16:42:05 +0530781**
782** Parameters: task_id - (input) The destination task Id for the event.
783** event - (input) The event flag
784**
785** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
786**
787** NOTE This function is NOT called by the Widcomm stack and
788** profiles. If you want to use it in your own implementation,
789** put your code here, otherwise you can delete the entire
790** body of the function.
791**
792*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530793uint8_t GKI_isend_event(uint8_t task_id, uint16_t event) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530794 DLOG_IF(INFO, nfc_debug_enabled)
795 << StringPrintf("GKI_isend_event %d %x", task_id, event);
796 DLOG_IF(INFO, nfc_debug_enabled)
797 << StringPrintf("GKI_isend_event %d %x done", task_id, event);
nxpandroid8f6d0532017-07-12 18:25:30 +0530798 return GKI_send_event(task_id, event);
nxpandroidc7611652015-09-23 16:42:05 +0530799}
800
nxpandroidc7611652015-09-23 16:42:05 +0530801/*******************************************************************************
802**
803** Function GKI_get_taskid
804**
805** Description This function gets the currently running task ID.
806**
807** Returns task ID
808**
nxpandroid8f6d0532017-07-12 18:25:30 +0530809** NOTE The Widcomm upper stack and profiles may run as a single
810** task. If you only have one GKI task, then you can hard-code
811** this function to return a '1'. Otherwise, you should have
812** some OS-specific method to determine the current task.
nxpandroidc7611652015-09-23 16:42:05 +0530813**
814*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530815uint8_t GKI_get_taskid(void) {
816 int i;
nxpandroid8f6d0532017-07-12 18:25:30 +0530817 pthread_t thread_id = pthread_self();
818 for (i = 0; i < GKI_MAX_TASKS; i++) {
nxf24591e1fb2f92018-06-06 14:41:56 +0530819#if (NXP_EXTNS == TRUE)
820 if (0 == memcmp(&(gki_cb.os.thread_id[i]), &thread_id, sizeof(pthread_t))) {
821#else
nxpandroid8f6d0532017-07-12 18:25:30 +0530822 if (gki_cb.os.thread_id[i] == thread_id) {
nxf24591e1fb2f92018-06-06 14:41:56 +0530823#endif
nxpandroid8f6d0532017-07-12 18:25:30 +0530824 return (i);
nxpandroidc7611652015-09-23 16:42:05 +0530825 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530826 }
nxpandroid8f6d0532017-07-12 18:25:30 +0530827 return (-1);
nxpandroidc7611652015-09-23 16:42:05 +0530828}
829
830/*******************************************************************************
831**
832** Function GKI_map_taskname
833**
nxpandroid8f6d0532017-07-12 18:25:30 +0530834** Description This function gets the task name of the taskid passed as
835** arg. If GKI_MAX_TASKS is passed as arg the currently running
836** task name is returned
nxpandroidc7611652015-09-23 16:42:05 +0530837**
838** Parameters: task_id - (input) The id of the task whose name is being
839** sought. GKI_MAX_TASKS is passed to get the name of the
840** currently running task.
841**
842** Returns pointer to task name
843**
844** NOTE this function needs no customization
845**
846*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530847int8_t* GKI_map_taskname(uint8_t task_id) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530848 DLOG_IF(INFO, nfc_debug_enabled)
849 << StringPrintf("GKI_map_taskname %d", task_id);
nxpandroidc7611652015-09-23 16:42:05 +0530850
nxpandroid8f6d0532017-07-12 18:25:30 +0530851 if (task_id < GKI_MAX_TASKS) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530852 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
853 "GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
nxpandroid8f6d0532017-07-12 18:25:30 +0530854 return (gki_cb.com.OSTName[task_id]);
855 } else if (task_id == GKI_MAX_TASKS) {
856 return (gki_cb.com.OSTName[GKI_get_taskid()]);
857 } else {
858 return (int8_t*)"BAD";
859 }
nxpandroidc7611652015-09-23 16:42:05 +0530860}
861
nxpandroidc7611652015-09-23 16:42:05 +0530862/*******************************************************************************
863**
864** Function GKI_enable
865**
866** Description This function enables interrupts.
867**
868** Returns void
869**
870*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530871void GKI_enable(void) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530872 pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
nxf24591c1cbeab2018-02-21 17:32:26 +0530873 /* pthread_mutex_xx is nesting save, no need for this: already_disabled =
874 * 0; */
nxpandroid8f6d0532017-07-12 18:25:30 +0530875 return;
nxpandroidc7611652015-09-23 16:42:05 +0530876}
877
nxpandroidc7611652015-09-23 16:42:05 +0530878/*******************************************************************************
879**
880** Function GKI_disable
881**
882** Description This function disables interrupts.
883**
884** Returns void
885**
886*******************************************************************************/
887
nxpandroid8f6d0532017-07-12 18:25:30 +0530888void GKI_disable(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530889 // DLOG_IF(INFO, nfc_debug_enabled) <<
890 // StringPrintf("GKI_disable");
nxpandroidc7611652015-09-23 16:42:05 +0530891
nxf24591c1cbeab2018-02-21 17:32:26 +0530892 /* pthread_mutex_xx is nesting save, no need for this: if
893 (!already_disabled) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530894 already_disabled = 1; */
895 pthread_mutex_lock(&gki_cb.os.GKI_mutex);
896 /* } */
nxf24591c1cbeab2018-02-21 17:32:26 +0530897 // DLOG_IF(INFO, nfc_debug_enabled) <<
898 // StringPrintf("Leaving GKI_disable");
nxpandroid8f6d0532017-07-12 18:25:30 +0530899 return;
nxpandroidc7611652015-09-23 16:42:05 +0530900}
901
nxpandroidc7611652015-09-23 16:42:05 +0530902/*******************************************************************************
903**
904** Function GKI_exception
905**
906** Description This function throws an exception.
907** This is normally only called for a nonrecoverable error.
908**
909** Parameters: code - (input) The code for the error
910** msg - (input) The message that has to be logged
911**
912** Returns void
913**
914*******************************************************************************/
915
nxf24591c1cbeab2018-02-21 17:32:26 +0530916void GKI_exception(uint16_t code, std::string msg) {
nxpandroid8f6d0532017-07-12 18:25:30 +0530917 uint8_t task_id;
nxpandroidc7611652015-09-23 16:42:05 +0530918
nxf24591c1cbeab2018-02-21 17:32:26 +0530919 LOG(ERROR) << StringPrintf("Task State Table");
nxpandroidc7611652015-09-23 16:42:05 +0530920
nxpandroid8f6d0532017-07-12 18:25:30 +0530921 for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
nxf24591c1cbeab2018-02-21 17:32:26 +0530922 LOG(ERROR) << StringPrintf("TASK ID [%d] task name [%s] state [%d]",
923 task_id, gki_cb.com.OSTName[task_id],
924 gki_cb.com.OSRdyTbl[task_id]);
nxpandroid8f6d0532017-07-12 18:25:30 +0530925 }
nxpandroidc7611652015-09-23 16:42:05 +0530926
nxf24591c1cbeab2018-02-21 17:32:26 +0530927 LOG(ERROR) << StringPrintf("%d %s", code, msg.c_str());
928 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530929 "********************************************************************");
nxf24591c1cbeab2018-02-21 17:32:26 +0530930 LOG(ERROR) << StringPrintf("* %d %s", code, msg.c_str());
931 LOG(ERROR) << StringPrintf(
nxpandroid8f6d0532017-07-12 18:25:30 +0530932 "********************************************************************");
nxpandroidc7611652015-09-23 16:42:05 +0530933
nxf24591c1cbeab2018-02-21 17:32:26 +0530934 LOG(ERROR) << StringPrintf("%d %s done", code, msg.c_str());
nxpandroidc7611652015-09-23 16:42:05 +0530935
nxpandroid8f6d0532017-07-12 18:25:30 +0530936 return;
nxpandroidc7611652015-09-23 16:42:05 +0530937}
938
nxpandroidc7611652015-09-23 16:42:05 +0530939/*******************************************************************************
940**
941** Function GKI_get_time_stamp
942**
943** Description This function formats the time into a user area
944**
945** Parameters: tbuf - (output) the address to the memory containing the
946** formatted time
947**
948** Returns the address of the user area containing the formatted time
949** The format of the time is ????
950**
951** NOTE This function is only called by OBEX.
952**
953*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +0530954int8_t* GKI_get_time_stamp(int8_t* tbuf) {
955 uint32_t ms_time;
956 uint32_t s_time;
957 uint32_t m_time;
958 uint32_t h_time;
959 int8_t* p_out = tbuf;
nxpandroidc7611652015-09-23 16:42:05 +0530960
nxf24591c1cbeab2018-02-21 17:32:26 +0530961 gki_cb.com.OSTicks = times(0);
nxpandroid8f6d0532017-07-12 18:25:30 +0530962 ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
963 s_time = ms_time / 100; /* 100 Ticks per second */
964 m_time = s_time / 60;
965 h_time = m_time / 60;
nxpandroidc7611652015-09-23 16:42:05 +0530966
nxpandroid8f6d0532017-07-12 18:25:30 +0530967 ms_time -= s_time * 100;
968 s_time -= m_time * 60;
969 m_time -= h_time * 60;
nxpandroidc7611652015-09-23 16:42:05 +0530970
nxpandroid8f6d0532017-07-12 18:25:30 +0530971 *p_out++ = (int8_t)((h_time / 10) + '0');
972 *p_out++ = (int8_t)((h_time % 10) + '0');
973 *p_out++ = ':';
974 *p_out++ = (int8_t)((m_time / 10) + '0');
975 *p_out++ = (int8_t)((m_time % 10) + '0');
976 *p_out++ = ':';
977 *p_out++ = (int8_t)((s_time / 10) + '0');
978 *p_out++ = (int8_t)((s_time % 10) + '0');
979 *p_out++ = ':';
980 *p_out++ = (int8_t)((ms_time / 10) + '0');
981 *p_out++ = (int8_t)((ms_time % 10) + '0');
982 *p_out++ = ':';
983 *p_out = 0;
nxpandroidc7611652015-09-23 16:42:05 +0530984
nxpandroid8f6d0532017-07-12 18:25:30 +0530985 return (tbuf);
nxpandroidc7611652015-09-23 16:42:05 +0530986}
987
nxpandroidc7611652015-09-23 16:42:05 +0530988/*******************************************************************************
989**
990** Function GKI_register_mempool
991**
992** Description This function registers a specific memory pool.
993**
994** Parameters: p_mem - (input) pointer to the memory pool
995**
996** Returns void
997**
998** NOTE This function is NOT called by the Widcomm stack and
999** profiles. If your OS has different memory pools, you
1000** can tell GKI the pool to use by calling this function.
1001**
1002*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301003void GKI_register_mempool(void* p_mem) {
1004 gki_cb.com.p_user_mempool = p_mem;
nxpandroidc7611652015-09-23 16:42:05 +05301005
nxpandroid8f6d0532017-07-12 18:25:30 +05301006 return;
nxpandroidc7611652015-09-23 16:42:05 +05301007}
1008
1009/*******************************************************************************
1010**
1011** Function GKI_os_malloc
1012**
1013** Description This function allocates memory
1014**
1015** Parameters: size - (input) The size of the memory that has to be
1016** allocated
1017**
1018** Returns the address of the memory allocated, or NULL if failed
1019**
1020** NOTE This function is called by the Widcomm stack when
nxpandroid8f6d0532017-07-12 18:25:30 +05301021** dynamic memory allocation is used.
nxpandroidc7611652015-09-23 16:42:05 +05301022**
1023*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301024void* GKI_os_malloc(uint32_t size) { return (malloc(size)); }
nxpandroidc7611652015-09-23 16:42:05 +05301025
1026/*******************************************************************************
1027**
1028** Function GKI_os_free
1029**
1030** Description This function frees memory
1031**
1032** Parameters: size - (input) The address of the memory that has to be
1033** freed
1034**
1035** Returns void
1036**
1037** NOTE This function is NOT called by the Widcomm stack and
1038** profiles. It is only called from within GKI if dynamic
1039**
1040*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301041void GKI_os_free(void* p_mem) {
1042 if (p_mem != NULL) free(p_mem);
1043 return;
nxpandroidc7611652015-09-23 16:42:05 +05301044}
1045
nxpandroidc7611652015-09-23 16:42:05 +05301046/*******************************************************************************
1047**
1048** Function GKI_suspend_task()
1049**
1050** Description This function suspends the task specified in the argument.
1051**
1052** Parameters: task_id - (input) the id of the task that has to suspended
1053**
1054** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
1055**
1056** NOTE This function is NOT called by the Widcomm stack and
nxpandroid8f6d0532017-07-12 18:25:30 +05301057** profiles. If you want to implement task suspension
1058** capability, put specific code here.
nxpandroidc7611652015-09-23 16:42:05 +05301059**
1060*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301061uint8_t GKI_suspend_task(uint8_t task_id) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301062 DLOG_IF(INFO, nfc_debug_enabled)
1063 << StringPrintf("GKI_suspend_task %d - NOT implemented", task_id);
nxpandroidc7611652015-09-23 16:42:05 +05301064
nxf24591c1cbeab2018-02-21 17:32:26 +05301065 DLOG_IF(INFO, nfc_debug_enabled)
1066 << StringPrintf("GKI_suspend_task %d done", task_id);
nxpandroidc7611652015-09-23 16:42:05 +05301067
nxpandroid8f6d0532017-07-12 18:25:30 +05301068 return (GKI_SUCCESS);
nxpandroidc7611652015-09-23 16:42:05 +05301069}
1070
nxpandroidc7611652015-09-23 16:42:05 +05301071/*******************************************************************************
1072**
1073** Function GKI_resume_task()
1074**
1075** Description This function resumes the task specified in the argument.
1076**
1077** Parameters: task_id - (input) the id of the task that has to resumed
1078**
1079** Returns GKI_SUCCESS if all OK
1080**
1081** NOTE This function is NOT called by the Widcomm stack and
nxpandroid8f6d0532017-07-12 18:25:30 +05301082** profiles. If you want to implement task suspension
1083** capability, put specific code here.
nxpandroidc7611652015-09-23 16:42:05 +05301084**
1085*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301086uint8_t GKI_resume_task(uint8_t task_id) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301087 DLOG_IF(INFO, nfc_debug_enabled)
1088 << StringPrintf("GKI_resume_task %d - NOT implemented", task_id);
nxpandroidcdd30442016-05-27 17:26:18 +05301089
nxf24591c1cbeab2018-02-21 17:32:26 +05301090 DLOG_IF(INFO, nfc_debug_enabled)
1091 << StringPrintf("GKI_resume_task %d done", task_id);
nxpandroidc7611652015-09-23 16:42:05 +05301092
nxpandroid8f6d0532017-07-12 18:25:30 +05301093 return (GKI_SUCCESS);
nxpandroidc7611652015-09-23 16:42:05 +05301094}
1095
nxpandroidc7611652015-09-23 16:42:05 +05301096/*******************************************************************************
1097**
1098** Function GKI_exit_task
1099**
1100** Description This function is called to stop a GKI task.
1101**
1102** Parameters: task_id - (input) the id of the task that has to be stopped
1103**
1104** Returns void
1105**
1106** NOTE This function is NOT called by the Widcomm stack and
1107** profiles. If you want to use it in your own implementation,
1108** put specific code here to kill a task.
1109**
1110*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301111void GKI_exit_task(uint8_t task_id) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301112 if (task_id >= GKI_MAX_TASKS) {
1113 return;
1114 }
nxpandroid8f6d0532017-07-12 18:25:30 +05301115 GKI_disable();
1116 gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
nxpandroidc7611652015-09-23 16:42:05 +05301117
nxpandroid8f6d0532017-07-12 18:25:30 +05301118 /* Destroy mutex and condition variable objects */
1119 pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
1120 pthread_cond_destroy(&gki_cb.os.thread_evt_cond[task_id]);
1121 pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
1122 pthread_cond_destroy(&gki_cb.os.thread_timeout_cond[task_id]);
nxpandroidc7611652015-09-23 16:42:05 +05301123
nxpandroid8f6d0532017-07-12 18:25:30 +05301124 GKI_enable();
nxpandroidc7611652015-09-23 16:42:05 +05301125
nxpandroid8f6d0532017-07-12 18:25:30 +05301126 // GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
nxpandroidc7611652015-09-23 16:42:05 +05301127
nxf24591c1cbeab2018-02-21 17:32:26 +05301128 DLOG_IF(INFO, nfc_debug_enabled)
1129 << StringPrintf("GKI_exit_task %d done", task_id);
nxpandroid8f6d0532017-07-12 18:25:30 +05301130 return;
nxpandroidc7611652015-09-23 16:42:05 +05301131}
1132
nxpandroidc7611652015-09-23 16:42:05 +05301133/*******************************************************************************
1134**
1135** Function GKI_sched_lock
1136**
1137** Description This function is called by tasks to disable scheduler
1138** task context switching.
1139**
1140** Returns void
1141**
1142** NOTE This function is NOT called by the Widcomm stack and
1143** profiles. If you want to use it in your own implementation,
1144** put code here to tell the OS to disable context switching.
1145**
1146*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301147void GKI_sched_lock(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301148 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("GKI_sched_lock");
nxpandroid8f6d0532017-07-12 18:25:30 +05301149 GKI_disable();
1150 return;
nxpandroidc7611652015-09-23 16:42:05 +05301151}
1152
nxpandroidc7611652015-09-23 16:42:05 +05301153/*******************************************************************************
1154**
1155** Function GKI_sched_unlock
1156**
nxpandroid8f6d0532017-07-12 18:25:30 +05301157** Description This function is called by tasks to enable scheduler
1158** switching.
nxpandroidc7611652015-09-23 16:42:05 +05301159**
1160** Returns void
1161**
1162** NOTE This function is NOT called by the Widcomm stack and
1163** profiles. If you want to use it in your own implementation,
1164** put code here to tell the OS to re-enable context switching.
1165**
1166*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301167void GKI_sched_unlock(void) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301168 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("GKI_sched_unlock");
nxpandroid8f6d0532017-07-12 18:25:30 +05301169 GKI_enable();
nxpandroidc7611652015-09-23 16:42:05 +05301170}
1171
1172/*******************************************************************************
1173**
1174** Function GKI_shiftdown
1175**
1176** Description shift memory down (to make space to insert a record)
1177**
1178*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301179void GKI_shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301180 uint8_t* ps = p_mem + len - 1;
1181 uint8_t* pd = ps + shift_amount;
1182 uint32_t xx;
nxpandroidc7611652015-09-23 16:42:05 +05301183
nxpandroid8f6d0532017-07-12 18:25:30 +05301184 for (xx = 0; xx < len; xx++) *pd-- = *ps--;
nxpandroidc7611652015-09-23 16:42:05 +05301185}
1186
1187/*******************************************************************************
1188**
1189** Function GKI_shiftup
1190**
1191** Description shift memory up (to delete a record)
1192**
1193*******************************************************************************/
nxpandroid8f6d0532017-07-12 18:25:30 +05301194void GKI_shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
nxf24591c1cbeab2018-02-21 17:32:26 +05301195 uint8_t* ps = p_src;
1196 uint8_t* pd = p_dest;
1197 uint32_t xx;
nxpandroidc7611652015-09-23 16:42:05 +05301198
nxpandroid8f6d0532017-07-12 18:25:30 +05301199 for (xx = 0; xx < len; xx++) *pd++ = *ps++;
nxpandroidc7611652015-09-23 16:42:05 +05301200}