/** ----------------------------------------------------------------------
 *
 * Copyright (C) 2016 ST Microelectronics S.A.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 ----------------------------------------------------------------------*/
#define LOG_TAG "NfcHal"


#include <hardware/nfc.h>
#include "halcore_private.h"
#include "android_logmsg.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>

extern int I2cWriteCmd(const uint8_t* x, size_t len);
extern void DispHal(const char* title, const void* data, size_t length);

extern uint32_t ScrProtocolTraceFlag;  // = SCR_PROTO_TRACE_ALL;

// HAL WRAPPER
static void HalStopTimer(HalInstance* inst);

typedef struct {
    struct nfc_nci_device nci_device;  // nci_device must be first struct member
    // below declarations are private variables within HAL
    nfc_stack_callback_t* p_cback;
    nfc_stack_data_callback_t* p_data_cback;
    HALHANDLE hHAL;
} st21nfc_dev_t;  // beware, is a duplication of structure in nfc_nci_st21nfc.c

/**************************************************************************************************
 *
 *                                      Private API Declaration
 *
 **************************************************************************************************/

static void* HalWorkerThread(void* arg);
static inline int sem_wait_nointr(sem_t *sem);

static void HalOnNewUpstreamFrame(HalInstance* inst, const uint8_t* data,
                                  size_t length);
static void HalTriggerNextDsPacket(HalInstance* inst);
static bool HalEnqueueThreadMessage(HalInstance* inst, ThreadMesssage* msg);
static bool HalDequeueThreadMessage(HalInstance* inst, ThreadMesssage* msg);
static HalBuffer* HalAllocBuffer(HalInstance* inst);
static HalBuffer* HalFreeBuffer(HalInstance* inst, HalBuffer* b);
static uint32_t HalSemWait(sem_t* pSemaphore, uint32_t timeout);

/**************************************************************************************************
 *
 *                                      Public API Entry-Points
 *
 **************************************************************************************************/

/**
 * Callback of HAL Core protocol layer.
 * Invoked by HAL worker thread according to if message is received from NCI
 * stack or posted by
 * I2C worker thread.
 * <p>@param context NFC callbacks for control/data
 * @param event Next HAL state machine action (send msg to I2C layer or report
 * data/control/error
 * to NFC task)
 * @param length Configure if debug and trace allowed, trace level
 */
void HalCoreCallback(void* context, uint32_t event, const void* d,
                     size_t length)
{
    const uint8_t* data = (const uint8_t*)d;
    uint8_t cmd = 'W';

    st21nfc_dev_t* dev = (st21nfc_dev_t*)context;

    switch (event) {
        case HAL_EVENT_DSWRITE:
            STLOG_HAL_V("!! got event HAL_EVENT_DSWRITE for %zu bytes\n", length);
            DispHal("TX DATA", (data), length);

            // Send write command to IO thread
            cmd = 'W';
            I2cWriteCmd(&cmd, sizeof(cmd));
            I2cWriteCmd((const uint8_t*)&length, sizeof(length));
            I2cWriteCmd(data, length);
            break;

        case HAL_EVENT_DATAIND:
            STLOG_HAL_V("!! got event HAL_EVENT_DATAIND for %zu bytes\n", length);

            if ((length >= 3) && (data[2] != (length - 3))) {
                STLOG_HAL_W("length is illogical. Header length is %d, packet length %zu\n",
                      data[2], length);
            }

            dev->p_data_cback(length, (uint8_t*)data);
            break;

        case HAL_EVENT_ERROR:
            STLOG_HAL_E("!! got event HAL_EVENT_ERROR\n");
            DispHal("Received unexpected HAL message !!!", data, length);
            break;

        case HAL_EVENT_LINKLOST:
            STLOG_HAL_E("!! got event HAL_EVENT_LINKLOST or HAL_EVENT_ERROR\n");

            dev->p_cback(HAL_NFC_ERROR_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);

            // Write terminate command
            cmd = 'X';
            I2cWriteCmd(&cmd, sizeof(cmd));
            break;

        case HAL_EVENT_TIMER_TIMEOUT:
            STLOG_HAL_D("!! got event HAL_EVENT_TIMER_TIMEOUT \n");
            dev->p_cback(HAL_WRAPPER_TIMEOUT_EVT, HAL_NFC_STATUS_OK);

            //            dev->p_data_cback(0, NULL);
            break;
    }
}

