Home | History | Annotate | Download | only in ulinux
      1 /******************************************************************************
      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  ******************************************************************************/
     18 #include <errno.h>
     19 #include <malloc.h>
     20 #include <pthread.h> /* must be 1st header defined  */
     21 
     22 #include <android-base/stringprintf.h>
     23 #include <base/logging.h>
     24 
     25 #include "gki_int.h"
     26 
     27 using android::base::StringPrintf;
     28 
     29 extern bool nfc_debug_enabled;
     30 
     31 /* Temp android logging...move to android tgt config file */
     32 
     33 #ifndef LINUX_NATIVE
     34 #else
     35 #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__)
     38 
     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 */
     48 tGKI_CB gki_cb;
     49 
     50 #define NANOSEC_PER_MILLISEC (1000000)
     51 #define NSEC_PER_SEC (1000 * NANOSEC_PER_MILLISEC)
     52 
     53 /* works only for 1ms to 1000ms heart beat ranges */
     54 #define LINUX_SEC (1000 / TICKS_PER_SEC)
     55 // #define GKI_TICK_TIMER_DEBUG
     56 
     57 /* 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;
     60 static pthread_cond_t thread_delay_cond;
     61 static pthread_mutex_t gki_timer_update_mutex;
     62 static pthread_cond_t   gki_timer_update_cond;
     63 */
     64 #ifdef NO_GKI_RUN_RETURN
     65 static pthread_t timer_thread_id = 0;
     66 #endif
     67 
     68 typedef 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*/
     74 } gki_pthread_info_t;
     75 gki_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 *******************************************************************************/
     86 void* gki_task_entry(void* params) {
     87   pthread_t thread_id = pthread_self();
     88   gki_pthread_info_t* p_pthread_info = (gki_pthread_info_t*)params;
     89   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);
     93 
     94   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);
     97 
     98   LOG(ERROR) << StringPrintf("gki_task task_id=%i terminating",
     99                              p_pthread_info->task_id);
    100   gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
    101 
    102   return NULL;
    103 }
    104 /* end android */
    105 
    106 /*******************************************************************************
    107 **
    108 ** Function         GKI_init
    109 **
    110 ** Description      This function is called once at startup to initialize
    111 **                  all the timer structures.
    112 **
    113 ** Returns          void
    114 **
    115 *******************************************************************************/
    116 
    117 void GKI_init(void) {
    118   pthread_mutexattr_t attr;
    119   tGKI_OS* p_os;
    120 
    121   memset(&gki_cb, 0, sizeof(gki_cb));
    122 
    123   gki_buffer_init();
    124   gki_timers_init();
    125   gki_cb.com.OSTicks = (uint32_t)times(0);
    126 
    127   pthread_mutexattr_init(&attr);
    128 
    129 #ifndef __CYGWIN__
    130   pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
    131 #endif
    132   p_os = &gki_cb.os;
    133   pthread_mutex_init(&p_os->GKI_mutex, &attr);
    134   /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
    135   /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
    136   /* pthread_cond_init (&thread_delay_cond, NULL); */
    137 
    138   /* Initialiase GKI_timer_update suspend variables & mutexes to be in running
    139    * state.
    140    * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
    141   p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
    142   pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
    143   pthread_cond_init(&p_os->gki_timer_cond, NULL);
    144 }
    145 
    146 /*******************************************************************************
    147 **
    148 ** Function         GKI_get_os_tick_count
    149 **
    150 ** Description      This function is called to retrieve the native OS system
    151 **                  tick.
    152 **
    153 ** Returns          Tick count of native OS.
    154 **
    155 *******************************************************************************/
    156 uint32_t GKI_get_os_tick_count(void) {
    157   /* TODO - add any OS specific code here
    158   **/
    159   return (gki_cb.com.OSTicks);
    160 }
    161 
    162 /*******************************************************************************
    163 **
    164 ** Function         GKI_create_task
    165 **
    166 ** Description      This function is called to create a new OSS task.
    167 **
    168 ** Parameters:      task_entry  - (input) pointer to the entry function of the
    169 **                                        task
    170 **                  task_id     - (input) Task id is mapped to priority
    171 **                  taskname    - (input) name given to the task
    172 **                  stack       - (input) pointer to the top of the stack
    173 **                                        (highest memory location)
    174 **                  stacksize   - (input) size of the stack allocated for the
    175 **                                        task
    176 **
    177 ** Returns          GKI_SUCCESS if all OK, GKI_FAILURE if any problem
    178 **
    179 ** NOTE             This function take some parameters that may not be needed
    180 **                  by your particular OS. They are here for compatability
    181 **                  of the function prototype.
    182 **
    183 *******************************************************************************/
    184 uint8_t GKI_create_task(TASKPTR task_entry, uint8_t task_id, int8_t* taskname,
    185                         uint16_t* stack, uint16_t stacksize, void* pCondVar,
    186                         void* pMutex) {
    187   struct sched_param param;
    188   int policy, ret = 0;
    189   pthread_condattr_t attr;
    190   pthread_attr_t attr1;
    191 
    192   pthread_condattr_init(&attr);
    193   pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
    194   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    195       "GKI_create_task func=0x%p  id=%d  name=%s  stack=0x%p  stackSize=%d",
    196       task_entry, task_id, taskname, stack, stacksize);
    197 
    198   if (task_id >= GKI_MAX_TASKS) {
    199     DLOG_IF(INFO, nfc_debug_enabled)
    200         << StringPrintf("Error! task ID > max task allowed");
    201     return (GKI_FAILURE);
    202   }
    203 
    204   gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
    205   gki_cb.com.OSTName[task_id] = taskname;
    206   gki_cb.com.OSWaitTmr[task_id] = 0;
    207   gki_cb.com.OSWaitEvt[task_id] = 0;
    208 
    209   /* Initialize mutex and condition variable objects for events and timeouts */
    210   pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
    211   pthread_cond_init(&gki_cb.os.thread_evt_cond[task_id], &attr);
    212   pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
    213   pthread_cond_init(&gki_cb.os.thread_timeout_cond[task_id], &attr);
    214 
    215   pthread_attr_init(&attr1);
    216 /* by default, pthread creates a joinable thread */
    217 #if (FALSE == GKI_PTHREAD_JOINABLE)
    218   pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
    219 
    220   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    221       "GKI creating task %i, pCond/pMutex=%p/%p", task_id, pCondVar, pMutex);
    222 #else
    223   DLOG_IF(INFO, nfc_debug_enabled)
    224       << StringPrintf("GKI creating JOINABLE task %i", task_id);
    225 #endif
    226 
    227   /* On Android, the new tasks starts running before
    228    * 'gki_cb.os.thread_id[task_id]' is initialized */
    229   /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id]
    230    * for it calls GKI_wait */
    231   gki_pthread_info[task_id].task_id = task_id;
    232   gki_pthread_info[task_id].task_entry = task_entry;
    233   gki_pthread_info[task_id].params = 0;
    234   gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
    235   gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
    236 
    237   ret = pthread_create(&gki_cb.os.thread_id[task_id], &attr1, gki_task_entry,
    238                        &gki_pthread_info[task_id]);
    239 
    240   if (ret != 0) {
    241     DLOG_IF(INFO, nfc_debug_enabled)
    242         << StringPrintf("pthread_create failed(%d), %s!", ret, taskname);
    243     return GKI_FAILURE;
    244   }
    245 
    246   if (pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, &param) ==
    247       0) {
    248 #if (PBS_SQL_TASK == TRUE)
    249     if (task_id == PBS_SQL_TASK) {
    250       DLOG_IF(INFO, nfc_debug_enabled)
    251           << StringPrintf("PBS SQL lowest priority task");
    252       policy = SCHED_NORMAL;
    253     } else
    254 #endif
    255     {
    256       policy = SCHED_RR;
    257       param.sched_priority = 30 - task_id - 2;
    258     }
    259     pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, &param);
    260   }
    261 
    262   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    263       "Leaving GKI_create_task %p %d %lx %s %p %d", task_entry, task_id,
    264       gki_cb.os.thread_id[task_id], taskname, stack, stacksize);
    265 
    266   return (GKI_SUCCESS);
    267 }
    268 
    269 /*******************************************************************************
    270 **
    271 ** Function         GKI_shutdown
    272 **
    273 ** Description      shutdowns the GKI tasks/threads in from max task id to 0 and
    274 **                  frees pthread resources!
    275 **                  IMPORTANT: in case of join method, GKI_shutdown must be
    276 **                  called outside a GKI thread context!
    277 **
    278 ** Returns          void
    279 **
    280 *******************************************************************************/
    281 #define WAKE_LOCK_ID "brcm_nfca"
    282 #define PARTIAL_WAKE_LOCK 1
    283 extern "C" int acquire_wake_lock(int lock, const char* id);
    284 extern "C" int release_wake_lock(const char* id);
    285 
    286 void GKI_shutdown(void) {
    287   uint8_t task_id;
    288   volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
    289   int oldCOnd = 0;
    290 #if (FALSE == GKI_PTHREAD_JOINABLE)
    291   int i = 0;
    292 #else
    293   int result;
    294 #endif
    295 
    296   /* release threads and set as TASK_DEAD. going from low to high priority fixes
    297    * GKI_exception problem due to btu->hci sleep request events  */
    298   for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--) {
    299     if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD) {
    300       gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
    301 
    302       /* paranoi settings, make sure that we do not execute any mailbox events
    303        */
    304       gki_cb.com.OSWaitEvt[task_id - 1] &=
    305           ~(TASK_MBOX_0_EVT_MASK | TASK_MBOX_1_EVT_MASK | TASK_MBOX_2_EVT_MASK |
    306             TASK_MBOX_3_EVT_MASK);
    307       GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
    308 
    309 #if (FALSE == GKI_PTHREAD_JOINABLE)
    310       i = 0;
    311 
    312       while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
    313         usleep(100 * 1000);
    314 #else
    315       /* wait for proper Arnold Schwarzenegger task state */
    316       result = pthread_join(gki_cb.os.thread_id[task_id - 1], NULL);
    317       if (result < 0) {
    318         DLOG_IF(INFO, nfc_debug_enabled)
    319             << StringPrintf("FAILED: result: %d", result);
    320       }
    321 #endif
    322       DLOG_IF(INFO, nfc_debug_enabled)
    323           << StringPrintf("task %s dead", gki_cb.com.OSTName[task_id]);
    324       GKI_exit_task(task_id - 1);
    325     }
    326   }
    327 
    328   /* Destroy mutex and condition variable objects */
    329   pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
    330 /*    pthread_mutex_destroy(&GKI_sched_mutex); */
    331 /*    pthread_mutex_destroy(&thread_delay_mutex);
    332  pthread_cond_destroy (&thread_delay_cond); */
    333 #if (FALSE == GKI_PTHREAD_JOINABLE)
    334   i = 0;
    335 #endif
    336 
    337 #ifdef NO_GKI_RUN_RETURN
    338   shutdown_timer = 1;
    339 #endif
    340   if (gki_cb.os.gki_timer_wake_lock_on) {
    341     DLOG_IF(INFO, nfc_debug_enabled)
    342         << StringPrintf("GKI_shutdown :  release_wake_lock(brcm_btld)");
    343     release_wake_lock(WAKE_LOCK_ID);
    344     gki_cb.os.gki_timer_wake_lock_on = 0;
    345   }
    346   oldCOnd = *p_run_cond;
    347   *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
    348   if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
    349     pthread_cond_signal(&gki_cb.os.gki_timer_cond);
    350 }
    351 
    352 /*******************************************************************************
    353  **
    354  ** Function        GKI_run
    355  **
    356  ** Description     This function runs a task
    357  **
    358  ** Parameters:     start: TRUE start system tick (again), FALSE stop
    359  **
    360  ** Returns         void
    361  **
    362  ******************************************************************************/
    363 void gki_system_tick_start_stop_cback(bool start) {
    364   tGKI_OS* p_os = &gki_cb.os;
    365   volatile int* p_run_cond = &p_os->no_timer_suspend;
    366 #ifdef GKI_TICK_TIMER_DEBUG
    367   static volatile int wake_lock_count;
    368 #endif
    369   if (start == false) {
    370     /* this can lead to a race condition. however as we only read this variable
    371      * in the timer loop
    372      * we should be fine with this approach. otherwise uncomment below mutexes.
    373      */
    374     /* GKI_disable(); */
    375     *p_run_cond = GKI_TIMER_TICK_STOP_COND;
    376 /* GKI_enable(); */
    377 #ifdef GKI_TICK_TIMER_DEBUG
    378     DLOG_IF(INFO, nfc_debug_enabled)
    379         << StringPrintf(">>> STOP wake_lock_count:%d", --wake_lock_count);
    380 #endif
    381     release_wake_lock(WAKE_LOCK_ID);
    382     gki_cb.os.gki_timer_wake_lock_on = 0;
    383   } else {
    384     /* restart GKI_timer_update() loop */
    385     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
    386     gki_cb.os.gki_timer_wake_lock_on = 1;
    387     *p_run_cond = GKI_TIMER_TICK_RUN_COND;
    388     pthread_mutex_lock(&p_os->gki_timer_mutex);
    389     pthread_cond_signal(&p_os->gki_timer_cond);
    390     pthread_mutex_unlock(&p_os->gki_timer_mutex);
    391 
    392 #ifdef GKI_TICK_TIMER_DEBUG
    393     DLOG_IF(INFO, nfc_debug_enabled)
    394         << StringPrintf(">>> START wake_lock_count:%d", ++wake_lock_count);
    395 #endif
    396   }
    397 }
    398 
    399 /*******************************************************************************
    400 **
    401 ** Function         timer_thread
    402 **
    403 ** Description      Timer thread
    404 **
    405 ** Parameters:      id  - (input) timer ID
    406 **
    407 ** Returns          void
    408 **
    409 *******************************************************************************/
    410 #ifdef NO_GKI_RUN_RETURN
    411 void timer_thread(signed long id) {
    412   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s enter", __func__);
    413   struct timespec delay;
    414   int timeout = 1000; /* 10  ms per system tick  */
    415   int err;
    416 
    417   while (!shutdown_timer) {
    418     delay.tv_sec = timeout / 1000;
    419     delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
    420 
    421     /* [u]sleep can't be used because it uses SIGALRM */
    422 
    423     do {
    424       err = nanosleep(&delay, &delay);
    425     } while (err < 0 && errno == EINTR);
    426 
    427     GKI_timer_update(1);
    428   }
    429   LOG(ERROR) << StringPrintf("%s exit", __func__);
    430   return;
    431 }
    432 #endif
    433 
    434 /*******************************************************************************
    435 **
    436 ** Function         GKI_run
    437 **
    438 ** Description      This function runs a task
    439 **
    440 ** Parameters:      p_task_id  - (input) pointer to task id
    441 **
    442 ** Returns          void
    443 **
    444 ** NOTE             This function is only needed for operating systems where
    445 **                  starting a task is a 2-step process. Most OS's do it in
    446 **                  one step, If your OS does it in one step, this function
    447 **                  should be empty.
    448 *******************************************************************************/
    449 void GKI_run(__attribute__((unused)) void* p_task_id) {
    450   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s enter", __func__);
    451   struct timespec delay;
    452   int err = 0;
    453   volatile int* p_run_cond = &gki_cb.os.no_timer_suspend;
    454 
    455 #ifndef GKI_NO_TICK_STOP
    456   /* register start stop function which disable timer loop in GKI_run() when no
    457    * timers are
    458    * in any GKI/BTA/BTU this should save power when BTLD is idle! */
    459   GKI_timer_queue_register_callback(gki_system_tick_start_stop_cback);
    460   DLOG_IF(INFO, nfc_debug_enabled)
    461       << StringPrintf("Start/Stop GKI_timer_update_registered!");
    462 #endif
    463 
    464 #ifdef NO_GKI_RUN_RETURN
    465   DLOG_IF(INFO, nfc_debug_enabled)
    466       << StringPrintf("GKI_run == NO_GKI_RUN_RETURN");
    467   pthread_attr_t timer_attr;
    468 
    469   shutdown_timer = 0;
    470 
    471   pthread_attr_init(&timer_attr);
    472   pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
    473   if (pthread_create(&timer_thread_id, &timer_attr, timer_thread, NULL) != 0) {
    474     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    475         "GKI_run: pthread_create failed to create timer_thread!");
    476     return GKI_FAILURE;
    477   }
    478 #else
    479   DLOG_IF(INFO, nfc_debug_enabled)
    480       << StringPrintf("GKI_run, run_cond(%p)=%d ", p_run_cond, *p_run_cond);
    481   for (; GKI_TIMER_TICK_EXIT_COND != *p_run_cond;) {
    482     do {
    483       /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this
    484        * formula works only for
    485        * 1-1000ms heart beat units! */
    486       delay.tv_sec = LINUX_SEC / 1000;
    487       delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
    488 
    489       /* [u]sleep can't be used because it uses SIGALRM */
    490       do {
    491         err = nanosleep(&delay, &delay);
    492       } while (err < 0 && errno == EINTR);
    493 
    494       if (GKI_TIMER_TICK_RUN_COND != *p_run_cond) break;  // GKI has shutdown
    495 
    496       /* the unit should be alsways 1 (1 tick). only if you vary for some reason
    497        * heart beat tick
    498        * e.g. power saving you may want to provide more ticks
    499        */
    500       GKI_timer_update(1);
    501     } while (GKI_TIMER_TICK_RUN_COND == *p_run_cond);
    502 
    503 /* currently on reason to exit above loop is no_timer_suspend ==
    504  * GKI_TIMER_TICK_STOP_COND
    505  * block timer main thread till re-armed by  */
    506 #ifdef GKI_TICK_TIMER_DEBUG
    507     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(">>> SUSPENDED");
    508 #endif
    509     if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
    510       pthread_mutex_lock(&gki_cb.os.gki_timer_mutex);
    511       pthread_cond_wait(&gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex);
    512       pthread_mutex_unlock(&gki_cb.os.gki_timer_mutex);
    513     }
    514 /* potentially we need to adjust os gki_cb.com.OSTicks */
    515 
    516 #ifdef GKI_TICK_TIMER_DEBUG
    517     DLOG_IF(INFO, nfc_debug_enabled)
    518         << StringPrintf(">>> RESTARTED run_cond: %d", *p_run_cond);
    519 #endif
    520   } /* for */
    521 #endif
    522   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s exit", __func__);
    523 }
    524 
    525 /*******************************************************************************
    526 **
    527 ** Function         GKI_stop
    528 **
    529 ** Description      This function is called to stop
    530 **                  the tasks and timers when the system is being stopped
    531 **
    532 ** Returns          void
    533 **
    534 ** NOTE             This function is NOT called by the Widcomm stack and
    535 **                  profiles. If you want to use it in your own implementation,
    536 **                  put specific code here.
    537 **
    538 *******************************************************************************/
    539 void GKI_stop(void) {
    540   uint8_t task_id;
    541 
    542   /*  gki_queue_timer_cback(FALSE); */
    543   /* TODO - add code here if needed*/
    544 
    545   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
    546     if (gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD) {
    547       GKI_exit_task(task_id);
    548     }
    549   }
    550 }
    551 
    552 /*******************************************************************************
    553 **
    554 ** Function         GKI_wait
    555 **
    556 ** Description      This function is called by tasks to wait for a specific
    557 **                  event or set of events. The task may specify the duration
    558 **                  that it wants to wait for, or 0 if infinite.
    559 **
    560 ** Parameters:      flag -    (input) the event or set of events to wait for
    561 **                  timeout - (input) the duration that the task wants to wait
    562 **                                    for the specific events (in system ticks)
    563 **
    564 **
    565 ** Returns          the event mask of received events or zero if timeout
    566 **
    567 *******************************************************************************/
    568 uint16_t GKI_wait(uint16_t flag, uint32_t timeout) {
    569   uint16_t evt;
    570   uint8_t rtask;
    571   struct timespec abstime = {0, 0};
    572   int sec;
    573   int nano_sec;
    574 
    575   rtask = GKI_get_taskid();
    576   if (rtask >= GKI_MAX_TASKS) {
    577     LOG(ERROR) << StringPrintf("%s() Exiting thread; rtask %d >= %d", __func__,
    578                                rtask, GKI_MAX_TASKS);
    579     return EVENT_MASK(GKI_SHUTDOWN_EVT);
    580   }
    581 
    582   gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
    583   if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
    584     int ret;
    585     DLOG_IF(INFO, nfc_debug_enabled)
    586         << StringPrintf("GKI_wait task=%i, pCond/pMutex = %p/%p", rtask,
    587                         p_pthread_info->pCond, p_pthread_info->pMutex);
    588     ret = pthread_mutex_lock(p_pthread_info->pMutex);
    589     ret = pthread_cond_signal(p_pthread_info->pCond);
    590     ret = pthread_mutex_unlock(p_pthread_info->pMutex);
    591     p_pthread_info->pMutex = NULL;
    592     p_pthread_info->pCond = NULL;
    593   }
    594   gki_cb.com.OSWaitForEvt[rtask] = flag;
    595 
    596   /* protect OSWaitEvt[rtask] from modification from an other thread */
    597   pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
    598 
    599 #if 0 /* for clean scheduling we probably should always call \
    600          pthread_cond_wait() */
    601     /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
    602      has been modified. however this should only result in addtional call to  pthread_cond_wait() but as
    603      the cond is met, it will exit immediately (depending on schedulling) */
    604     if (gki_cb.com.OSTaskQFirst[rtask][0])
    605     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
    606     if (gki_cb.com.OSTaskQFirst[rtask][1])
    607     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
    608     if (gki_cb.com.OSTaskQFirst[rtask][2])
    609     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
    610     if (gki_cb.com.OSTaskQFirst[rtask][3])
    611     gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
    612 #endif
    613 
    614   if (!(gki_cb.com.OSWaitEvt[rtask] & flag)) {
    615     if (timeout) {
    616       //            timeout = GKI_MS_TO_TICKS(timeout);     /* convert from
    617       //            milliseconds to ticks */
    618 
    619       /* get current system time */
    620       //            clock_gettime(CLOCK_MONOTONIC, &currSysTime);
    621       //            abstime.tv_sec = currSysTime.time;
    622       //            abstime.tv_nsec = NANOSEC_PER_MILLISEC *
    623       //            currSysTime.millitm;
    624       clock_gettime(CLOCK_MONOTONIC, &abstime);
    625 
    626       /* add timeout */
    627       sec = timeout / 1000;
    628       nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
    629       abstime.tv_nsec += nano_sec;
    630       if (abstime.tv_nsec > NSEC_PER_SEC) {
    631         abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
    632         abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
    633       }
    634       abstime.tv_sec += sec;
    635 
    636       pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
    637                              &gki_cb.os.thread_evt_mutex[rtask], &abstime);
    638 
    639     } else {
    640       pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask],
    641                         &gki_cb.os.thread_evt_mutex[rtask]);
    642     }
    643 
    644     /* TODO: check, this is probably neither not needed depending on
    645      phtread_cond_wait() implmentation,
    646      e.g. it looks like it is implemented as a counter in which case multiple
    647      cond_signal
    648      should NOT be lost! */
    649     // we are waking up after waiting for some events, so refresh variables
    650     // no need to call GKI_disable() here as we know that we will have some
    651     // events as we've been waking up after condition pending or timeout
    652     if (gki_cb.com.OSTaskQFirst[rtask][0])
    653       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
    654     if (gki_cb.com.OSTaskQFirst[rtask][1])
    655       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
    656     if (gki_cb.com.OSTaskQFirst[rtask][2])
    657       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
    658     if (gki_cb.com.OSTaskQFirst[rtask][3])
    659       gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
    660 
    661     if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
    662       gki_cb.com.OSWaitEvt[rtask] = 0;
    663       /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond
    664        * is met */
    665       pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
    666       LOG(ERROR) << StringPrintf("GKI TASK_DEAD received. exit thread %d...",
    667                                  rtask);
    668 
    669       gki_cb.os.thread_id[rtask] = 0;
    670       return (EVENT_MASK(GKI_SHUTDOWN_EVT));
    671     }
    672   }
    673 
    674   /* Clear the wait for event mask */
    675   gki_cb.com.OSWaitForEvt[rtask] = 0;
    676 
    677   /* Return only those bits which user wants... */
    678   evt = gki_cb.com.OSWaitEvt[rtask] & flag;
    679 
    680   /* Clear only those bits which user wants... */
    681   gki_cb.com.OSWaitEvt[rtask] &= ~flag;
    682 
    683   /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when
    684    * cond is met */
    685   pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
    686   return (evt);
    687 }
    688 
    689 /*******************************************************************************
    690 **
    691 ** Function         GKI_delay
    692 **
    693 ** Description      This function is called by tasks to sleep unconditionally
    694 **                  for a specified amount of time. The duration is in
    695 **                  milliseconds
    696 **
    697 ** Parameters:      timeout -    (input) the duration in milliseconds
    698 **
    699 ** Returns          void
    700 **
    701 *******************************************************************************/
    702 
    703 void GKI_delay(uint32_t timeout) {
    704   uint8_t rtask = GKI_get_taskid();
    705   struct timespec delay;
    706   int err;
    707 
    708   DLOG_IF(INFO, nfc_debug_enabled)
    709       << StringPrintf("GKI_delay %d %d", rtask, timeout);
    710 
    711   delay.tv_sec = timeout / 1000;
    712   delay.tv_nsec = 1000 * 1000 * (timeout % 1000);
    713 
    714   /* [u]sleep can't be used because it uses SIGALRM */
    715 
    716   do {
    717     err = nanosleep(&delay, &delay);
    718   } while (err < 0 && errno == EINTR);
    719 
    720   /* Check if task was killed while sleeping */
    721   /* NOTE
    722   **      if you do not implement task killing, you do not
    723   **      need this check.
    724   */
    725   if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD) {
    726   }
    727 
    728   DLOG_IF(INFO, nfc_debug_enabled)
    729       << StringPrintf("GKI_delay %d %d done", rtask, timeout);
    730   return;
    731 }
    732 
    733 /*******************************************************************************
    734 **
    735 ** Function         GKI_send_event
    736 **
    737 ** Description      This function is called by tasks to send events to other
    738 **                  tasks. Tasks can also send events to themselves.
    739 **
    740 ** Parameters:      task_id -  (input) The id of the task to which the event has
    741 **                                     to be sent
    742 **                  event   -  (input) The event that has to be sent
    743 **
    744 **
    745 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
    746 **
    747 *******************************************************************************/
    748 uint8_t GKI_send_event(uint8_t task_id, uint16_t event) {
    749   /* use efficient coding to avoid pipeline stalls */
    750   if (task_id < GKI_MAX_TASKS) {
    751     /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
    752     pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
    753 
    754     /* Set the event bit */
    755     gki_cb.com.OSWaitEvt[task_id] |= event;
    756 
    757     pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
    758 
    759     pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
    760 
    761     return (GKI_SUCCESS);
    762   }
    763   return (GKI_FAILURE);
    764 }
    765 
    766 /*******************************************************************************
    767 **
    768 ** Function         GKI_isend_event
    769 **
    770 ** Description      This function is called from ISRs to send events to other
    771 **                  tasks. The only difference between this function and
    772 **                  GKI_send_event is that this function assumes interrupts are
    773 **                  already disabled.
    774 **
    775 ** Parameters:      task_id -  (input) The destination task Id for the event.
    776 **                  event   -  (input) The event flag
    777 **
    778 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
    779 **
    780 ** NOTE             This function is NOT called by the Widcomm stack and
    781 **                  profiles. If you want to use it in your own implementation,
    782 **                  put your code here, otherwise you can delete the entire
    783 **                  body of the function.
    784 **
    785 *******************************************************************************/
    786 uint8_t GKI_isend_event(uint8_t task_id, uint16_t event) {
    787   DLOG_IF(INFO, nfc_debug_enabled)
    788       << StringPrintf("GKI_isend_event %d %x", task_id, event);
    789   DLOG_IF(INFO, nfc_debug_enabled)
    790       << StringPrintf("GKI_isend_event %d %x done", task_id, event);
    791   return GKI_send_event(task_id, event);
    792 }
    793 
    794 /*******************************************************************************
    795 **
    796 ** Function         GKI_get_taskid
    797 **
    798 ** Description      This function gets the currently running task ID.
    799 **
    800 ** Returns          task ID
    801 **
    802 ** NOTE             The Widcomm upper stack and profiles may run as a single
    803 **                  task. If you only have one GKI task, then you can hard-code
    804 **                  this function to return a '1'. Otherwise, you should have
    805 **                  some OS-specific method to determine the current task.
    806 **
    807 *******************************************************************************/
    808 uint8_t GKI_get_taskid(void) {
    809   int i;
    810   pthread_t thread_id = pthread_self();
    811   for (i = 0; i < GKI_MAX_TASKS; i++) {
    812     if (gki_cb.os.thread_id[i] == thread_id) {
    813       return (i);
    814     }
    815   }
    816   return (-1);
    817 }
    818 
    819 /*******************************************************************************
    820 **
    821 ** Function         GKI_map_taskname
    822 **
    823 ** Description      This function gets the task name of the taskid passed as
    824 **                  arg. If GKI_MAX_TASKS is passed as arg the currently running
    825 **                  task name is returned
    826 **
    827 ** Parameters:      task_id -  (input) The id of the task whose name is being
    828 **                  sought. GKI_MAX_TASKS is passed to get the name of the
    829 **                  currently running task.
    830 **
    831 ** Returns          pointer to task name
    832 **
    833 ** NOTE             this function needs no customization
    834 **
    835 *******************************************************************************/
    836 int8_t* GKI_map_taskname(uint8_t task_id) {
    837   DLOG_IF(INFO, nfc_debug_enabled)
    838       << StringPrintf("GKI_map_taskname %d", task_id);
    839 
    840   if (task_id < GKI_MAX_TASKS) {
    841     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    842         "GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
    843     return (gki_cb.com.OSTName[task_id]);
    844   } else if (task_id == GKI_MAX_TASKS) {
    845     return (gki_cb.com.OSTName[GKI_get_taskid()]);
    846   } else {
    847     return (int8_t*)"BAD";
    848   }
    849 }
    850 
    851 /*******************************************************************************
    852 **
    853 ** Function         GKI_enable
    854 **
    855 ** Description      This function enables interrupts.
    856 **
    857 ** Returns          void
    858 **
    859 *******************************************************************************/
    860 void GKI_enable(void) {
    861   pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
    862   /* 	pthread_mutex_xx is nesting save, no need for this: already_disabled =
    863    * 0; */
    864   return;
    865 }
    866 
    867 /*******************************************************************************
    868 **
    869 ** Function         GKI_disable
    870 **
    871 ** Description      This function disables interrupts.
    872 **
    873 ** Returns          void
    874 **
    875 *******************************************************************************/
    876 
    877 void GKI_disable(void) {
    878   // DLOG_IF(INFO, nfc_debug_enabled) <<
    879   // StringPrintf("GKI_disable");
    880 
    881   /*	pthread_mutex_xx is nesting save, no need for this: if
    882      (!already_disabled) {
    883       already_disabled = 1; */
    884   pthread_mutex_lock(&gki_cb.os.GKI_mutex);
    885   /*  } */
    886   // DLOG_IF(INFO, nfc_debug_enabled) <<
    887   // StringPrintf("Leaving GKI_disable");
    888   return;
    889 }
    890 
    891 /*******************************************************************************
    892 **
    893 ** Function         GKI_exception
    894 **
    895 ** Description      This function throws an exception.
    896 **                  This is normally only called for a nonrecoverable error.
    897 **
    898 ** Parameters:      code    -  (input) The code for the error
    899 **                  msg     -  (input) The message that has to be logged
    900 **
    901 ** Returns          void
    902 **
    903 *******************************************************************************/
    904 
    905 void GKI_exception(uint16_t code, std::string msg) {
    906   uint8_t task_id;
    907 
    908   LOG(ERROR) << StringPrintf("Task State Table");
    909 
    910   for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) {
    911     LOG(ERROR) << StringPrintf("TASK ID [%d] task name [%s] state [%d]",
    912                                task_id, gki_cb.com.OSTName[task_id],
    913                                gki_cb.com.OSRdyTbl[task_id]);
    914   }
    915 
    916   LOG(ERROR) << StringPrintf("%d %s", code, msg.c_str());
    917   LOG(ERROR) << StringPrintf(
    918       "********************************************************************");
    919   LOG(ERROR) << StringPrintf("* %d %s", code, msg.c_str());
    920   LOG(ERROR) << StringPrintf(
    921       "********************************************************************");
    922 
    923   LOG(ERROR) << StringPrintf("%d %s done", code, msg.c_str());
    924 
    925   return;
    926 }
    927 
    928 /*******************************************************************************
    929 **
    930 ** Function         GKI_get_time_stamp
    931 **
    932 ** Description      This function formats the time into a user area
    933 **
    934 ** Parameters:      tbuf -  (output) the address to the memory containing the
    935 **                  formatted time
    936 **
    937 ** Returns          the address of the user area containing the formatted time
    938 **                  The format of the time is ????
    939 **
    940 ** NOTE             This function is only called by OBEX.
    941 **
    942 *******************************************************************************/
    943 int8_t* GKI_get_time_stamp(int8_t* tbuf) {
    944   uint32_t ms_time;
    945   uint32_t s_time;
    946   uint32_t m_time;
    947   uint32_t h_time;
    948   int8_t* p_out = tbuf;
    949 
    950   gki_cb.com.OSTicks = times(0);
    951   ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
    952   s_time = ms_time / 100; /* 100 Ticks per second */
    953   m_time = s_time / 60;
    954   h_time = m_time / 60;
    955 
    956   ms_time -= s_time * 100;
    957   s_time -= m_time * 60;
    958   m_time -= h_time * 60;
    959 
    960   *p_out++ = (int8_t)((h_time / 10) + '0');
    961   *p_out++ = (int8_t)((h_time % 10) + '0');
    962   *p_out++ = ':';
    963   *p_out++ = (int8_t)((m_time / 10) + '0');
    964   *p_out++ = (int8_t)((m_time % 10) + '0');
    965   *p_out++ = ':';
    966   *p_out++ = (int8_t)((s_time / 10) + '0');
    967   *p_out++ = (int8_t)((s_time % 10) + '0');
    968   *p_out++ = ':';
    969   *p_out++ = (int8_t)((ms_time / 10) + '0');
    970   *p_out++ = (int8_t)((ms_time % 10) + '0');
    971   *p_out++ = ':';
    972   *p_out = 0;
    973 
    974   return (tbuf);
    975 }
    976 
    977 /*******************************************************************************
    978 **
    979 ** Function         GKI_register_mempool
    980 **
    981 ** Description      This function registers a specific memory pool.
    982 **
    983 ** Parameters:      p_mem -  (input) pointer to the memory pool
    984 **
    985 ** Returns          void
    986 **
    987 ** NOTE             This function is NOT called by the Widcomm stack and
    988 **                  profiles. If your OS has different memory pools, you
    989 **                  can tell GKI the pool to use by calling this function.
    990 **
    991 *******************************************************************************/
    992 void GKI_register_mempool(void* p_mem) {
    993   gki_cb.com.p_user_mempool = p_mem;
    994 
    995   return;
    996 }
    997 
    998 /*******************************************************************************
    999 **
   1000 ** Function         GKI_os_malloc
   1001 **
   1002 ** Description      This function allocates memory
   1003 **
   1004 ** Parameters:      size -  (input) The size of the memory that has to be
   1005 **                  allocated
   1006 **
   1007 ** Returns          the address of the memory allocated, or NULL if failed
   1008 **
   1009 ** NOTE             This function is called by the Widcomm stack when
   1010 **                  dynamic memory allocation is used.
   1011 **
   1012 *******************************************************************************/
   1013 void* GKI_os_malloc(uint32_t size) { return (malloc(size)); }
   1014 
   1015 /*******************************************************************************
   1016 **
   1017 ** Function         GKI_os_free
   1018 **
   1019 ** Description      This function frees memory
   1020 **
   1021 ** Parameters:      size -  (input) The address of the memory that has to be
   1022 **                  freed
   1023 **
   1024 ** Returns          void
   1025 **
   1026 ** NOTE             This function is NOT called by the Widcomm stack and
   1027 **                  profiles. It is only called from within GKI if dynamic
   1028 **
   1029 *******************************************************************************/
   1030 void GKI_os_free(void* p_mem) {
   1031   if (p_mem != NULL) free(p_mem);
   1032   return;
   1033 }
   1034 
   1035 /*******************************************************************************
   1036 **
   1037 ** Function         GKI_suspend_task()
   1038 **
   1039 ** Description      This function suspends the task specified in the argument.
   1040 **
   1041 ** Parameters:      task_id  - (input) the id of the task that has to suspended
   1042 **
   1043 ** Returns          GKI_SUCCESS if all OK, else GKI_FAILURE
   1044 **
   1045 ** NOTE             This function is NOT called by the Widcomm stack and
   1046 **                  profiles. If you want to implement task suspension
   1047 **                  capability, put specific code here.
   1048 **
   1049 *******************************************************************************/
   1050 uint8_t GKI_suspend_task(uint8_t task_id) {
   1051   DLOG_IF(INFO, nfc_debug_enabled)
   1052       << StringPrintf("GKI_suspend_task %d - NOT implemented", task_id);
   1053 
   1054   DLOG_IF(INFO, nfc_debug_enabled)
   1055       << StringPrintf("GKI_suspend_task %d done", task_id);
   1056 
   1057   return (GKI_SUCCESS);
   1058 }
   1059 
   1060 /*******************************************************************************
   1061 **
   1062 ** Function         GKI_resume_task()
   1063 **
   1064 ** Description      This function resumes the task specified in the argument.
   1065 **
   1066 ** Parameters:      task_id  - (input) the id of the task that has to resumed
   1067 **
   1068 ** Returns          GKI_SUCCESS if all OK
   1069 **
   1070 ** NOTE             This function is NOT called by the Widcomm stack and
   1071 **                  profiles. If you want to implement task suspension
   1072 **                  capability, put specific code here.
   1073 **
   1074 *******************************************************************************/
   1075 uint8_t GKI_resume_task(uint8_t task_id) {
   1076   DLOG_IF(INFO, nfc_debug_enabled)
   1077       << StringPrintf("GKI_resume_task %d - NOT implemented", task_id);
   1078 
   1079   DLOG_IF(INFO, nfc_debug_enabled)
   1080       << StringPrintf("GKI_resume_task %d done", task_id);
   1081 
   1082   return (GKI_SUCCESS);
   1083 }
   1084 
   1085 /*******************************************************************************
   1086 **
   1087 ** Function         GKI_exit_task
   1088 **
   1089 ** Description      This function is called to stop a GKI task.
   1090 **
   1091 ** Parameters:      task_id  - (input) the id of the task that has to be stopped
   1092 **
   1093 ** Returns          void
   1094 **
   1095 ** NOTE             This function is NOT called by the Widcomm stack and
   1096 **                  profiles. If you want to use it in your own implementation,
   1097 **                  put specific code here to kill a task.
   1098 **
   1099 *******************************************************************************/
   1100 void GKI_exit_task(uint8_t task_id) {
   1101   if (task_id >= GKI_MAX_TASKS) {
   1102     return;
   1103   }
   1104   GKI_disable();
   1105   gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
   1106 
   1107   /* Destroy mutex and condition variable objects */
   1108   pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
   1109   pthread_cond_destroy(&gki_cb.os.thread_evt_cond[task_id]);
   1110   pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
   1111   pthread_cond_destroy(&gki_cb.os.thread_timeout_cond[task_id]);
   1112 
   1113   GKI_enable();
   1114 
   1115   // GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
   1116 
   1117   DLOG_IF(INFO, nfc_debug_enabled)
   1118       << StringPrintf("GKI_exit_task %d done", task_id);
   1119   return;
   1120 }
   1121 
   1122 /*******************************************************************************
   1123 **
   1124 ** Function         GKI_sched_lock
   1125 **
   1126 ** Description      This function is called by tasks to disable scheduler
   1127 **                  task context switching.
   1128 **
   1129 ** Returns          void
   1130 **
   1131 ** NOTE             This function is NOT called by the Widcomm stack and
   1132 **                  profiles. If you want to use it in your own implementation,
   1133 **                  put code here to tell the OS to disable context switching.
   1134 **
   1135 *******************************************************************************/
   1136 void GKI_sched_lock(void) {
   1137   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("GKI_sched_lock");
   1138   GKI_disable();
   1139   return;
   1140 }
   1141 
   1142 /*******************************************************************************
   1143 **
   1144 ** Function         GKI_sched_unlock
   1145 **
   1146 ** Description      This function is called by tasks to enable scheduler
   1147 **                  switching.
   1148 **
   1149 ** Returns          void
   1150 **
   1151 ** NOTE             This function is NOT called by the Widcomm stack and
   1152 **                  profiles. If you want to use it in your own implementation,
   1153 **                  put code here to tell the OS to re-enable context switching.
   1154 **
   1155 *******************************************************************************/
   1156 void GKI_sched_unlock(void) {
   1157   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("GKI_sched_unlock");
   1158   GKI_enable();
   1159 }
   1160 
   1161 /*******************************************************************************
   1162 **
   1163 ** Function         GKI_shiftdown
   1164 **
   1165 ** Description      shift memory down (to make space to insert a record)
   1166 **
   1167 *******************************************************************************/
   1168 void GKI_shiftdown(uint8_t* p_mem, uint32_t len, uint32_t shift_amount) {
   1169   uint8_t* ps = p_mem + len - 1;
   1170   uint8_t* pd = ps + shift_amount;
   1171   uint32_t xx;
   1172 
   1173   for (xx = 0; xx < len; xx++) *pd-- = *ps--;
   1174 }
   1175 
   1176 /*******************************************************************************
   1177 **
   1178 ** Function         GKI_shiftup
   1179 **
   1180 ** Description      shift memory up (to delete a record)
   1181 **
   1182 *******************************************************************************/
   1183 void GKI_shiftup(uint8_t* p_dest, uint8_t* p_src, uint32_t len) {
   1184   uint8_t* ps = p_src;
   1185   uint8_t* pd = p_dest;
   1186   uint32_t xx;
   1187 
   1188   for (xx = 0; xx < len; xx++) *pd++ = *ps++;
   1189 }
   1190