summaryrefslogtreecommitdiffstats
path: root/hci/src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'hci/src/utils.c')
-rw-r--r--hci/src/utils.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/hci/src/utils.c b/hci/src/utils.c
new file mode 100644
index 0000000..9c1711b
--- /dev/null
+++ b/hci/src/utils.c
@@ -0,0 +1,315 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * This program is the proprietary software of Broadcom Corporation and/or its
+ * licensors, and may only be used, duplicated, modified or distributed
+ * pursuant to the terms and conditions of a separate, written license
+ * agreement executed between you and Broadcom (an "Authorized License").
+ * Except as set forth in an Authorized License, Broadcom grants no license
+ * (express or implied), right to use, or waiver of any kind with respect to
+ * the Software, and Broadcom expressly reserves all rights in and to the
+ * Software and all intellectual property rights therein.
+ * IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
+ * SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
+ * ALL USE OF THE SOFTWARE.
+ *
+ * Except as expressly set forth in the Authorized License,
+ *
+ * 1. This program, including its structure, sequence and organization,
+ * constitutes the valuable trade secrets of Broadcom, and you shall
+ * use all reasonable efforts to protect the confidentiality thereof,
+ * and to use this information only in connection with your use of
+ * Broadcom integrated circuit products.
+ *
+ * 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED
+ * "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
+ * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
+ * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE. BROADCOM SPECIFICALLY
+ * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
+ * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
+ * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
+ * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT
+ * OF USE OR PERFORMANCE OF THE SOFTWARE.
+ *
+ * 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR
+ * ITS LICENSORS BE LIABLE FOR
+ * (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY
+ * DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO
+ * YOUR USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM
+ * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES; OR
+ * (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ACTUALLY PAID FOR THE
+ * SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
+ * LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF
+ * ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Filename: utils.c
+ *
+ * Description: Contains helper functions
+ *
+ ******************************************************************************/
+
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+#include "bt_hci_bdroid.h"
+#include "utils.h"
+
+/******************************************************************************
+** Static variables
+******************************************************************************/
+
+static pthread_mutex_t utils_mutex;
+
+/*****************************************************************************
+** UTILS INTERFACE FUNCTIONS
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function utils_init
+**
+** Description Utils initialization
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_init (void)
+{
+ pthread_mutex_init(&utils_mutex, NULL);
+}
+
+/*******************************************************************************
+**
+** Function utils_cleanup
+**
+** Description Utils cleanup
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_cleanup (void)
+{
+}
+
+/*******************************************************************************
+**
+** Function utils_queue_init
+**
+** Description Initialize the given buffer queue
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_queue_init (BUFFER_Q *p_q)
+{
+ p_q->p_first = p_q->p_last = NULL;
+ p_q->count = 0;
+}
+
+/*******************************************************************************
+**
+** Function utils_enqueue
+**
+** Description Enqueue a buffer at the tail of the given queue
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_enqueue (BUFFER_Q *p_q, void *p_buf)
+{
+ HC_BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (HC_BUFFER_HDR_T *) ((uint8_t *) p_buf - BT_HC_BUFFER_HDR_SIZE);
+
+ pthread_mutex_lock(&utils_mutex);
+
+ if (p_q->p_last)
+ {
+ HC_BUFFER_HDR_T *p_last_hdr = \
+ (HC_BUFFER_HDR_T *)((uint8_t *)p_q->p_last - BT_HC_BUFFER_HDR_SIZE);
+
+ p_last_hdr->p_next = p_hdr;
+ }
+ else
+ p_q->p_first = p_buf;
+
+ p_q->p_last = p_buf;
+ p_q->count++;
+
+ p_hdr->p_next = NULL;
+
+ pthread_mutex_unlock(&utils_mutex);
+}
+
+/*******************************************************************************
+**
+** Function utils_dequeue
+**
+** Description Dequeues a buffer from the head of the given queue
+**
+** Returns NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *utils_dequeue (BUFFER_Q *p_q)
+{
+ HC_BUFFER_HDR_T *p_hdr;
+
+ pthread_mutex_lock(&utils_mutex);
+
+ if (!p_q || !p_q->count)
+ {
+ pthread_mutex_unlock(&utils_mutex);
+ return (NULL);
+ }
+
+ p_hdr=(HC_BUFFER_HDR_T *)((uint8_t *)p_q->p_first-BT_HC_BUFFER_HDR_SIZE);
+
+ if (p_hdr->p_next)
+ p_q->p_first = ((uint8_t *)p_hdr->p_next + BT_HC_BUFFER_HDR_SIZE);
+ else
+ {
+ p_q->p_first = NULL;
+ p_q->p_last = NULL;
+ }
+
+ p_q->count--;
+
+ p_hdr->p_next = NULL;
+
+ pthread_mutex_unlock(&utils_mutex);
+
+ return ((uint8_t *)p_hdr + BT_HC_BUFFER_HDR_SIZE);
+}
+
+/*******************************************************************************
+**
+** Function utils_getnext
+**
+** Description Return a pointer to the next buffer linked to the given
+** buffer
+**
+** Returns NULL if the given buffer does not point to any next buffer,
+** else next buffer address
+**
+*******************************************************************************/
+void *utils_getnext (void *p_buf)
+{
+ HC_BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (HC_BUFFER_HDR_T *) ((uint8_t *) p_buf - BT_HC_BUFFER_HDR_SIZE);
+
+ if (p_hdr->p_next)
+ return ((uint8_t *)p_hdr->p_next + BT_HC_BUFFER_HDR_SIZE);
+ else
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function utils_remove_from_queue
+**
+** Description Dequeue the given buffer from the middle of the given queue
+**
+** Returns NULL if the given queue is empty, else the given buffer
+**
+*******************************************************************************/
+void *utils_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
+{
+ HC_BUFFER_HDR_T *p_prev;
+ HC_BUFFER_HDR_T *p_buf_hdr;
+
+ pthread_mutex_lock(&utils_mutex);
+
+ if (p_buf == p_q->p_first)
+ {
+ pthread_mutex_unlock(&utils_mutex);
+ return (utils_dequeue (p_q));
+ }
+
+ p_buf_hdr = (HC_BUFFER_HDR_T *)((uint8_t *)p_buf - BT_HC_BUFFER_HDR_SIZE);
+ p_prev=(HC_BUFFER_HDR_T *)((uint8_t *)p_q->p_first-BT_HC_BUFFER_HDR_SIZE);
+
+ for ( ; p_prev; p_prev = p_prev->p_next)
+ {
+ /* If the previous points to this one, move the pointers around */
+ if (p_prev->p_next == p_buf_hdr)
+ {
+ p_prev->p_next = p_buf_hdr->p_next;
+
+ /* If we are removing the last guy in the queue, update p_last */
+ if (p_buf == p_q->p_last)
+ p_q->p_last = p_prev + 1;
+
+ /* One less in the queue */
+ p_q->count--;
+
+ /* The buffer is now unlinked */
+ p_buf_hdr->p_next = NULL;
+
+ pthread_mutex_unlock(&utils_mutex);
+ return (p_buf);
+ }
+ }
+
+ pthread_mutex_unlock(&utils_mutex);
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function utils_delay
+**
+** Description sleep unconditionally for timeout milliseconds
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_delay (uint32_t timeout)
+{
+ struct timespec delay;
+ int err;
+
+ delay.tv_sec = timeout / 1000;
+ delay.tv_nsec = 1000 * 1000 * (timeout%1000);
+
+ /* [u]sleep can't be used because it uses SIGALRM */
+ do {
+ err = nanosleep(&delay, &delay);
+ } while (err < 0 && errno ==EINTR);
+}
+
+/*******************************************************************************
+**
+** Function utils_lock
+**
+** Description application calls this function before entering critical
+** section
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_lock (void)
+{
+ pthread_mutex_lock(&utils_mutex);
+}
+
+/*******************************************************************************
+**
+** Function utils_unlock
+**
+** Description application calls this function when leaving critical
+** section
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_unlock (void)
+{
+ pthread_mutex_unlock(&utils_mutex);
+}
+