/**
 * Connection to the HAL Core layer.
 * Set-up HAL context and create HAL worker thread.
 * <p>@param context NFC NCI device context, NFC callbacks for control/data, HAL
 * handle
 * @param callback HAL callback function pointer
 * @param flags Configure if debug and trace allowed, trace level
 */
HALHANDLE HalCreate(void* context, HAL_CALLBACK callback, uint32_t flags)
{
    halTraceMask = true;

    if (flags & HAL_FLAG_NO_DEBUG) {
        halTraceMask = false;
    }

    STLOG_HAL_V("HalCreate enter\n");

    HalInstance* inst = calloc(1, sizeof(HalInstance));

    if (!inst) {
        STLOG_HAL_E("!out of memory\n");
        return NULL;
    }

    // We need a semaphore to wakeup our protocol thread
    if (0 != sem_init(&inst->semaphore, 0, 0)) {
        STLOG_HAL_E("!sem_init failed\n");
        free(inst);
        return NULL;
    }

    // We need a semaphore to manage buffers
    if (0 != sem_init(&inst->bufferResourceSem, 0, NUM_BUFFERS)) {
        STLOG_HAL_E("!sem_init failed\n");
        sem_destroy(&inst->semaphore);
        free(inst);
        return NULL;
    }

    // We need a semaphore to block upstream data indications
    if (0 != sem_init(&inst->upstreamBlock, 0, 0)) {
        STLOG_HAL_E("!sem_init failed\n");
        sem_destroy(&inst->semaphore);
        sem_destroy(&inst->bufferResourceSem);
        free(inst);
        return NULL;
    }

    // Initialize remaining data-members
    inst->context = context;
    inst->callback = callback;
    inst->flags = flags;
    inst->freeBufferList = 0;
    inst->pendingNciList = 0;
    inst->nciBuffer = 0;
    inst->ringReadPos = 0;
    inst->ringWritePos = 0;
    inst->timeout = HAL_SLEEP_TIMER_DURATION;

    inst->bufferData = calloc(NUM_BUFFERS, sizeof(HalBuffer));
    if (!inst->bufferData) {
        STLOG_HAL_E("!failed to allocate memory\n");
        sem_destroy(&inst->semaphore);
        sem_destroy(&inst->bufferResourceSem);
        sem_destroy(&inst->upstreamBlock);
        free(inst);
        return NULL;
    }

    // Concatenate the buffers into a linked list for easy access
    size_t i;
    for (i = 0; i < NUM_BUFFERS; i++) {
        HalBuffer* b = &inst->bufferData[i];
        b->next = inst->freeBufferList;
        inst->freeBufferList = b;
    }

    if (0 != pthread_mutex_init(&inst->hMutex, 0))
      {
        STLOG_HAL_E("!failed to initialize Mutex \n");
        sem_destroy(&inst->semaphore);
        sem_destroy(&inst->bufferResourceSem);
        sem_destroy(&inst->upstreamBlock);
        free(inst->bufferData);
        free(inst);
        return NULL;
      }

    // Spawn the thread
    if (0 != pthread_create(&inst->thread, NULL, HalWorkerThread, inst)) {
        STLOG_HAL_E("!failed to spawn workerthread \n");
        sem_destroy(&inst->semaphore);
        sem_destroy(&inst->bufferResourceSem);
        sem_destroy(&inst->upstreamBlock);
        pthread_mutex_destroy(&inst->hMutex);
        free(inst->bufferData);
        free(inst);
        return NULL;
    }

    STLOG_HAL_V("HalCreate exit\n");
    return (HALHANDLE)inst;
}

/**
 * Disconnection of the HAL protocol layer.
 * Send message to stop the HAL worker thread and wait for it to finish. Free
 * resources.
 * @param hHAL HAL handle
 */
void HalDestroy(HALHANDLE hHAL)
{
    HalInstance* inst = (HalInstance*)hHAL;
    // Tell the thread that we want to finish
    ThreadMesssage msg;
    msg.command = MSG_EXIT_REQUEST;
    msg.payload = 0;
    msg.length = 0;

    HalEnqueueThreadMessage(inst, &msg);

    // Wait for thread to finish
    pthread_join(inst->thread, NULL);

    // Cleanup and exit
    sem_destroy(&inst->semaphore);
    sem_destroy(&inst->upstreamBlock);
    sem_destroy(&inst->bufferResourceSem);
    pthread_mutex_destroy(&inst->hMutex);

    // Free resources
    free(inst->bufferData);
    free(inst);

    STLOG_HAL_V("HalDestroy done\n");
}

/**
 * Send an NCI message downstream to HAL protocol layer (DH->NFCC transfer).
 * Block if more than NUM_BUFFERS (10) transfers are outstanding, otherwise will return immediately.
 * @param hHAL HAL handle
 * @param data Data message
 * @param size Message size
 */ bool HalSendDownstream(HALHANDLE hHAL, const uint8_t* data, size_t size)
{
    // Send an NCI frame downstream. will
    HalInstance* inst = (HalInstance*)hHAL;

    if ((size <= MAX_BUFFER_SIZE) && (size > 0)) {
        ThreadMesssage msg;
        HalBuffer* b = HalAllocBuffer(inst);

        if (!b) {
            // Should never be reachable
            return false;
        }

        memcpy(b->data, data, size);
        b->length = size;

        msg.command = MSG_TX_DATA;
        msg.payload = 0;
        msg.length = 0;
        msg.buffer = b;

        return HalEnqueueThreadMessage(inst, &msg);

    } else {
        STLOG_HAL_E("HalSendDownstream size to large %zu instead of %d\n", size,
              MAX_BUFFER_SIZE);
        return false;
    }
}

// HAL WRAPPER
/**
 * Send an NCI message downstream to HAL protocol layer (DH->NFCC transfer).
 * Block if more than NUM_BUFFERS (10) transfers are outstanding, otherwise will return immediately.
 * @param hHAL HAL handle
 * @param data Data message
 * @param size Message size
 */ bool HalSendDownstreamTimer(HALHANDLE hHAL, const uint8_t* data,
                                size_t size, uint8_t duration)
{
    // Send an NCI frame downstream. will
    HalInstance* inst = (HalInstance*)hHAL;

    if ((size <= MAX_BUFFER_SIZE) && (size > 0)) {
        ThreadMesssage msg;
        HalBuffer* b = HalAllocBuffer(inst);

        if (!b) {
            // Should never be reachable
            return false;
        }

        memcpy(b->data, data, size);
        b->length = size;

        msg.command = MSG_TX_DATA_TIMER_START;
        msg.payload = 0;
        msg.length = duration;
        msg.buffer = b;

        return HalEnqueueThreadMessage(inst, &msg);

    } else {
        STLOG_HAL_E("HalSendDownstreamTimer size to large %zu instead of %d\n", size,
              MAX_BUFFER_SIZE);
        return false;
    }
}

/**
 * Send an NCI message downstream to HAL protocol layer (DH->NFCC transfer).
 * Block if more than NUM_BUFFERS (10) transfers are outstanding, otherwise will
 * return immediately.
 * @param hHAL HAL handle
 * @param data Data message
 * @param size Message size
 */
bool HalSendDownstreamStopTimer(HALHANDLE hHAL)
{
    // Send an NCI frame downstream. will
    HalInstance* inst = (HalInstance*)hHAL;

    HalStopTimer(inst);
    return 1;


}

/**
 * Send an NCI message upstream to NFC NCI layer (NFCC->DH transfer).
 * @param hHAL HAL handle
 * @param data Data message
 * @param size Message size
 */ bool HalSendUpstream(HALHANDLE hHAL, const uint8_t* data, size_t size)
{
    HalInstance* inst = (HalInstance*)hHAL;
    if ((size <= MAX_BUFFER_SIZE) && (size > 0)) {
        ThreadMesssage msg;
        msg.command = MSG_RX_DATA;
        msg.payload = data;
        msg.length = size;

        if (HalEnqueueThreadMessage(inst, &msg)) {
            // Block until the protocol has taken a copy of the data
            sem_wait_nointr(&inst->upstreamBlock);
            return true;
        }
        return false;
    } else {
        STLOG_HAL_E("HalSendUpstream size to large %zu instead of %d\n", size,
              MAX_BUFFER_SIZE);
        return false;
    }
}

/**************************************************************************************************
 *
 *                                      Private API Definition
 *
 **************************************************************************************************/
/*
 * Get current time stamp
 */
struct timespec HalGetTimestamp(void)
{
    struct timespec tm;
    clock_gettime(CLOCK_REALTIME, &tm);
    return tm;
}

int HalTimeDiffInMs(struct timespec start, struct timespec end)
{
    struct timespec temp;
    if ((end.tv_nsec - start.tv_nsec) < 0) {
        temp.tv_sec = end.tv_sec - start.tv_sec - 1;
        temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec - start.tv_sec;
        temp.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return (temp.tv_nsec / 1000000) + (temp.tv_sec * 1000);
}


/**
 * Determine the next shortest sleep to fulfill the pending timer requirements.
 * @param inst HAL instance
 * @param now timespec structure for time definition
 */
static uint32_t HalCalcSemWaitingTime(HalInstance* inst, struct timespec* now)
{
    // Default to infinite wait time
    uint32_t result = OS_SYNC_INFINITE;

    if (inst->timer.active) {
        int delta =
            inst->timer.duration - HalTimeDiffInMs(inst->timer.startTime, *now);

        if (delta < 0) {
            // If we have a timer that has already expired, pick a zero wait time
            result = 0;

        } else if ((uint32_t)delta < result) {
            // Smaller time difference? If so take it
            result = delta;
        }
    }

    if (result != OS_SYNC_INFINITE) {
        // Add one millisecond on top of that, so the waiting semaphore will time
        // out just a moment
        // after the timer should expire
        result += 1;
    }

    return result;
}

/**************************************************************************************************
 *
 *                                     Timer Management
 *
 **************************************************************************************************/

static void HalStopTimer(HalInstance* inst)
{
    inst->timer.active = false;
    STLOG_HAL_D("HalStopTimer \n");
}

static void HalStartTimer(HalInstance* inst, uint32_t duration)
{
    STLOG_HAL_D("HalStartTimer \n");
    inst->timer.startTime = HalGetTimestamp();
    inst->timer.active = true;
    inst->timer.duration = duration;
}

/**************************************************************************************************
 *
 *                                     Thread Message Queue
 *
 **************************************************************************************************/

/**
 * Write message pointer to small ring buffer for queuing HAL messages.
 * @param inst HAL instance
 * @param msg Message to send
 * @return true if message properly copied in ring buffer
 */
static bool HalEnqueueThreadMessage(HalInstance* inst, ThreadMesssage* msg)
{
    // Put a message to the queue
    int nextWriteSlot;
    bool result = true;

    pthread_mutex_lock(&inst->hMutex);

    nextWriteSlot = inst->ringWritePos + 1;

    if (nextWriteSlot == HAL_QUEUE_MAX) {
        nextWriteSlot = 0;
    }

    // Check that we don't overflow the queue entries
    if (nextWriteSlot == inst->ringReadPos) {
        STLOG_HAL_E("HAL thread message ring: RNR (implement me!!)");
        result = false;
    }

    if (result) {
        // inst->ring[nextWriteSlot] = *msg;
        memcpy(&(inst->ring[nextWriteSlot]), msg, sizeof(ThreadMesssage));
        inst->ringWritePos = nextWriteSlot;
    }

    pthread_mutex_unlock(&inst->hMutex);

    if (result) {
        sem_post(&inst->semaphore);
    }

    return result;
}

/**
 * Remove message pointer from stored ring buffer.
 * @param inst HAL instance
 * @param msg Message received
 * @return true if there is a new message to pull, false otherwise.
 */
static bool HalDequeueThreadMessage(HalInstance* inst, ThreadMesssage* msg)
{
    int nextCmdIndex;
    bool result = true;
    // New data available
    pthread_mutex_lock(&inst->hMutex);

    // Get new timer read index
    nextCmdIndex = inst->ringReadPos + 1;

    if (nextCmdIndex == HAL_QUEUE_MAX) {
        nextCmdIndex = 0;
    }
     //check if ring buffer is empty
    if (inst->ringReadPos == inst->ringWritePos)
      {
        STLOG_HAL_E("HAL thread message ring: already read last valid data");
        result = false;
      }

    // Get new element from ringbuffer
    if (result) {
    memcpy(msg, &(inst->ring[nextCmdIndex]), sizeof(ThreadMesssage));
    inst->ringReadPos = nextCmdIndex;
    }

    pthread_mutex_unlock(&inst->hMutex);

    return result;
}

/**************************************************************************************************
 *
 *                                     Buffer/Memory Management
 *
 **************************************************************************************************/

/**
 * Allocate buffer from pre-allocated pool.
 * @param inst HAL instance
 * @return Pointer to allocated HAL buffer
 */
static HalBuffer* HalAllocBuffer(HalInstance* inst)
{
    HalBuffer* b;

    // Wait until we have a buffer resource
    sem_wait_nointr(&inst->bufferResourceSem);

    pthread_mutex_lock(&inst->hMutex);

    b = inst->freeBufferList;
    if (b) {
        inst->freeBufferList = b->next;
        b->next = 0;
    }

    pthread_mutex_unlock(&inst->hMutex);

    if (!b) {
        STLOG_HAL_E(
            "! unable to allocate buffer resource."
            "check bufferResourceSem\n");
    }

    return b;
}

/**
 * Return buffer to pool.
 * @param inst HAL instance
 * @param b Pointer of HAL buffer to free
 * @return Pointer of freed HAL buffer
 */
static HalBuffer* HalFreeBuffer(HalInstance* inst, HalBuffer* b)
{
    pthread_mutex_lock(&inst->hMutex);

    b->next = inst->freeBufferList;
    inst->freeBufferList = b;

    pthread_mutex_unlock(&inst->hMutex);

    // Unblock treads waiting for a buffer
    sem_post(&inst->bufferResourceSem);

    return b;
}

/**************************************************************************************************
 *
 *                                     State Machine
 *
 **************************************************************************************************/

/**
 * Event handler for HAL message
 * @param inst HAL instance
 * @param e HAL event
 */
static void Hal_event_handler(HalInstance* inst, HalEvent e)
{
    switch (e) {
        case EVT_RX_DATA: {
            // New data packet arrived
            const uint8_t* nciData;
            size_t nciLength;

            // Extract raw NCI data from frame
            nciData = inst->lastUsFrame;
            nciLength = inst->lastUsFrameSize;

            // Pass received raw NCI data to stack
            inst->callback(inst->context, HAL_EVENT_DATAIND, nciData, nciLength);
        }
        break;

        case EVT_TX_DATA:
            // NCI data arrived from stack
            // Send data
            inst->callback(inst->context, HAL_EVENT_DSWRITE, inst->nciBuffer->data,
                           inst->nciBuffer->length);

            // Free the buffer
            HalFreeBuffer(inst, inst->nciBuffer);
            inst->nciBuffer = 0;
            break;

        // HAL WRAPPER
        case EVT_TIMER:
            inst->callback(inst->context, HAL_EVENT_TIMER_TIMEOUT, NULL, 0);
            break;
    }
}

/**************************************************************************************************
 *
 *                                     HAL Worker Thread
 *
 **************************************************************************************************/

/**
 * HAL worker thread to serialize all actions into a single thread.
 * RX/TX/TIMER are dispatched from here.
 * @param arg HAL instance arguments
 */
static void* HalWorkerThread(void* arg)
{
    HalInstance* inst = (HalInstance*)arg;
    inst->exitRequest = false;

    STLOG_HAL_V("thread running\n");

    while (!inst->exitRequest) {
        struct timespec now = HalGetTimestamp();
        uint32_t waitResult =
            HalSemWait(&inst->semaphore, HalCalcSemWaitingTime(inst, &now));

        switch (waitResult) {
            case OS_SYNC_TIMEOUT: {
                // One or more times have expired
                STLOG_HAL_W("OS_SYNC_TIMEOUT\n");
                now = HalGetTimestamp();

                // HAL WRAPPER
                // callback to hal wrapper
                // Unblock
                sem_post(&inst->upstreamBlock);

                // Data frame
                Hal_event_handler(inst, EVT_TIMER);
            }
            break;

            case OS_SYNC_RELEASED: {
                // A message arrived
                ThreadMesssage msg;

                if (HalDequeueThreadMessage(inst, &msg)) {
                    switch (msg.command) {
                        case MSG_EXIT_REQUEST:

                            STLOG_HAL_V("received exit request from upper layer\n");
                            inst->exitRequest = true;
                            break;

                        case MSG_TX_DATA:
                            STLOG_HAL_V("received new NCI data from stack\n");

                            // Attack to end of list
                            if (!inst->pendingNciList) {
                                inst->pendingNciList = msg.buffer;
                                inst->pendingNciList->next = 0;
                            } else {
                                // Find last element of the list. b->next is zero for this
                                // element
                                HalBuffer* b;
                                for (b = inst->pendingNciList; b->next; b = b->next) {
                                };

                                // Concatenate to list
                                b->next = msg.buffer;
                                msg.buffer->next = 0;
                            }

                            // Start transmitting if we're in the correct state
                            HalTriggerNextDsPacket(inst);
                            break;

                        // HAL WRAPPER
                        case MSG_TX_DATA_TIMER_START:
                            STLOG_HAL_V("received new NCI data from stack, need timer start\n");

                            // Attack to end of list
                            if (!inst->pendingNciList) {
                                inst->pendingNciList = msg.buffer;
                                inst->pendingNciList->next = 0;
                            } else {
                                // Find last element of the list. b->next is zero for this
                                // element
                                HalBuffer* b;
                                for (b = inst->pendingNciList; b->next; b = b->next) {
                                };

                                // Concatenate to list
                                b->next = msg.buffer;
                                msg.buffer->next = 0;
                            }

                            // Start timer
                            HalStartTimer(inst, msg.length);

                            // Start transmitting if we're in the correct state
                            HalTriggerNextDsPacket(inst);
                            break;

                        case MSG_RX_DATA:
                            STLOG_HAL_D("received new data from CLF\n");
                            HalOnNewUpstreamFrame(inst, msg.payload, msg.length);
                            break;

                        default:
                            STLOG_HAL_E("!received unkown thread message?\n");
                            break;
                    }
                } else {
                    STLOG_HAL_E("!got wakeup in workerthread, but no message here? ?\n");

            }
            }
            break;

            case OS_SYNC_FAILED:

              STLOG_HAL_E(
                    "!Something went horribly wrong.. The semaphore wait function "
                    "failed\n");
                inst->exitRequest = true;
                break;
        }
    }

    STLOG_HAL_D("thread about to exit\n");
    return NULL;
}

/**************************************************************************************************
 *
 *                                     Misc. Functions
 *
 **************************************************************************************************/
/**
 *  helper to make sem_t interrupt safe
 * @param sem_t  semaphore
 * @return sem_wait return value.
 */

static inline int sem_wait_nointr(sem_t *sem) {
  while (sem_wait(sem))
    if (errno == EINTR) errno = 0;
    else return -1;
  return 0;
}

/**
 * Handle RX frames here first in HAL context.
 * @param inst HAL instance
 * @param data HAL data received from I2C worker thread
 * @param length Size of HAL data
 */
static void HalOnNewUpstreamFrame(HalInstance* inst, const uint8_t* data,
                                  size_t length)
{
    memcpy(inst->lastUsFrame, data, length);
    inst->lastUsFrameSize = length;

    // Data frame
    Hal_event_handler(inst, EVT_RX_DATA);
    // Allow the I2C thread to get the next message (if done early, it may
    // overwrite before handled)
    sem_post(&inst->upstreamBlock);
}

/**
 * Send out the next queued up buffer for TX if any.
 * @param inst HAL instance
 */
static void HalTriggerNextDsPacket(HalInstance* inst)
{
    // Check if we have something to transmit downstream
    HalBuffer* b = inst->pendingNciList;

    if (b) {
        // Get the buffer from the pending list
        inst->pendingNciList = b->next;
        inst->nciBuffer = b;

        STLOG_HAL_V("trigger transport of next NCI data downstream\n");
        // Process the new nci frame
        Hal_event_handler(inst, EVT_TX_DATA);

    } else {
        STLOG_HAL_V("no new NCI data to transmit, enter wait..\n");
    }
}

/*
 * Wait for given semaphore signaling a specific time or ever
 * param sem_t * pSemaphore
 * param uint32_t timeout
 * return uint32_t
 */
static uint32_t HalSemWait(sem_t* pSemaphore, uint32_t timeout)
{
    uint32_t result = OS_SYNC_RELEASED;
    bool gotResult = false;

    if (timeout == OS_SYNC_INFINITE) {
        while (!gotResult) {
            if (sem_wait(pSemaphore) == -1) {
                int e = errno;
                char msg[200];

                if (e == EINTR) {
                    STLOG_HAL_W(
                        "! semaphore (infin) wait interrupted by system signal. re-enter "
                        "wait");
                    continue;
                }

                strerror_r(e, msg, sizeof(msg) - 1);
                STLOG_HAL_E("! semaphore (infin) wait failed. sem=0x%p, %s", pSemaphore, msg);
                gotResult = true;
                result = OS_SYNC_FAILED;
            } else {
                gotResult = true;
            }
        };
    } else {
        struct timespec tm;
        long oneSecInNs = (int)1e9;

        clock_gettime(CLOCK_REALTIME, &tm);

        /* add timeout (can't overflow): */
        tm.tv_sec += (timeout / 1000);
        tm.tv_nsec += ((timeout % 1000) * 1000000);

        /* make sure nanoseconds are below a million */
        if (tm.tv_nsec >= oneSecInNs) {
            tm.tv_sec++;
            tm.tv_nsec -= oneSecInNs;
        }

        while (!gotResult) {
            if (sem_timedwait(pSemaphore, &tm) == -1) {
                int e = errno;

                if (e == EINTR) {
                    /* interrupted by signal? repeat sem_wait again */
                    continue;
                }

                if (e == ETIMEDOUT) {
                    result = OS_SYNC_TIMEOUT;
                    gotResult = true;
                } else {
                    result = OS_SYNC_FAILED;
                    gotResult = true;
                }
            } else {
                gotResult = true;
            }
        }
    }
    return result;
}
