summaryrefslogtreecommitdiffstats
path: root/vendor
diff options
context:
space:
mode:
authorAndre Eisenbach <andre@broadcom.com>2012-02-22 13:18:21 -0800
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:11 -0700
commite448862a47c08eb23185aaed574b39264f5005fc (patch)
tree2bc6246e3091315e77224fd798ea2fe8074ef972 /vendor
parenta2ca4b83ab8bbbfd8d5f6693e927ed4b82094624 (diff)
downloadexternal_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.zip
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.gz
external_bluetooth_bluedroid-e448862a47c08eb23185aaed574b39264f5005fc.tar.bz2
Initial Bluedroid stack commit
Diffstat (limited to 'vendor')
-rw-r--r--vendor/Android.mk3
-rw-r--r--vendor/firmware/Android.mk2
-rw-r--r--vendor/firmware/LICENSE.TXT216
-rw-r--r--vendor/firmware/bcm4329/Android.mk19
-rw-r--r--vendor/firmware/bcm4329/BCM4329B1_002.002.023.0944.0956.hcdbin0 -> 18310 bytes
-rw-r--r--vendor/firmware/bcm4330/Android.mk19
-rw-r--r--vendor/firmware/bcm4330/BCM4330B1.hcdbin0 -> 53775 bytes
-rw-r--r--vendor/libvendor/Android.mk23
-rw-r--r--vendor/libvendor/include/bt_vendor_brcm.h414
-rw-r--r--vendor/libvendor/include/bt_vendor_lib.h222
-rw-r--r--vendor/libvendor/include/upio.h136
-rw-r--r--vendor/libvendor/include/userial.h245
-rw-r--r--vendor/libvendor/include/utils.h200
-rw-r--r--vendor/libvendor/include/vnd_buildcfg.h14
-rw-r--r--vendor/libvendor/src/bt_vendor_brcm.c455
-rw-r--r--vendor/libvendor/src/btsnoop.c721
-rw-r--r--vendor/libvendor/src/hardware.c1012
-rw-r--r--vendor/libvendor/src/hci_h4.c1047
-rw-r--r--vendor/libvendor/src/upio.c322
-rw-r--r--vendor/libvendor/src/userial.c745
-rw-r--r--vendor/libvendor/src/utils.c312
21 files changed, 6127 insertions, 0 deletions
diff --git a/vendor/Android.mk b/vendor/Android.mk
new file mode 100644
index 0000000..d940fa5
--- /dev/null
+++ b/vendor/Android.mk
@@ -0,0 +1,3 @@
+ifneq ($(TARGET_SIMULATOR),true)
+ include $(call all-subdir-makefiles)
+endif
diff --git a/vendor/firmware/Android.mk b/vendor/firmware/Android.mk
new file mode 100644
index 0000000..8338432
--- /dev/null
+++ b/vendor/firmware/Android.mk
@@ -0,0 +1,2 @@
+include $(call all-subdir-makefiles)
+
diff --git a/vendor/firmware/LICENSE.TXT b/vendor/firmware/LICENSE.TXT
new file mode 100644
index 0000000..a418468
--- /dev/null
+++ b/vendor/firmware/LICENSE.TXT
@@ -0,0 +1,216 @@
+SOFTWARE LICENSE AGREEMENT
+
+Unless you and Broadcom Corporation ("Broadcom") execute a separate written
+software license agreement governing use of the accompanying software, this
+software is licensed to you under the terms of this Software License
+Agreement ("Agreement").
+
+ANY USE, REPRODUCTION OR DISTRIBUTION OF THE SOFTWARE CONSTITUTES YOUR
+ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS.
+
+1.1. "Broadcom Product" means any of the proprietary integrated circuit
+product(s) sold by Broadcom with which the Software was designed to be used,
+or their successors.
+
+1.2. "Licensee" means you or if you are accepting on behalf of an entity
+then the entity and its affiliates exercising rights under, and complying
+with all of the terms of this Agreement.
+
+1.3. "Software" shall mean that software made available by Broadcom to
+Licensee in binary code form with this Agreement.
+
+2. LICENSE GRANT; OWNERSHIP
+
+2.1. License Grants. Subject to the terms and conditions of this Agreement,
+Broadcom hereby grants to Licensee a non-exclusive, non-transferable,
+royalty-free license (i) to use and integrate the Software in conjunction
+with any other software; and (ii) to reproduce and distribute the Software
+complete, unmodified and only for use with a Broadcom Product.
+
+2.2. Restriction on Modification. If and to the extent that the Software is
+designed to be compliant with any published communications standard
+(including, without limitation, DOCSIS, HomePNA, IEEE, and ITU standards),
+Licensee may not make any modifications to the Software that would cause the
+Software or the accompanying Broadcom Products to be incompatible with such
+standard.
+
+2.3. Restriction on Distribution. Licensee shall only distribute the
+Software (a) under the terms of this Agreement and a copy of this Agreement
+accompanies such distribution, and (b) agrees to defend and indemnify
+Broadcom and its licensors from and against any damages, costs, liabilities,
+settlement amounts and/or expenses (including attorneys' fees) incurred in
+connection with any claim, lawsuit or action by any third party that arises
+or results from the use or distribution of any and all Software by the
+Licensee except as contemplated herein.
+
+2.4. Proprietary Notices. Licensee shall not remove, efface or obscure any
+copyright or trademark notices from the Software. Licensee shall include
+reproductions of the Broadcom copyright notice with each copy of the
+Software, except where such Software is embedded in a manner not readily
+accessible to the end user. Licensee acknowledges that any symbols,
+trademarks, tradenames, and service marks adopted by Broadcom to identify the
+Software belong to Broadcom and that Licensee shall have no rights therein.
+
+2.5. Ownership. Broadcom shall retain all right, title and interest,
+including all intellectual property rights, in and to the Software. Licensee
+hereby covenants that it will not assert any claim that the Software created
+by or for Broadcom infringe any intellectual property right owned or
+controlled by Licensee.
+
+2.6. No Other Rights Granted; Restrictions. Apart from the license rights
+expressly set forth in this Agreement, Broadcom does not grant and Licensee
+does not receive any ownership right, title or interest nor any security
+interest or other interest in any intellectual property rights relating to
+the Software, nor in any copy of any part of the foregoing. No license is
+granted to Licensee in any human readable code of the Software (source code).
+Licensee shall not (i) use, license, sell or otherwise distribute the
+Software except as provided in this Agreement, (ii) attempt to reverse
+engineer, decompile or disassemble any portion of the Software; or (iii) use
+the Software or other material in violation of any applicable law or
+regulation, including but not limited to any regulatory agency, such as FCC,
+rules.
+
+3. NO WARRANTY OR SUPPORT
+
+3.1. No Warranty. THE SOFTWARE IS OFFERED "AS IS," AND BROADCOM GRANTS AND
+LICENSEE RECEIVES NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, BY STATUTE,
+COMMUNICATION OR CONDUCT WITH LICENSEE, OR OTHERWISE. BROADCOM SPECIFICALLY
+DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A SPECIFIC
+PURPOSE OR NONINFRINGEMENT CONCERNING THE SOFTWARE OR ANY UPGRADES TO OR
+DOCUMENTATION FOR THE SOFTWARE. WITHOUT LIMITATION OF THE ABOVE, BROADCOM
+GRANTS NO WARRANTY THAT THE SOFTWARE IS ERROR-FREE OR WILL OPERATE WITHOUT
+INTERRUPTION, AND GRANTS NO WARRANTY REGARDING ITS USE OR THE RESULTS
+THEREFROM INCLUDING, WITHOUT LIMITATION, ITS CORRECTNESS, ACCURACY OR
+RELIABILITY.
+
+3.2. No Support. Nothing in this agreement shall obligate Broadcom to
+provide any support for the Software. Broadcom may, but shall be under no
+obligation to, correct any defects in the Software and/or provide updates to
+licensees of the Software. Licensee shall make reasonable efforts to
+promptly report to Broadcom any defects it finds in the Software, as an aid
+to creating improved revisions of the Software.
+
+3.3. Dangerous Applications. The Software is not designed, intended, or
+certified for use in components of systems intended for the operation of
+weapons, weapons systems, nuclear installations, means of mass
+transportation, aviation, life-support computers or equipment (including
+resuscitation equipment and surgical implants), pollution control, hazardous
+substances management, or for any other dangerous application in which the
+failure of the Software could create a situation where personal injury or
+death may occur. Licensee understands that use of the Software in such
+applications is fully at the risk of Licensee.
+
+4. TERM AND TERMINATION
+
+4.1. Termination. This Agreement will automatically terminate if Licensee
+fails to comply with any of the terms and conditions hereof. In such event,
+Licensee must destroy all copies of the Software and all of its component
+parts.
+
+4.2. Effect Of Termination. Upon any termination of this Agreement, the
+rights and licenses granted to Licensee under this Agreement shall
+immediately terminate.
+
+4.3. Survival. The rights and obligations under this Agreement which by
+their nature should survive termination will remain in effect after
+expiration or termination of this Agreement.
+
+5. CONFIDENTIALITY
+
+5.1. Obligations. Licensee acknowledges and agrees that any documentation
+relating to the Software, and any other information (if such other
+information is identified as confidential or should be recognized as
+confidential under the circumstances) provided to Licensee by Broadcom
+hereunder (collectively, "Confidential Information") constitute the
+confidential and proprietary information of Broadcom, and that Licensee's
+protection thereof is an essential condition to Licensee's use and possession
+of the Software. Licensee shall retain all Confidential Information in
+strict confidence and not disclose it to any third party or use it in any way
+except under a written agreement with terms and conditions at least as
+protective as the terms of this Section. Licensee will exercise at least the
+same amount of diligence in preserving the secrecy of the Confidential
+Information as it uses in preserving the secrecy of its own most valuable
+confidential information, but in no event less than reasonable diligence.
+Information shall not be considered Confidential Information if and to the
+extent that it: (i) was in the public domain at the time it was disclosed or
+has entered the public domain through no fault of Licensee; (ii) was known to
+Licensee, without restriction, at the time of disclosure as proven by the
+files of Licensee in existence at the time of disclosure; or (iii) becomes
+known to Licensee, without restriction, from a source other than Broadcom
+without breach of this Agreement by Licensee and otherwise not in violation
+of Broadcom's rights.
+
+5.2. Return of Confidential Information. Notwithstanding the foregoing, all
+documents and other tangible objects containing or representing Broadcom
+Confidential Information and all copies thereof which are in the possession
+of Licensee shall be and remain the property of Broadcom, and shall be
+promptly returned to Broadcom upon written request by Broadcom or upon
+termination of this Agreement.
+
+6. LIMITATION OF LIABILITY
+TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ANY OF
+BROADCOM'S LICENSORS HAVE ANY LIABILITY FOR ANY INDIRECT, INCIDENTAL,
+SPECIAL, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER FOR BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR
+OTHERWISE, ARISING OUT OF THIS AGREEMENT, INCLUDING BUT NOT LIMITED TO LOSS
+OF PROFITS, EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES. IN NO EVENT WILL BROADCOM'S LIABILITY WHETHER IN CONTRACT, TORT
+(INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE AMOUNT PAID BY LICENSEE FOR
+SOFTWARE UNDER THIS AGREEMENT. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
+ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
+
+7. MISCELLANEOUS
+
+7.1. Export Regulations. YOU UNDERSTAND AND AGREE THAT THE SOFTWARE IS
+SUBJECT TO UNITED STATES AND OTHER APPLICABLE EXPORT-RELATED LAWS AND
+REGULATIONS AND THAT YOU MAY NOT EXPORT, RE-EXPORT OR TRANSFER THE SOFTWARE
+OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER THOSE LAWS.
+WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT OR TRANSFER OF THE SOFTWARE
+TO CUBA, IRAN, NORTH KOREA, SUDAN AND SYRIA IS PROHIBITED.
+
+7.2 Assignment. This Agreement shall be binding upon and inure to the
+benefit of the parties and their respective successors and assigns, provided,
+however that Licensee may not assign this Agreement or any rights or
+obligation hereunder, directly or indirectly, by operation of law or
+otherwise, without the prior written consent of Broadcom, and any such
+attempted assignment shall be void. Notwithstanding the foregoing, Licensee
+may assign this Agreement to a successor to all or substantially all of its
+business or assets to which this Agreement relates that is not a competitor
+of Broadcom.
+
+7.3. Governing Law; Venue. This Agreement shall be governed by the laws of
+California without regard to any conflict-of-laws rules, and the United
+Nations Convention on Contracts for the International Sale of Goods is hereby
+excluded. The sole jurisdiction and venue for actions related to the subject
+matter hereof shall be the state and federal courts located in the County of
+Orange, California, and both parties hereby consent to such jurisdiction and
+venue.
+
+7.4. Severability. All terms and provisions of this Agreement shall, if
+possible, be construed in a manner which makes them valid, but in the event
+any term or provision of this Agreement is found by a court of competent
+jurisdiction to be illegal or unenforceable, the validity or enforceability
+of the remainder of this Agreement shall not be affected if the illegal or
+unenforceable provision does not materially affect the intent of this
+Agreement. If the illegal or unenforceable provision materially affects the
+intent of the parties to this Agreement, this Agreement shall become
+terminated.
+
+7.5. Equitable Relief. Licensee hereby acknowledges that its breach of this
+Agreement would cause irreparable harm and significant injury to Broadcom
+that may be difficult to ascertain and that a remedy at law would be
+inadequate. Accordingly, Licensee agrees that Broadcom shall have the right
+to seek and obtain immediate injunctive relief to enforce obligations under
+the Agreement in addition to any other rights and remedies it may have.
+
+7.6. Waiver. The waiver of, or failure to enforce, any breach or default
+hereunder shall not constitute the waiver of any other or subsequent breach
+or default.
+
+7.7. Entire Agreement. This Agreement sets forth the entire Agreement
+between the parties and supersedes any and all prior proposals, agreements
+and representations between them, whether written or oral concerning the
+Software. This Agreement may be changed only by mutual agreement of the
+parties in writing.
diff --git a/vendor/firmware/bcm4329/Android.mk b/vendor/firmware/bcm4329/Android.mk
new file mode 100644
index 0000000..e8e3449
--- /dev/null
+++ b/vendor/firmware/bcm4329/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bcm4329.hcd
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/firmware
+
+#LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_SRC_FILES := BCM4329B1_002.002.023.0944.0956.hcd
+
+#PRODUCT_COPY_FILES += \
+# hardware/broadcom/bt/firmware/bcm4330/BCM4329B1_002.002.023.0944.0956.hcd:system/vendor/firmware/BCM4329B1_002.002.023.0944.0956.hcd \
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_PREBUILT)
+
+
diff --git a/vendor/firmware/bcm4329/BCM4329B1_002.002.023.0944.0956.hcd b/vendor/firmware/bcm4329/BCM4329B1_002.002.023.0944.0956.hcd
new file mode 100644
index 0000000..581125a
--- /dev/null
+++ b/vendor/firmware/bcm4329/BCM4329B1_002.002.023.0944.0956.hcd
Binary files differ
diff --git a/vendor/firmware/bcm4330/Android.mk b/vendor/firmware/bcm4330/Android.mk
new file mode 100644
index 0000000..3742d98
--- /dev/null
+++ b/vendor/firmware/bcm4330/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := bcm4330.hcd
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/firmware
+
+#LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_SRC_FILES := BCM4330B1.hcd
+
+#PRODUCT_COPY_FILES += \
+# hardware/broadcom/bt/firmware/bcm4330/BCM4330B1.hcd:system/vendor/firmware/BCM4330B1.hcd
+
+LOCAL_MODULE_TAGS := eng
+
+include $(BUILD_PREBUILT)
+
+
diff --git a/vendor/firmware/bcm4330/BCM4330B1.hcd b/vendor/firmware/bcm4330/BCM4330B1.hcd
new file mode 100644
index 0000000..983d40e
--- /dev/null
+++ b/vendor/firmware/bcm4330/BCM4330B1.hcd
Binary files differ
diff --git a/vendor/libvendor/Android.mk b/vendor/libvendor/Android.mk
new file mode 100644
index 0000000..8ea5e90
--- /dev/null
+++ b/vendor/libvendor/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ src/bt_vendor_brcm.c \
+ src/hci_h4.c \
+ src/userial.c \
+ src/hardware.c \
+ src/upio.c \
+ src/utils.c \
+ src/btsnoop.c
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/include
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils
+
+LOCAL_MODULE := libbt-vendor
+LOCAL_MODULE_TAGS := eng
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/vendor/libvendor/include/bt_vendor_brcm.h b/vendor/libvendor/include/bt_vendor_brcm.h
new file mode 100644
index 0000000..e89fa9e
--- /dev/null
+++ b/vendor/libvendor/include/bt_vendor_brcm.h
@@ -0,0 +1,414 @@
+/************************************************************************************
+ *
+ * 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: bt_vendor_brcm.h
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#ifndef BT_VENDOR_BRCM_H
+#define BT_VENDOR_BRCM_H
+
+#include "bt_vendor_lib.h"
+#include "vnd_buildcfg.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#ifndef BTVND_LINUX_BASE_PRIORITY
+#define BTVND_LINUX_BASE_PRIORITY 30
+#endif
+
+#ifndef BTVND_USERIAL_READ_THREAD_PRIORITY
+#define BTVND_USERIAL_READ_THREAD_PRIORITY (BTVND_LINUX_BASE_PRIORITY)
+#endif
+
+#ifndef BTVND_MAIN_THREAD_PRIORITY
+#define BTVND_MAIN_THREAD_PRIORITY (BTVND_LINUX_BASE_PRIORITY-1)
+#endif
+
+#ifndef BTVND_USERIAL_READ_MEM_SIZE
+#define BTVND_USERIAL_READ_MEM_SIZE (1024)
+#endif
+
+/* Vendor lib internal event ID */
+#define VND_EVENT_PRELOAD 0x0001
+#define VND_EVENT_POSTLOAD 0x0002
+#define VND_EVENT_RX 0x0004
+#define VND_EVENT_TX 0x0008
+#define VND_EVENT_LPM_ENABLE 0x0010
+#define VND_EVENT_LPM_DISABLE 0x0020
+#define VND_EVENT_LPM_WAKE_DEVICE 0x0040
+#define VND_EVENT_LPM_ALLOW_SLEEP 0x0080
+#define VND_EVENT_LPM_IDLE_TIMEOUT 0x0100
+#define VND_EVENT_EXIT 0x0200
+
+/* Message event mask across vendor lib and stack */
+#define MSG_EVT_MASK 0xFF00 /* eq. BT_EVT_MASK */
+#define MSG_SUB_EVT_MASK 0x00FF /* eq. BT_SUB_EVT_MASK */
+
+/* Message event ID passed from vendor lib to stack */
+#define MSG_VND_TO_STACK_HCI_ERR 0x1300 /* HCIT_TYPE_COMMAND = BT_EVT_TO_BTU_HCIT_ERR */
+#define MSG_VND_TO_STACK_HCI_ACL 0x1100 /* HCIT_TYPE_ACL_DATA = BT_EVT_TO_BTU_HCI_ACL */
+#define MSG_VND_TO_STACK_HCI_SCO 0x1200 /* HCIT_TYPE_SCO_DATA = BT_EVT_TO_BTU_HCI_SCO */
+#define MSG_VND_TO_STACK_HCI_EVT 0x1000 /* HCIT_TYPE_EVENT = BT_EVT_TO_BTU_HCI_EVT */
+#define MSG_VND_TO_STACK_L2C_SEG_XMIT 0x1900 /* L2CAP segment(s) transmitted = BT_EVT_TO_BTU_L2C_SEG_XMIT */
+
+/* Message event ID passed from stack to vendor lib */
+#define MSG_STACK_TO_VND_HCI_ACL 0x2100 /* HCI ACL Data = BT_EVT_TO_LM_HCI_ACL */
+#define MSG_STACK_TO_VND_HCI_SCO 0x2200 /* HCI SCO Data = BT_EVT_TO_LM_HCI_SCO */
+#define MSG_STACK_TO_VND_HCI_CMD 0x2000 /* HCI Command = BT_EVT_TO_LM_HCI_CMD */
+
+/* Local Bluetooth Controller ID for BR/EDR */
+#define LOCAL_BR_EDR_CONTROLLER_ID 0
+
+/* Device port name where Bluetooth controller attached */
+#ifndef BLUETOOTH_UART_DEVICE_PORT
+#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyO1" /* maguro */
+#endif
+
+/* Location of firmware patch files */
+#ifndef FW_PATCHFILE_LOCATION
+#define FW_PATCHFILE_LOCATION ("/vendor/firmware/") /* maguro */
+#endif
+
+#ifndef UART_TARGET_BAUD_RATE
+#define UART_TARGET_BAUD_RATE 3000000
+#endif
+
+/* sleep mode
+
+ 0: disable
+ 1: UART with Host wake/BT wake out of band signals
+*/
+#ifndef LPM_SLEEP_MODE
+#define LPM_SLEEP_MODE 1
+#endif
+
+/* Host Stack Idle Threshold in 300ms or 25ms
+
+ In sleep mode 1, this is the number of firmware loops executed with no activity
+ before the Host wake line is deasserted. Activity includes HCI traffic excluding
+ certain sleep mode commands and the presence of SCO connections if the
+ "Allow Host Sleep During SCO" flag is not set to 1. Each count of this
+ parameter is roughly equivalent to 300ms or 25ms.
+*/
+#ifndef LPM_IDLE_THRESHOLD
+#define LPM_IDLE_THRESHOLD 1
+#endif
+
+/* Host Controller Idle Threshold in 300ms or 25ms
+
+ This is the number of firmware loops executed with no activity before the HC is
+ considered idle. Depending on the mode, HC may then attempt to sleep.
+ Activity includes HCI traffic excluding certain sleep mode commands and
+ the presence of ACL/SCO connections.
+
+*/
+#ifndef LPM_HC_IDLE_THRESHOLD
+#define LPM_HC_IDLE_THRESHOLD 1
+#endif
+
+/* BT_WAKE Polarity - 0=Active Low, 1= Active High */
+#ifndef LPM_BT_WAKE_POLARITY
+#define LPM_BT_WAKE_POLARITY 1 /* maguro */
+#endif
+
+/* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
+#ifndef LPM_HOST_WAKE_POLARITY
+#define LPM_HOST_WAKE_POLARITY 1 /* maguro */
+#endif
+
+/* LPM_ALLOW_HOST_SLEEP_DURING_SCO
+
+ When this flag is set to 0, the host is not allowed to sleep while
+ an SCO is active. In sleep mode 1, the device will keep the host
+ wake line asserted while an SCO is active.
+ When this flag is set to 1, the host can sleep while an SCO is active.
+ This flag should only be set to 1 if SCO traffic is directed to the PCM interface.
+*/
+#ifndef LPM_ALLOW_HOST_SLEEP_DURING_SCO
+#define LPM_ALLOW_HOST_SLEEP_DURING_SCO 1
+#endif
+
+/* LPM_COMBINE_SLEEP_MODE_AND_LPM
+
+ In Mode 0, always set byte 7 to 0. In sleep mode 1, device always
+ requires permission to sleep between scans / periodic inquiries regardless
+ of the setting of this byte. In sleep mode 1, if byte is set, device must
+ have "permission" to sleep during the low power modes of sniff, hold, and park.
+ If byte is not set, device can sleep without permission during these modes.
+ Permission to sleep in Mode 1 is obtained if the BT_WAKE signal is not asserted.
+*/
+#ifndef LPM_COMBINE_SLEEP_MODE_AND_LPM
+#define LPM_COMBINE_SLEEP_MODE_AND_LPM 1
+#endif
+
+/* LPM_ENABLE_UART_TXD_TRI_STATE
+
+ When set to 0, the device will not tristate its UART TX line before going to sleep.
+ When set to 1, the device will tristate its UART TX line before going to sleep.
+*/
+#ifndef LPM_ENABLE_UART_TXD_TRI_STATE
+#define LPM_ENABLE_UART_TXD_TRI_STATE 0
+#endif
+
+/* LPM_PULSED_HOST_WAKE
+*/
+#ifndef LPM_PULSED_HOST_WAKE
+#define LPM_PULSED_HOST_WAKE 0
+#endif
+
+/* LPM_IDLE_TIMEOUT_MULTIPLE
+
+ The multiple factor of host stack idle threshold in 300ms/25ms
+*/
+#ifndef LPM_IDLE_TIMEOUT_MULTIPLE
+#define LPM_IDLE_TIMEOUT_MULTIPLE 10
+#endif
+
+/* SCO_CFG_INCLUDED
+
+ Do SCO configuration by default. If the firmware patch had been embedded
+ with desired SCO configuration, set this FALSE to bypass configuration
+ from host software.
+*/
+#ifndef SCO_CFG_INCLUDED
+#define SCO_CFG_INCLUDED TRUE
+#endif
+
+#ifndef SCO_USE_I2S_INTERFACE
+#define SCO_USE_I2S_INTERFACE FALSE
+#endif
+
+#if (SCO_USE_I2S_INTERFACE == TRUE)
+#define SCO_I2SPCM_PARAM_SIZE 4
+
+/* SCO_I2SPCM_IF_MODE - 0=Disable, 1=Enable */
+#ifndef SCO_I2SPCM_IF_MODE
+#define SCO_I2SPCM_IF_MODE 1
+#endif
+
+/* SCO_I2SPCM_IF_ROLE - 0=Slave, 1=Master */
+#ifndef SCO_I2SPCM_IF_ROLE
+#define SCO_I2SPCM_IF_ROLE 1
+#endif
+
+/* SCO_I2SPCM_IF_SAMPLE_RATE
+
+ 0 : 8K
+ 1 : 16K
+ 2 : 4K
+*/
+#ifndef SCO_I2SPCM_IF_SAMPLE_RATE
+#define SCO_I2SPCM_IF_SAMPLE_RATE 0
+#endif
+
+/* SCO_I2SPCM_IF_CLOCK_RATE
+
+ 0 : 128K
+ 1 : 256K
+ 2 : 512K
+ 3 : 1024K
+ 4 : 2048K
+*/
+#ifndef SCO_I2SPCM_IF_CLOCK_RATE
+#define SCO_I2SPCM_IF_CLOCK_RATE 1
+#endif
+#endif // SCO_USE_I2S_INTERFACE
+
+
+#define SCO_PCM_PARAM_SIZE 5
+
+/* SCO_PCM_ROUTING
+
+ 0 : PCM
+ 1 : Transport
+ 2 : Codec
+ 3 : I2S
+*/
+#ifndef SCO_PCM_ROUTING
+#define SCO_PCM_ROUTING 0
+#endif
+
+/* SCO_PCM_IF_CLOCK_RATE
+
+ 0 : 128K
+ 1 : 256K
+ 2 : 512K
+ 3 : 1024K
+ 4 : 2048K
+*/
+#ifndef SCO_PCM_IF_CLOCK_RATE
+#define SCO_PCM_IF_CLOCK_RATE 4
+#endif
+
+/* SCO_PCM_IF_FRAME_TYPE - 0=Short, 1=Long */
+#ifndef SCO_PCM_IF_FRAME_TYPE
+#define SCO_PCM_IF_FRAME_TYPE 0
+#endif
+
+/* SCO_PCM_IF_SYNC_MODE - 0=Slave, 1=Master */
+#ifndef SCO_PCM_IF_SYNC_MODE
+#define SCO_PCM_IF_SYNC_MODE 0
+#endif
+
+/* SCO_PCM_IF_CLOCK_MODE - 0=Slave, 1=Master */
+#ifndef SCO_PCM_IF_CLOCK_MODE
+#define SCO_PCM_IF_CLOCK_MODE 0
+#endif
+
+#define PCM_DATA_FORMAT_PARAM_SIZE 5
+
+/* PCM_DATA_FMT_SHIFT_MODE
+
+ 0 : MSB first
+ 1 : LSB first
+*/
+#ifndef PCM_DATA_FMT_SHIFT_MODE
+#define PCM_DATA_FMT_SHIFT_MODE 0
+#endif
+
+/* PCM_DATA_FMT_FILL_BITS
+
+ Specifies the value with which to fill unused bits
+ if Fill_Method is set to programmable
+*/
+#ifndef PCM_DATA_FMT_FILL_BITS
+#define PCM_DATA_FMT_FILL_BITS 0
+#endif
+
+/* PCM_DATA_FMT_FILL_METHOD
+
+ 0 : 0's
+ 1 : 1's
+ 2 : Signed
+ 3 : Programmable
+*/
+#ifndef PCM_DATA_FMT_FILL_METHOD
+#define PCM_DATA_FMT_FILL_METHOD 3
+#endif
+
+/* PCM_DATA_FMT_FILL_NUM
+
+ Specifies the number of bits to be filled
+*/
+#ifndef PCM_DATA_FMT_FILL_NUM
+#define PCM_DATA_FMT_FILL_NUM 3
+#endif
+
+/* PCM_DATA_FMT_JUSTIFY_MODE
+
+ 0 : Left justify (fill data shifted out last)
+ 1 : Right justify (fill data shifted out first)
+*/
+#ifndef PCM_DATA_FMT_JUSTIFY_MODE
+#define PCM_DATA_FMT_JUSTIFY_MODE 0
+#endif
+
+/************************************************************************************
+** Type definitions and return values
+************************************************************************************/
+
+typedef struct
+{
+ uint16_t event;
+ uint16_t len;
+ uint16_t offset;
+ uint16_t layer_specific;
+} VND_BT_HDR;
+
+#define BT_VND_HDR_SIZE (sizeof(VND_BT_HDR))
+
+
+typedef struct _vnd_buffer_hdr
+{
+ struct _vnd_buffer_hdr *p_next; /* next buffer in the queue */
+ uint8_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+ uint8_t reserved4;
+} VND_BUFFER_HDR_T;
+
+#define BT_VND_BUFFER_HDR_SIZE (sizeof(VND_BUFFER_HDR_T))
+
+/************************************************************************************
+** Extern variables and functions
+************************************************************************************/
+
+extern bt_vendor_callbacks_t *bt_vendor_cbacks;
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function btvnd_signal_event
+**
+** Description Perform context switch to bt_vendor main thread
+**
+** Returns None
+**
+*******************************************************************************/
+extern void btvnd_signal_event(uint16_t event);
+
+
+#endif /* BT_VENDOR_BRCM_H */
+
diff --git a/vendor/libvendor/include/bt_vendor_lib.h b/vendor/libvendor/include/bt_vendor_lib.h
new file mode 100644
index 0000000..226d4f4
--- /dev/null
+++ b/vendor/libvendor/include/bt_vendor_lib.h
@@ -0,0 +1,222 @@
+/************************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+#ifndef BT_VENDOR_LIB_H
+#define BT_VENDOR_LIB_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/** Struct types */
+
+
+/** Typedefs and defines */
+
+/* Generic purpose transac returned upon request complete */
+typedef void* TRANSAC;
+
+/** Bluetooth Power Control States */
+typedef enum {
+ BT_VENDOR_CHIP_PWR_OFF,
+ BT_VENDOR_CHIP_PWR_ON,
+} bt_vendor_chip_power_state_t;
+
+/** Bluetooth Low Power Mode */
+typedef enum {
+ BT_VENDOR_LPM_DISABLE,
+ BT_VENDOR_LPM_ENABLE,
+ BT_VENDOR_LPM_WAKE_ASSERT,
+ BT_VENDOR_LPM_WAKE_DEASSERT,
+} bt_vendor_low_power_event_t;
+
+/** Receive flow control */
+typedef enum {
+ BT_RXFLOW_OFF, /* add transport device fd to select set */
+ BT_RXFLOW_ON, /* remove transport device to from select set */
+} bt_rx_flow_state_t;
+
+/** Result of write request */
+typedef enum {
+ BT_VENDOR_TX_SUCCESS, /* a buffer is fully processed and can be released */
+ BT_VENDOR_TX_FAIL, /* transmit fail */
+ BT_VENDOR_TX_FRAGMENT, /* send back split ACL packet for core stack to reprocess */
+} bt_vendor_transmit_result_t;
+
+/** Result of preload initialization */
+typedef enum {
+ BT_VENDOR_PRELOAD_SUCCESS,
+ BT_VENDOR_PRELOAD_FAIL,
+} bt_vendor_preload_result_t;
+
+/** Result of postload initialization */
+typedef enum {
+ BT_VENDOR_POSTLOAD_SUCCESS,
+ BT_VENDOR_POSTLOAD_FAIL,
+} bt_vendor_postload_result_t;
+
+/** Result of low power enable/disable request */
+typedef enum {
+ BT_VENDOR_LPM_DISABLED,
+ BT_VENDOR_LPM_ENABLED,
+} bt_vendor_lpm_request_result_t;
+
+/** Vendor Library Return Status */
+typedef enum {
+ BT_VENDOR_STATUS_SUCCESS,
+ BT_VENDOR_STATUS_FAIL,
+ BT_VENDOR_STATUS_NOT_READY,
+ BT_VENDOR_STATUS_NOMEM,
+ BT_VENDOR_STATUS_BUSY,
+ BT_VENDOR_STATUS_CORRUPTED_BUFFER
+} bt_vnd_status_t;
+
+
+/* Section comment */
+
+/*
+ * Bluetooth Vendor callback structure.
+ */
+
+/* called upon bt host wake signal */
+typedef void (*hostwake_ind_cb)(bt_vendor_low_power_event_t event);
+
+/* preload initialization callback */
+typedef void (*preload_result_cb)(TRANSAC transac, bt_vendor_preload_result_t result);
+
+/* postload initialization callback */
+typedef void (*postload_result_cb)(TRANSAC transac, bt_vendor_postload_result_t result);
+
+/* lpm enable/disable callback */
+typedef void (*lpm_result_cb)(bt_vendor_lpm_request_result_t result);
+
+/* datapath buffer allocation callback (callout) */
+typedef char* (*alloc_mem_cb)(int size);
+
+/* datapath buffer deallocation callback (callout) */
+typedef int (*dealloc_mem_cb)(TRANSAC transac, char *p_buf);
+
+/* transmit result callback */
+typedef int (*tx_result_cb)(TRANSAC transac, char *p_buf, bt_vendor_transmit_result_t result);
+
+/* a previously setup buffer is read and available for processing
+ buffer is deallocated in stack when processed */
+typedef int (*data_ind_cb)(TRANSAC transac, char *p_buf, int len);
+
+typedef struct {
+ /** set to sizeof(bt_vendor_callbacks_t) */
+ size_t size;
+
+ /* notifies caller result of preload request */
+ preload_result_cb preload_cb;
+
+ /* notifies caller result of postload request */
+ postload_result_cb postload_cb;
+
+ /* notifies caller result of lpm enable/disable */
+ lpm_result_cb lpm_cb;
+
+ /* notifies hardware on host wake state */
+ hostwake_ind_cb hostwake_ind;
+
+ /* buffer allocation request */
+ alloc_mem_cb alloc;
+
+ /* buffer deallocation request */
+ dealloc_mem_cb dealloc;
+
+ /* notifies stack data is available */
+ data_ind_cb data_ind;
+
+ /* notifies caller when a buffer is transmitted (or failed) */
+ tx_result_cb tx_result;
+} bt_vendor_callbacks_t;
+
+/*
+ * Bluetooth Vendor Interface
+ */
+typedef struct {
+ /** Set to sizeof(bt_vendor_interface_t) */
+ size_t size;
+
+ /**
+ * Opens the interface and provides the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)(const bt_vendor_callbacks_t* p_cb);
+
+ /** Chip power control */
+ void (*set_power)(bt_vendor_chip_power_state_t state);
+
+ /** Set low power mode wake */
+ int (*lpm)(bt_vendor_low_power_event_t event);
+
+ /** Called prior to stack initialization */
+ void (*preload)(TRANSAC transac);
+
+ /** Called post stack initialization */
+ void (*postload)(TRANSAC transac);
+
+ /** Transmit buffer */
+ int (*transmit_buf)(TRANSAC transac, char *p_buf, int len);
+
+ /** Controls receive flow */
+ int (*set_rxflow)(bt_rx_flow_state_t state);
+
+ /** Closes the interface */
+ void (*cleanup)( void );
+} bt_vendor_interface_t;
+
+
+/*
+ * External shared lib functions
+ */
+
+extern const bt_vendor_interface_t* bt_vendor_get_interface(void);
+
+#endif /* BT_VENDOR_LIB_H */
+
diff --git a/vendor/libvendor/include/upio.h b/vendor/libvendor/include/upio.h
new file mode 100644
index 0000000..9135da5
--- /dev/null
+++ b/vendor/libvendor/include/upio.h
@@ -0,0 +1,136 @@
+/************************************************************************************
+ *
+ * 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: upio.h
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#ifndef UPIO_H
+#define UPIO_H
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#define UPIO_BT_POWER_OFF 0
+#define UPIO_BT_POWER_ON 1
+
+/* UPIO signals */
+enum {
+ UPIO_BT_WAKE = 0,
+ UPIO_HOST_WAKE,
+ UPIO_MAX_COUNT
+};
+
+/* UPIO assertion/deassertion */
+enum {
+ UPIO_UNKNOWN = 0,
+ UPIO_DEASSERT,
+ UPIO_ASSERT
+};
+
+
+/************************************************************************************
+** Extern variables and functions
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function upio_init
+**
+** Description Initialization
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_init(void);
+
+/*******************************************************************************
+**
+** Function upio_cleanup
+**
+** Description Clean up
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_cleanup(void);
+
+/*******************************************************************************
+**
+** Function upio_set_bluetooth_power
+**
+** Description Interact with low layer driver to set Bluetooth power
+** on/off.
+**
+** Returns 0 : SUCCESS or Not-Applicable
+** <0 : ERROR
+**
+*******************************************************************************/
+int upio_set_bluetooth_power(int on);
+
+/*******************************************************************************
+**
+** Function upio_set
+**
+** Description Set i/o based on polarity
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_set(uint8_t pio, uint8_t action, uint8_t polarity);
+
+#endif /* UPIO_H */
+
diff --git a/vendor/libvendor/include/userial.h b/vendor/libvendor/include/userial.h
new file mode 100644
index 0000000..c7a97b9
--- /dev/null
+++ b/vendor/libvendor/include/userial.h
@@ -0,0 +1,245 @@
+/************************************************************************************
+ *
+ * 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: userial.h
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#ifndef USERIAL_H
+#define USERIAL_H
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+/**** port IDs ****/
+#define USERIAL_PORT_1 0
+#define USERIAL_PORT_2 1
+#define USERIAL_PORT_3 2
+#define USERIAL_PORT_4 3
+#define USERIAL_PORT_5 4
+#define USERIAL_PORT_6 5
+#define USERIAL_PORT_7 6
+#define USERIAL_PORT_8 7
+#define USERIAL_PORT_9 8
+#define USERIAL_PORT_10 9
+#define USERIAL_PORT_11 10
+#define USERIAL_PORT_12 11
+#define USERIAL_PORT_13 12
+#define USERIAL_PORT_14 13
+#define USERIAL_PORT_15 14
+#define USERIAL_PORT_16 15
+#define USERIAL_PORT_17 16
+#define USERIAL_PORT_18 17
+
+/**** baud rates ****/
+#define USERIAL_BAUD_300 0
+#define USERIAL_BAUD_600 1
+#define USERIAL_BAUD_1200 2
+#define USERIAL_BAUD_2400 3
+#define USERIAL_BAUD_9600 4
+#define USERIAL_BAUD_19200 5
+#define USERIAL_BAUD_57600 6
+#define USERIAL_BAUD_115200 7
+#define USERIAL_BAUD_230400 8
+#define USERIAL_BAUD_460800 9
+#define USERIAL_BAUD_921600 10
+#define USERIAL_BAUD_1M 11
+#define USERIAL_BAUD_1_5M 12
+#define USERIAL_BAUD_2M 13
+#define USERIAL_BAUD_3M 14
+#define USERIAL_BAUD_4M 15
+#define USERIAL_BAUD_AUTO 16
+
+/**** Data Format ****/
+/* Stop Bits */
+#define USERIAL_STOPBITS_1 1
+#define USERIAL_STOPBITS_1_5 (1<<1)
+#define USERIAL_STOPBITS_2 (1<<2)
+
+/* Parity Bits */
+#define USERIAL_PARITY_NONE (1<<3)
+#define USERIAL_PARITY_EVEN (1<<4)
+#define USERIAL_PARITY_ODD (1<<5)
+
+/* Data Bits */
+#define USERIAL_DATABITS_5 (1<<6)
+#define USERIAL_DATABITS_6 (1<<7)
+#define USERIAL_DATABITS_7 (1<<8)
+#define USERIAL_DATABITS_8 (1<<9)
+
+typedef enum {
+ USERIAL_OP_INIT,
+ USERIAL_OP_RXFLOW_ON,
+ USERIAL_OP_RXFLOW_OFF,
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+ USERIAL_OP_ASSERT_BT_WAKE,
+ USERIAL_OP_DEASSERT_BT_WAKE,
+ USERIAL_OP_GET_BT_WAKE_STATE
+#endif
+} userial_ioctl_op_t;
+
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+/* These are the ioctl values used for bt_wake ioctl via UART driver. you may need to
+ * redefine them on you platform!
+ * Logically they need to be unique and not colide with existing uart ioctl's.
+ */
+#ifndef USERIAL_IOCTL_BT_WAKE_ASSERT
+#define USERIAL_IOCTL_BT_WAKE_ASSERT 0x8003
+#endif
+#ifndef USERIAL_IOCTL_BT_WAKE_DEASSERT
+#define USERIAL_IOCTL_BT_WAKE_DEASSERT 0x8004
+#endif
+#ifndef USERIAL_IOCTL_BT_WAKE_GET_ST
+#define USERIAL_IOCTL_BT_WAKE_GET_ST 0x8005
+#endif
+#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+
+/************************************************************************************
+** Type definitions
+************************************************************************************/
+
+/* Structure used to configure serial port during open */
+typedef struct
+{
+ uint16_t fmt; /* Data format */
+ uint8_t baud; /* Baud rate */
+} tUSERIAL_CFG;
+
+/************************************************************************************
+** Extern variables and functions
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function userial_init
+**
+** Description Initializes the userial driver
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t userial_init(void);
+
+/*******************************************************************************
+**
+** Function userial_open
+**
+** Description Open the indicated serial port with the given configuration
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t userial_open(uint8_t port, tUSERIAL_CFG *p_cfg);
+
+/*******************************************************************************
+**
+** Function userial_read
+**
+** Description Read data from the userial port
+**
+** Returns Number of bytes actually read from the userial port and
+** copied into p_data. This may be less than len.
+**
+*******************************************************************************/
+uint16_t userial_read(uint8_t *p_buffer, uint16_t len);
+
+/*******************************************************************************
+**
+** Function userial_write
+**
+** Description Write data to the userial port
+**
+** Returns Number of bytes actually written to the userial port. This
+** may be less than len.
+**
+*******************************************************************************/
+uint16_t userial_write(uint8_t *p_data, uint16_t len);
+
+/*******************************************************************************
+**
+** Function userial_close
+**
+** Description Close the userial port
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_close(void);
+
+/*******************************************************************************
+**
+** Function userial_change_baud
+**
+** Description Change baud rate of userial port
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_change_baud(uint8_t baud);
+
+/*******************************************************************************
+**
+** Function userial_ioctl
+**
+** Description ioctl inteface
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_ioctl(userial_ioctl_op_t op, void *p_data);
+
+#endif /* USERIAL_H */
+
diff --git a/vendor/libvendor/include/utils.h b/vendor/libvendor/include/utils.h
new file mode 100644
index 0000000..c1a5f35
--- /dev/null
+++ b/vendor/libvendor/include/utils.h
@@ -0,0 +1,200 @@
+/************************************************************************************
+ *
+ * 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.h
+ *
+ * Description: Utility functions declaration
+ *
+ ***********************************************************************************/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
+#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
+
+/************************************************************************************
+** Type definitions
+************************************************************************************/
+
+typedef struct
+{
+ void *p_first;
+ void *p_last;
+ uint16_t count;
+} BUFFER_Q;
+
+/************************************************************************************
+** Extern variables and functions
+************************************************************************************/
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function utils_init
+**
+** Description Utils initialization
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_init ();
+
+/*******************************************************************************
+**
+** Function utils_cleanup
+**
+** Description Utils cleanup
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_cleanup ();
+
+/*******************************************************************************
+**
+** Function utils_queue_init
+**
+** Description Initialize the given buffer queue
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_queue_init (BUFFER_Q *p_q);
+
+/*******************************************************************************
+**
+** 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);
+
+/*******************************************************************************
+**
+** 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);
+
+/*******************************************************************************
+**
+** 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);
+
+/*******************************************************************************
+**
+** 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);
+
+/*******************************************************************************
+**
+** Function utils_delay
+**
+** Description sleep unconditionally for timeout milliseconds
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_delay (uint32_t timeout);
+
+/*******************************************************************************
+**
+** Function utils_lock
+**
+** Description application calls this function before entering critical
+** section
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_lock (void);
+
+/*******************************************************************************
+**
+** Function utils_unlock
+**
+** Description application calls this function when leaving critical
+** section
+**
+** Returns None
+**
+*******************************************************************************/
+void utils_unlock (void);
+
+#endif /* UTILS_H */
+
diff --git a/vendor/libvendor/include/vnd_buildcfg.h b/vendor/libvendor/include/vnd_buildcfg.h
new file mode 100644
index 0000000..a6fbb23
--- /dev/null
+++ b/vendor/libvendor/include/vnd_buildcfg.h
@@ -0,0 +1,14 @@
+#ifndef VND_BUILDCFG_H
+#define VND_BUILDCFG_H
+//#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyHS0" /* pyramid */
+//#define FW_PATCHFILE_LOCATION ("/etc/firmware/") /* pyramid */
+//#define LPM_BT_WAKE_POLARITY 0 /* pyramid */
+//#define LPM_HOST_WAKE_POLARITY 0 /* pyramid */
+#define BT_WAKE_VIA_USERIAL_IOCTL TRUE
+#define LPM_IDLE_TIMEOUT_MULTIPLE 5
+#define BTSNOOPDISP_INCLUDED TRUE
+#define BTSNOOP_FILENAME "/data/misc/bluedroid/btsnoop_hci.cfa"
+#define SNOOP_CONFIG_PATH "/data/misc/bluedroid/btsnoop_enabled"
+#define BTSNOOP_DBG FALSE
+#define SCO_USE_I2S_INTERFACE TRUE
+#endif // VND_BUILDCFG_H
diff --git a/vendor/libvendor/src/bt_vendor_brcm.c b/vendor/libvendor/src/bt_vendor_brcm.c
new file mode 100644
index 0000000..20cd7a3
--- /dev/null
+++ b/vendor/libvendor/src/bt_vendor_brcm.c
@@ -0,0 +1,455 @@
+/************************************************************************************
+ *
+ * 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: bt_vendor_brcm.c
+ *
+ * Description: Bluetooth vendor library implementation
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_vendor_brcm"
+
+#include <utils/Log.h>
+#include <pthread.h>
+#include "bt_vendor_brcm.h"
+#include "upio.h"
+#include "utils.h"
+#include "userial.h"
+
+#ifndef BTVND_DBG
+#define BTVND_DBG FALSE
+#endif
+
+#if (BTVND_DBG == TRUE)
+#define BTVNDDBG LOGD
+#else
+#define BTVNDDBG
+#endif
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+extern int num_hci_cmd_pkts;
+void hci_h4_init(void);
+void hci_h4_cleanup(void);
+void hci_h4_send_msg(VND_BT_HDR *p_msg);
+uint16_t hci_h4_receive_msg(void);
+void hci_h4_get_acl_data_length(void);
+void hw_config_start(void);
+uint8_t hw_lpm_enable(uint8_t turn_on);
+void hw_lpm_deassert_bt_wake(void);
+void hw_lpm_allow_bt_device_sleep(void);
+void hw_lpm_assert_bt_wake(void);
+#if (SCO_CFG_INCLUDED == TRUE)
+void hw_sco_config(void);
+#endif
+
+/************************************************************************************
+** Variables
+************************************************************************************/
+
+bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
+
+/************************************************************************************
+** Static Variables
+************************************************************************************/
+
+static pthread_t worker_thread;
+static volatile uint8_t lib_running = 0;
+static pthread_mutex_t vnd_mutex;
+static pthread_cond_t vnd_cond;
+static volatile uint16_t ready_events = 0;
+static volatile uint8_t tx_cmd_pkts_pending = FALSE;
+
+static const tUSERIAL_CFG userial_init_cfg =
+{
+ (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
+ USERIAL_BAUD_115200
+};
+
+BUFFER_Q tx_q;
+
+/************************************************************************************
+** Functions
+************************************************************************************/
+
+static void *bt_vndor_worker_thread(void *arg);
+
+void btvnd_signal_event(uint16_t event)
+{
+ pthread_mutex_lock(&vnd_mutex);
+ ready_events |= event;
+ pthread_cond_signal(&vnd_cond);
+ pthread_mutex_unlock(&vnd_mutex);
+}
+
+/*****************************************************************************
+**
+** BLUETOOTH VENDOR LIBRARY INTERFACE FUNCTIONS
+**
+*****************************************************************************/
+
+static int init(const bt_vendor_callbacks_t* p_cb)
+{
+ pthread_attr_t thread_attr;
+ struct sched_param param;
+ int policy;
+
+ BTVNDDBG("init");
+
+ if (p_cb == NULL)
+ {
+ LOGE("init failed with no user callbacks!");
+ return BT_VENDOR_STATUS_FAIL;
+ }
+
+ /* store reference to user callbacks */
+ bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
+
+ utils_init();
+ upio_init();
+ hci_h4_init();
+ userial_init();
+
+ utils_queue_init(&tx_q);
+
+ if (lib_running)
+ {
+ LOGW("init has been called repeatedly without calling cleanup ?");
+ }
+
+ lib_running = 1;
+ ready_events = 0;
+ pthread_mutex_init(&vnd_mutex, NULL);
+ pthread_cond_init(&vnd_cond, NULL);
+ pthread_attr_init(&thread_attr);
+
+ if (pthread_create(&worker_thread, &thread_attr, bt_vndor_worker_thread, NULL) != 0)
+ {
+ LOGE("pthread_create failed!");
+ lib_running = 0;
+ return BT_VENDOR_STATUS_FAIL;
+ }
+
+ if(pthread_getschedparam(worker_thread, &policy, &param)==0)
+ {
+ policy = SCHED_FIFO;
+ param.sched_priority = BTVND_MAIN_THREAD_PRIORITY;
+ pthread_setschedparam(worker_thread, policy, &param);
+ }
+
+ return BT_VENDOR_STATUS_SUCCESS;
+}
+
+
+/** Chip power control */
+static void set_power(bt_vendor_chip_power_state_t state)
+{
+ BTVNDDBG("set_power %d", state);
+
+ if (state == BT_VENDOR_CHIP_PWR_OFF)
+ upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
+ else if (state == BT_VENDOR_CHIP_PWR_ON)
+ upio_set_bluetooth_power(UPIO_BT_POWER_ON);
+}
+
+
+/** Configure low power mode wake state */
+static int lpm(bt_vendor_low_power_event_t event)
+{
+ uint8_t status = TRUE;
+
+ switch (event)
+ {
+ case BT_VENDOR_LPM_DISABLE:
+ btvnd_signal_event(VND_EVENT_LPM_DISABLE);
+ break;
+
+ case BT_VENDOR_LPM_ENABLE:
+ btvnd_signal_event(VND_EVENT_LPM_ENABLE);
+ break;
+
+ case BT_VENDOR_LPM_WAKE_ASSERT:
+ btvnd_signal_event(VND_EVENT_LPM_WAKE_DEVICE);
+ break;
+
+ case BT_VENDOR_LPM_WAKE_DEASSERT:
+ btvnd_signal_event(VND_EVENT_LPM_ALLOW_SLEEP);
+ break;
+ }
+
+ return(status == TRUE) ? BT_VENDOR_STATUS_SUCCESS : BT_VENDOR_STATUS_FAIL;
+}
+
+
+/** Called prio to stack initialization */
+static void preload(TRANSAC transac)
+{
+ BTVNDDBG("preload");
+ btvnd_signal_event(VND_EVENT_PRELOAD);
+}
+
+
+/** Called post stack initialization */
+static void postload(TRANSAC transac)
+{
+ BTVNDDBG("postload");
+ btvnd_signal_event(VND_EVENT_POSTLOAD);
+}
+
+
+/** Transmit frame */
+static int transmit_buf(TRANSAC transac, char *p_buf, int len)
+{
+ utils_enqueue(&tx_q, (void *) transac);
+
+ btvnd_signal_event(VND_EVENT_TX);
+
+ return BT_VENDOR_STATUS_SUCCESS;
+}
+
+
+/** Controls receive flow */
+static int set_rxflow(bt_rx_flow_state_t state)
+{
+ BTVNDDBG("set_rxflow %d", state);
+
+ userial_ioctl(((state == BT_RXFLOW_ON) ? USERIAL_OP_RXFLOW_ON : USERIAL_OP_RXFLOW_OFF), NULL);
+
+ return BT_VENDOR_STATUS_SUCCESS;
+}
+
+
+/** Closes the interface */
+static void cleanup( void )
+{
+ BTVNDDBG("cleanup");
+
+ if (lib_running)
+ {
+ lib_running = 0;
+ btvnd_signal_event(VND_EVENT_EXIT);
+ pthread_join(worker_thread, NULL);
+ }
+
+ userial_close();
+ hci_h4_cleanup();
+ upio_cleanup();
+ utils_cleanup();
+
+ bt_vendor_cbacks = NULL;
+}
+
+
+static const bt_vendor_interface_t bluetoothVendorLibInterface = {
+ sizeof(bt_vendor_interface_t),
+ init,
+ set_power,
+ lpm,
+ preload,
+ postload,
+ transmit_buf,
+ set_rxflow,
+ cleanup
+};
+
+
+/*******************************************************************************
+**
+** Function bt_vndor_worker_thread
+**
+** Description Mian worker thread
+**
+** Returns void *
+**
+*******************************************************************************/
+static void *bt_vndor_worker_thread(void *arg)
+{
+ uint16_t events;
+ VND_BT_HDR *p_msg, *p_next_msg;
+
+ BTVNDDBG("bt_vndor_worker_thread started");
+ tx_cmd_pkts_pending = FALSE;
+
+ while (lib_running)
+ {
+ pthread_mutex_lock(&vnd_mutex);
+ while (ready_events == 0)
+ {
+ pthread_cond_wait(&vnd_cond, &vnd_mutex);
+ }
+ events = ready_events;
+ ready_events = 0;
+ pthread_mutex_unlock(&vnd_mutex);
+
+ if (events & VND_EVENT_RX)
+ {
+ hci_h4_receive_msg();
+
+ if ((tx_cmd_pkts_pending == TRUE) && (num_hci_cmd_pkts > 0))
+ {
+ /* Got HCI Cmd Credits from Controller.
+ * Prepare to send prior pending Cmd packets in the
+ * following VND_EVENT_TX session.
+ */
+ events |= VND_EVENT_TX;
+ }
+ }
+
+ if (events & VND_EVENT_PRELOAD)
+ {
+ userial_open(USERIAL_PORT_1, (tUSERIAL_CFG *) &userial_init_cfg);
+ hw_config_start();
+ }
+
+ if (events & VND_EVENT_POSTLOAD)
+ {
+ /* Start from SCO related H/W configuration, if SCO configuration
+ * is required. Then, follow with reading requests of getting
+ * ACL data length for both BR/EDR and LE.
+ */
+#if (SCO_CFG_INCLUDED == TRUE)
+ hw_sco_config();
+#else
+ hci_h4_get_acl_data_length();
+#endif
+ }
+
+ if (events & VND_EVENT_TX)
+ {
+ /*
+ * We will go through every packets in the tx queue.
+ * Fine to clear tx_cmd_pkts_pending.
+ */
+ tx_cmd_pkts_pending = FALSE;
+
+ p_next_msg = tx_q.p_first;
+ while (p_next_msg)
+ {
+ if ((p_next_msg->event & MSG_EVT_MASK) == MSG_STACK_TO_VND_HCI_CMD)
+ {
+ /*
+ * if we have used up controller's outstanding HCI command credits
+ * (normally is 1), skip all HCI command packets in the queue.
+ * The pending command packets will be sent once controller gives
+ * back us credits through CommandCompleteEvent or CommandStatusEvent.
+ */
+ if ((tx_cmd_pkts_pending == TRUE) || (num_hci_cmd_pkts <= 0))
+ {
+ tx_cmd_pkts_pending = TRUE;
+ p_next_msg = utils_getnext(p_next_msg);
+ continue;
+ }
+ }
+
+ p_msg = p_next_msg;
+ p_next_msg = utils_getnext(p_msg);
+ utils_remove_from_queue(&tx_q, p_msg);
+ hci_h4_send_msg(p_msg);
+ }
+
+ if (tx_cmd_pkts_pending == TRUE)
+ BTVNDDBG("Used up Tx Cmd credits");
+
+ }
+
+ if (events & VND_EVENT_LPM_ENABLE)
+ {
+ hw_lpm_enable(TRUE);
+ }
+
+ if (events & VND_EVENT_LPM_DISABLE)
+ {
+ hw_lpm_enable(FALSE);
+ }
+
+ if (events & VND_EVENT_LPM_IDLE_TIMEOUT)
+ {
+ hw_lpm_deassert_bt_wake();
+ }
+
+ if (events & VND_EVENT_LPM_ALLOW_SLEEP)
+ {
+ hw_lpm_allow_bt_device_sleep();
+ }
+
+ if (events & VND_EVENT_LPM_WAKE_DEVICE)
+ {
+ hw_lpm_assert_bt_wake();
+ }
+
+ if (events & VND_EVENT_EXIT)
+ break;
+ }
+
+ BTVNDDBG("bt_vndor_worker_thread exiting");
+
+ pthread_exit(NULL);
+
+ return NULL; // compiler friendly
+}
+
+
+/*******************************************************************************
+**
+** Function bt_vendor_get_interface
+**
+** Description Caller calls this function to get API instance
+**
+** Returns API table
+**
+*******************************************************************************/
+const bt_vendor_interface_t *bt_vendor_get_interface(void)
+{
+ return &bluetoothVendorLibInterface;
+}
+
+
+
diff --git a/vendor/libvendor/src/btsnoop.c b/vendor/libvendor/src/btsnoop.c
new file mode 100644
index 0000000..a0476b4
--- /dev/null
+++ b/vendor/libvendor/src/btsnoop.c
@@ -0,0 +1,721 @@
+/************************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+/****************************************************************************
+ *
+ * Name: btsnoopdisp.c
+ *
+ * Function: this file contains functions to generate a BTSNOOP file
+ *
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+/* for gettimeofday */
+#include <sys/time.h>
+/* for the S_* open parameters */
+#include <sys/stat.h>
+/* for write */
+#include <unistd.h>
+/* for O_* open parameters */
+#include <fcntl.h>
+/* defines the O_* open parameters */
+#include <fcntl.h>
+
+#define LOG_TAG "BTSNOOP-DISP"
+#include <cutils/log.h>
+
+#include "bt_vendor_brcm.h"
+#include "utils.h"
+
+#ifndef BTSNOOP_DBG
+#define BTSNOOP_DBG FALSE
+#endif
+
+#if (BTSNOOP_DBG == TRUE)
+#define SNOOPDBG LOGD
+#else
+#define SNOOPDBG
+#endif
+
+/* file descriptor of the BT snoop file (by default, -1 means disabled) */
+int hci_btsnoop_fd = -1;
+
+#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
+
+/* if not specified in .txt file then use this as default */
+#ifndef BTSNOOP_FILENAME
+
+//#define BTSNOOP_FILENAME "/sdcard/snoop_log.cfa"
+#error "BTSNOOP_FILENAME needs to be defined in vnd_buildcfg.h"
+
+#endif /* BTSNOOP_FILENAME */
+
+#endif /* BTSNOOPDISP_INCLUDED */
+
+/* Macro to perform a multiplication of 2 unsigned 32bit values and store the result
+ * in an unsigned 64 bit value (as two 32 bit variables):
+ * u64 = u32In1 * u32In2
+ * u32OutLow = u64[31:0]
+ * u32OutHi = u64[63:32]
+ * basically the algorithm:
+ * (hi1*2^16 + lo1)*(hi2*2^16 + lo2) = lo1*lo2 + (hi1*hi2)*2^32 + (hi1*lo2 + hi2*lo1)*2^16
+ * and the carry is propagated 16 bit by 16 bit:
+ * result[15:0] = lo1*lo2 & 0xFFFF
+ * result[31:16] = ((lo1*lo2) >> 16) + (hi1*lo2 + hi2*lo1)
+ * and so on
+ */
+#define HCIDISP_MULT_64(u32In1, u32In2, u32OutLo, u32OutHi) \
+do { \
+ uint32_t u32In1Tmp = u32In1; \
+ uint32_t u32In2Tmp = u32In2; \
+ uint32_t u32Tmp, u32Carry; \
+ u32OutLo = (u32In1Tmp & 0xFFFF) * (u32In2Tmp & 0xFFFF); /*lo1*lo2*/ \
+ u32OutHi = ((u32In1Tmp >> 16) & 0xFFFF) * ((u32In2Tmp >> 16) & 0xFFFF); /*hi1*hi2*/ \
+ u32Tmp = (u32In1Tmp & 0xFFFF) * ((u32In2Tmp >> 16) & 0xFFFF); /*lo1*hi2*/ \
+ u32Carry = (uint32_t)((u32OutLo>>16)&0xFFFF); \
+ u32Carry += (u32Tmp&0xFFFF); \
+ u32OutLo += (u32Tmp << 16) ; \
+ u32OutHi += (u32Tmp >> 16); \
+ u32Tmp = ((u32In1Tmp >> 16) & 0xFFFF) * (u32In2Tmp & 0xFFFF); \
+ u32Carry += (u32Tmp)&0xFFFF; \
+ u32Carry>>=16; \
+ u32OutLo += (u32Tmp << 16); \
+ u32OutHi += (u32Tmp >> 16); \
+ u32OutHi += u32Carry; \
+} while (0)
+
+/* Macro to make an addition of 2 64 bit values:
+ * result = (u32OutHi & u32OutLo) + (u32InHi & u32InLo)
+ * u32OutHi = result[63:32]
+ * u32OutLo = result[31:0]
+ */
+#define HCIDISP_ADD_64(u32InLo, u32InHi, u32OutLo, u32OutHi) \
+do { \
+ (u32OutLo) += (u32InLo); \
+ if ((u32OutLo) < (u32InLo)) (u32OutHi)++; \
+ (u32OutHi) += (u32InHi); \
+} while (0)
+
+/* EPOCH in microseconds since 01/01/0000 : 0x00dcddb3.0f2f8000 */
+#define BTSNOOP_EPOCH_HI 0x00dcddb3U
+#define BTSNOOP_EPOCH_LO 0x0f2f8000U
+
+/*******************************************************************************
+ **
+ ** Function tv_to_btsnoop_ts
+ **
+ ** Description This function generate a BT Snoop timestamp.
+ **
+ ** Returns void
+ **
+ ** NOTE
+ ** The return value is 64 bit as 2 32 bit variables out_lo and * out_hi.
+ ** A BT Snoop timestamp is the number of microseconds since 01/01/0000.
+ ** The timeval structure contains the number of microseconds since EPOCH
+ ** (01/01/1970) encoded as: tv.tv_sec, number of seconds since EPOCH and
+ ** tv_usec, number of microseconds in current second
+ **
+ ** Therefore the algorithm is:
+ ** result = tv.tv_sec * 1000000
+ ** result += tv.tv_usec
+ ** result += EPOCH_OFFSET
+ *******************************************************************************/
+static void tv_to_btsnoop_ts(uint32_t *out_lo, uint32_t *out_hi, struct timeval *tv)
+{
+ /* multiply the seconds by 1000000 */
+ HCIDISP_MULT_64(tv->tv_sec, 0xf4240, *out_lo, *out_hi);
+
+ /* add the microseconds */
+ HCIDISP_ADD_64((uint32_t)tv->tv_usec, 0, *out_lo, *out_hi);
+
+ /* add the epoch */
+ HCIDISP_ADD_64(BTSNOOP_EPOCH_LO, BTSNOOP_EPOCH_HI, *out_lo, *out_hi);
+}
+
+/*******************************************************************************
+ **
+ ** Function l_to_be
+ **
+ ** Description Function to convert a 32 bit value into big endian format
+ **
+ ** Returns 32 bit value in big endian format
+*******************************************************************************/
+static uint32_t l_to_be(uint32_t x)
+{
+ #if __BIG_ENDIAN != TRUE
+ x = (x >> 24) |
+ ((x >> 8) & 0xFF00) |
+ ((x << 8) & 0xFF0000) |
+ (x << 24);
+ #endif
+ return x;
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_is_open
+ **
+ ** Description Function to check if BTSNOOP is open
+ **
+ ** Returns 1 if open otherwise 0
+*******************************************************************************/
+int btsnoop_is_open(void)
+{
+#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
+ SNOOPDBG("btsnoop_is_open: snoop fd = %d\n", hci_btsnoop_fd);
+
+ if (hci_btsnoop_fd != -1)
+ {
+ return 1;
+ }
+ return 0;
+#else
+ return 2; /* Snoop not available */
+#endif
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_log_open
+ **
+ ** Description Function to open the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+static int btsnoop_log_open(void)
+{
+#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
+ hci_btsnoop_fd = -1;
+
+ SNOOPDBG("btsnoop_log_open: snoop log file = %s\n", BTSNOOP_FILENAME);
+
+ /* write the BT snoop header */
+ if (BTSNOOP_FILENAME != NULL)
+ {
+ hci_btsnoop_fd = open((char*)BTSNOOP_FILENAME, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if (hci_btsnoop_fd == -1)
+ {
+ perror("open");
+ SNOOPDBG("btsnoop_log_open: Unable to open snoop log file\n");
+ hci_btsnoop_fd = -1;
+ return 0;
+ }
+ write(hci_btsnoop_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
+ return 1;
+ }
+#else
+ return 2; /* Snoop not available */
+#endif
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_log_close
+ **
+ ** Description Function to close the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+static int btsnoop_log_close(void)
+{
+#if defined(BTSNOOPDISP_INCLUDED) && (BTSNOOPDISP_INCLUDED == TRUE)
+ /* write the BT snoop header */
+ if (hci_btsnoop_fd != -1)
+ {
+ SNOOPDBG("btsnoop_log_close: Closing snoop log file\n");
+ close(hci_btsnoop_fd);
+ hci_btsnoop_fd = -1;
+ return 1;
+ }
+ return 0;
+#else
+ return 2; /* Snoop not available */
+#endif
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_hci_cmd
+ **
+ ** Description Function to add a command in the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+void btsnoop_hci_cmd(uint8_t *p)
+{
+ SNOOPDBG("btsnoop_hci_cmd: fd = %d", hci_btsnoop_fd);
+
+ if (hci_btsnoop_fd != -1)
+ {
+ uint32_t value, value_hi;
+ struct timeval tv;
+
+ /* since these display functions are called from different contexts */
+ utils_lock();
+
+ /* store the length in both original and included fields */
+ value = l_to_be(p[2] + 4);
+ write(hci_btsnoop_fd, &value, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* flags: command sent from the host */
+ value = l_to_be(2);
+ write(hci_btsnoop_fd, &value, 4);
+ /* drops: none */
+ value = 0;
+ write(hci_btsnoop_fd, &value, 4);
+ /* time */
+ gettimeofday(&tv, NULL);
+ tv_to_btsnoop_ts(&value, &value_hi, &tv);
+ value_hi = l_to_be(value_hi);
+ value = l_to_be(value);
+ write(hci_btsnoop_fd, &value_hi, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* data */
+ write(hci_btsnoop_fd, "\x1", 1);
+ write(hci_btsnoop_fd, p, p[2] + 3);
+
+ /* since these display functions are called from different contexts */
+ utils_unlock();
+ }
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_hci_evt
+ **
+ ** Description Function to add a event in the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+void btsnoop_hci_evt(uint8_t *p)
+{
+ SNOOPDBG("btsnoop_hci_evt: fd = %d", hci_btsnoop_fd);
+
+ if (hci_btsnoop_fd != -1)
+ {
+ uint32_t value, value_hi;
+ struct timeval tv;
+
+ /* since these display functions are called from different contexts */
+ utils_lock();
+
+ /* store the length in both original and included fields */
+ value = l_to_be(p[1] + 3);
+ write(hci_btsnoop_fd, &value, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* flags: event received in the host */
+ value = l_to_be(3);
+ write(hci_btsnoop_fd, &value, 4);
+ /* drops: none */
+ value = 0;
+ write(hci_btsnoop_fd, &value, 4);
+ /* time */
+ gettimeofday(&tv, NULL);
+ tv_to_btsnoop_ts(&value, &value_hi, &tv);
+ value_hi = l_to_be(value_hi);
+ value = l_to_be(value);
+ write(hci_btsnoop_fd, &value_hi, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* data */
+ write(hci_btsnoop_fd, "\x4", 1);
+ write(hci_btsnoop_fd, p, p[1] + 2);
+
+ /* since these display functions are called from different contexts */
+ utils_unlock();
+ }
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_sco_data
+ **
+ ** Description Function to add a SCO data packet in the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+void btsnoop_sco_data(uint8_t *p, uint8_t is_rcvd)
+{
+ SNOOPDBG("btsnoop_sco_data: fd = %d", hci_btsnoop_fd);
+
+ if (hci_btsnoop_fd != -1)
+ {
+ uint32_t value, value_hi;
+ struct timeval tv;
+
+ /* since these display functions are called from different contexts */
+ utils_lock();
+
+ /* store the length in both original and included fields */
+ value = l_to_be(p[2] + 4);
+ write(hci_btsnoop_fd, &value, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* flags: data can be sent or received */
+ value = l_to_be(is_rcvd?1:0);
+ write(hci_btsnoop_fd, &value, 4);
+ /* drops: none */
+ value = 0;
+ write(hci_btsnoop_fd, &value, 4);
+ /* time */
+ gettimeofday(&tv, NULL);
+ tv_to_btsnoop_ts(&value, &value_hi, &tv);
+ value_hi = l_to_be(value_hi);
+ value = l_to_be(value);
+ write(hci_btsnoop_fd, &value_hi, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* data */
+ write(hci_btsnoop_fd, "\x3", 1);
+ write(hci_btsnoop_fd, p, p[2] + 3);
+
+ /* since these display functions are called from different contexts */
+ utils_unlock();
+ }
+}
+
+/*******************************************************************************
+ **
+ ** Function btsnoop_acl_data
+ **
+ ** Description Function to add an ACL data packet in the BTSNOOP file
+ **
+ ** Returns None
+*******************************************************************************/
+void btsnoop_acl_data(uint8_t *p, uint8_t is_rcvd)
+{
+ SNOOPDBG("btsnoop_acl_data: fd = %d", hci_btsnoop_fd);
+ if (hci_btsnoop_fd != -1)
+ {
+ uint32_t value, value_hi;
+ struct timeval tv;
+
+ /* since these display functions are called from different contexts */
+ utils_lock();
+
+ /* store the length in both original and included fields */
+ value = l_to_be((p[3]<<8) + p[2] + 5);
+ write(hci_btsnoop_fd, &value, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* flags: data can be sent or received */
+ value = l_to_be(is_rcvd?1:0);
+ write(hci_btsnoop_fd, &value, 4);
+ /* drops: none */
+ value = 0;
+ write(hci_btsnoop_fd, &value, 4);
+ /* time */
+ gettimeofday(&tv, NULL);
+ tv_to_btsnoop_ts(&value, &value_hi, &tv);
+ value_hi = l_to_be(value_hi);
+ value = l_to_be(value);
+ write(hci_btsnoop_fd, &value_hi, 4);
+ write(hci_btsnoop_fd, &value, 4);
+ /* data */
+ write(hci_btsnoop_fd, "\x2", 1);
+ write(hci_btsnoop_fd, p, (p[3]<<8) + p[2] + 4);
+
+ /* since these display functions are called from different contexts */
+ utils_unlock();
+ }
+}
+
+
+/********************************************************************************
+ ** API allow external realtime parsing of output using e.g hcidump
+ *********************************************************************************/
+
+#define EXT_PARSER_PORT 4330
+
+static pthread_t thread_id;
+static int s_listen = -1;
+static int ext_parser_fd = -1;
+
+static void ext_parser_detached(void);
+
+int ext_parser_accept(int port)
+{
+ socklen_t clilen;
+ struct sockaddr_in cliaddr, servaddr;
+ int s, srvlen;
+ int n = 1;
+ int size_n;
+ int result = 0;
+
+ LOGD("waiting for connection on port %d", port);
+
+ s_listen = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (s_listen < 0)
+ {
+ LOGE("listener not created: listen fd %d", s_listen);
+ return -1;
+ }
+
+ bzero(&servaddr, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servaddr.sin_port = htons(port);
+
+ srvlen = sizeof(servaddr);
+
+ /* allow reuse of sock addr upon bind */
+ result = setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (result<0)
+ {
+ perror("setsockopt");
+ }
+
+ result = bind(s_listen, (struct sockaddr *) &servaddr, srvlen);
+
+ if (result < 0)
+ perror("bind");
+
+ result = listen(s_listen, 1);
+
+ if (result < 0)
+ perror("listen");
+
+ clilen = sizeof(struct sockaddr_in);
+
+ s = accept(s_listen, (struct sockaddr *) &cliaddr, &clilen);
+
+ if (s < 0)
+{
+ perror("accept");
+ return -1;
+ }
+
+ LOGD("connected (%d)", s);
+
+ return s;
+}
+
+static int send_ext_parser(char *p, int len)
+{
+ int n;
+
+ /* check if io socket is connected */
+ if (ext_parser_fd == -1)
+ return 0;
+
+ SNOOPDBG("write %d to snoop socket\n", len);
+
+ n = write(ext_parser_fd, p, len);
+
+ if (n<=0)
+ {
+ ext_parser_detached();
+ }
+
+ return n;
+}
+
+static void ext_parser_detached(void)
+{
+ LOGD("ext parser detached");
+
+ if (ext_parser_fd>0)
+ close(ext_parser_fd);
+
+ if (s_listen > 0)
+ close(s_listen);
+
+ ext_parser_fd = -1;
+ s_listen = -1;
+}
+
+static void interruptFn (int sig)
+{
+ LOGD("interruptFn");
+ pthread_exit(0);
+}
+
+static void ext_parser_thread(void* param)
+{
+ int fd;
+ int sig = SIGUSR2;
+ sigset_t sigSet;
+ sigemptyset (&sigSet);
+ sigaddset (&sigSet, sig);
+
+ LOGD("ext_parser_thread");
+
+ prctl(PR_SET_NAME, (unsigned long)"BtsnoopExtParser", 0, 0, 0);
+
+ pthread_sigmask (SIG_UNBLOCK, &sigSet, NULL);
+
+ struct sigaction act;
+ act.sa_handler = interruptFn;
+ sigaction (sig, &act, NULL );
+
+ do
+ {
+ fd = ext_parser_accept(EXT_PARSER_PORT);
+
+ ext_parser_fd = fd;
+
+ LOGD("ext parser attached on fd %d\n", ext_parser_fd);
+ } while (1);
+}
+
+void btsnoop_stop_listener(void)
+{
+ LOGD("btsnoop_init");
+ ext_parser_detached();
+}
+
+void btsnoop_init(void)
+{
+ LOGD("btsnoop_init");
+
+ /* always setup ext listener port */
+ if (pthread_create(&thread_id, NULL,
+ (void*)ext_parser_thread,NULL)!=0)
+ perror("pthread_create");
+}
+
+void btsnoop_open(void)
+{
+ LOGD("btsnoop_open");
+ btsnoop_log_open();
+}
+
+void btsnoop_close(void)
+{
+ LOGD("btsnoop_close");
+ btsnoop_log_close();
+}
+
+void btsnoop_cleanup (void)
+{
+ LOGD("btsnoop_cleanup");
+ pthread_kill(thread_id, SIGUSR2);
+ pthread_join(thread_id, NULL);
+ ext_parser_detached();
+}
+
+
+#define HCIT_TYPE_COMMAND 1
+#define HCIT_TYPE_ACL_DATA 2
+#define HCIT_TYPE_SCO_DATA 3
+#define HCIT_TYPE_EVENT 4
+
+void btsnoop_capture(VND_BT_HDR *p_buf, uint8_t is_rcvd)
+{
+ uint8_t *p = (uint8_t *)(p_buf + 1) + p_buf->offset;
+
+ SNOOPDBG("btsnoop_capture: fd = %d, type %x, rcvd %d, ext %d", hci_btsnoop_fd, p_buf->event, is_rcvd, ext_parser_fd);
+
+ if (ext_parser_fd > 0)
+ {
+ uint8_t tmp = *p;
+
+ /* borrow one byte for H4 packet type indicator */
+ p--;
+
+ switch (p_buf->event & MSG_EVT_MASK)
+ {
+ case MSG_VND_TO_STACK_HCI_EVT:
+ *p = HCIT_TYPE_EVENT;
+ break;
+ case MSG_VND_TO_STACK_HCI_ACL:
+ case MSG_STACK_TO_VND_HCI_ACL:
+ *p = HCIT_TYPE_ACL_DATA;
+ break;
+ case MSG_VND_TO_STACK_HCI_SCO:
+ case MSG_STACK_TO_VND_HCI_SCO:
+ *p = HCIT_TYPE_SCO_DATA;
+ break;
+ case MSG_STACK_TO_VND_HCI_CMD:
+ *p = HCIT_TYPE_COMMAND;
+ break;
+ }
+
+ send_ext_parser((char*)p, p_buf->len+1);
+ *(++p) = tmp;
+ return;
+ }
+
+ if (hci_btsnoop_fd == -1)
+ return;
+
+ switch (p_buf->event & MSG_EVT_MASK)
+ {
+ case MSG_VND_TO_STACK_HCI_EVT:
+ SNOOPDBG("TYPE : EVT");
+ btsnoop_hci_evt(p);
+ break;
+ case MSG_VND_TO_STACK_HCI_ACL:
+ case MSG_STACK_TO_VND_HCI_ACL:
+ SNOOPDBG("TYPE : ACL");
+ btsnoop_acl_data(p, is_rcvd);
+ break;
+ case MSG_VND_TO_STACK_HCI_SCO:
+ case MSG_STACK_TO_VND_HCI_SCO:
+ SNOOPDBG("TYPE : SCO");
+ btsnoop_sco_data(p, is_rcvd);
+ break;
+ case MSG_STACK_TO_VND_HCI_CMD:
+ SNOOPDBG("TYPE : CMD");
+ btsnoop_hci_cmd(p);
+ break;
+ }
+}
+
+
diff --git a/vendor/libvendor/src/hardware.c b/vendor/libvendor/src/hardware.c
new file mode 100644
index 0000000..de2bc1e
--- /dev/null
+++ b/vendor/libvendor/src/hardware.c
@@ -0,0 +1,1012 @@
+/************************************************************************************
+ *
+ * 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: hardware.c
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_hw"
+
+#include <utils/Log.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <time.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include "bt_vendor_brcm.h"
+#include "userial.h"
+#include "utils.h"
+#include "upio.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef BTHW_DBG
+#define BTHW_DBG FALSE
+#endif
+
+#if (BTHW_DBG == TRUE)
+#define BTHWDBG LOGD
+#else
+#define BTHWDBG
+#endif
+
+#define FW_PATCHFILE_EXTENSION ".hcd"
+#define FW_PATCHFILE_EXTENSION_LEN 4
+#define FW_PATCHFILE_PATH_MAXLEN 248 /* Local_Name length of return of HCI_Read_Local_Name */
+
+#define HCI_CMD_MAX_LEN 258
+
+#define HCI_RESET 0x0C03
+#define HCI_VSC_WRITE_UART_CLOCK_SETTING 0xFC45
+#define HCI_VSC_UPDATE_BAUDRATE 0xFC18
+#define HCI_READ_LOCAL_NAME 0x0C14
+#define HCI_VSC_DOWNLOAD_MINIDRV 0xFC2E
+#define HCI_VSC_WRITE_BD_ADDR 0xFC01
+#define HCI_VSC_WRITE_SLEEP_MODE 0xFC27
+#define HCI_VSC_WRITE_SCO_PCM_INT_PARAM 0xFC1C
+#define HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM 0xFC1E
+#define HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM 0xFC6D
+
+#define LPM_CMD_PARAMETER_LEN 12
+
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/* Hardware Configuration State */
+enum {
+ HW_CFG_START = 1,
+ HW_CFG_SET_UART_CLOCK,
+ HW_CFG_SET_UART_BAUD_1,
+ HW_CFG_READ_LOCAL_NAME,
+ HW_CFG_DL_MINIDRIVER,
+ HW_CFG_DL_FW_PATCH,
+ HW_CFG_SET_UART_BAUD_2,
+ HW_CFG_SET_BD_ADDR
+};
+
+/* low power mode parameters */
+typedef struct
+{
+ uint8_t sleep_mode; /* Sleep Mode 0(disable),1(UART),9(H5) */
+ uint8_t host_stack_idle_threshold; /* Host Idle Treshold in 300ms/25ms if mode = 1 */
+ uint8_t host_controller_idle_threshold; /* Host Controller Idle Treshold in 300ms/25ms if mode = 1,9 */
+ uint8_t bt_wake_polarity; /* BT_WAKE Polarity - 0=Active Low, 1= Active High if mode = 1 */
+ uint8_t host_wake_polarity; /* HOST_WAKE Polarity - 0=Active Low, 1= Active High if mode = 1 */
+ uint8_t allow_host_sleep_during_sco; /* Allow host Sleep during SCO if mode = 1 */
+ uint8_t combine_sleep_mode_and_lpm; /* Combine Sleep Mode and LPM if mode = 1 */
+ uint8_t enable_uart_txd_tri_state; /* UART_TXD Tri-State if mode = 1 */
+ uint8_t sleep_guard_time; /* sleep guard time in 12.5ms */
+ uint8_t wakeup_guard_time; /* wakeup guard time in 12.5ms */
+ uint8_t txd_config; /* TXD is high in sleep state */
+ uint8_t pulsed_host_wake; /* pulsed host wake if mode = 1 */
+} bt_lpm_param_t;
+
+enum {
+ HW_LPM_DISABLED = 0, /* initial state */
+ HW_LPM_ENABLED,
+ HW_LPM_ENABLING,
+ HW_LPM_DISABLING
+};
+
+enum {
+ LPM_BTWAKE_DEASSERTED = 0, /* initial state */
+ LPM_BTWAKE_W4_TX_DONE,
+ LPM_BTWAKE_W4_TIMEOUT,
+ LPM_BTWAKE_ASSERTED
+};
+
+/* low power mode control block */
+typedef struct
+{
+ uint8_t state; /* DISABLED, ENABLED, ENABLING, DISABLING */
+ uint8_t btwake_state; /* ASSERTED, W4_TX_DONE, W4_TIMEOUT, DEASSERTED */
+ uint8_t no_tx_data;
+ uint8_t timer_created;
+ timer_t timer_id;
+ uint32_t timeout_ms; /* 10 times of the chip unit */
+} bt_lpm_cb_t;
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+/* Callback function for the returned event of internal issued command */
+typedef void (*tINT_CMD_CBACK)(VND_BT_HDR *p_buf);
+uint8_t hci_h4_send_int_cmd(uint16_t opcode, VND_BT_HDR *p_buf, tINT_CMD_CBACK p_cback);
+void hci_h4_get_acl_data_length(void);
+
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+static uint8_t hw_cfg_state = 0;
+static int fw_fd = -1;
+static uint8_t f_set_baud_2 = FALSE;
+static uint8_t local_bd_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static const uint8_t null_bdaddr[6] = {0,0,0,0,0,0};
+static char local_chip_name[32];
+static bt_lpm_cb_t hw_lpm_cb;
+
+static bt_lpm_param_t lpm_param =
+{
+ LPM_SLEEP_MODE,
+ LPM_IDLE_THRESHOLD,
+ LPM_HC_IDLE_THRESHOLD,
+ LPM_BT_WAKE_POLARITY,
+ LPM_HOST_WAKE_POLARITY,
+ LPM_ALLOW_HOST_SLEEP_DURING_SCO,
+ LPM_COMBINE_SLEEP_MODE_AND_LPM,
+ LPM_ENABLE_UART_TXD_TRI_STATE,
+ 0, /* not applicable */
+ 0, /* not applicable */
+ 0, /* not applicable */
+ LPM_PULSED_HOST_WAKE
+};
+
+#if (SCO_USE_I2S_INTERFACE == FALSE)
+static uint8_t bt_sco_param[SCO_PCM_PARAM_SIZE] =
+{
+ SCO_PCM_ROUTING,
+ SCO_PCM_IF_CLOCK_RATE,
+ SCO_PCM_IF_FRAME_TYPE,
+ SCO_PCM_IF_SYNC_MODE,
+ SCO_PCM_IF_CLOCK_MODE
+};
+
+static uint8_t bt_pcm_data_fmt_param[PCM_DATA_FORMAT_PARAM_SIZE] =
+{
+ PCM_DATA_FMT_SHIFT_MODE,
+ PCM_DATA_FMT_FILL_BITS,
+ PCM_DATA_FMT_FILL_METHOD,
+ PCM_DATA_FMT_FILL_NUM,
+ PCM_DATA_FMT_JUSTIFY_MODE
+};
+#else
+static uint8_t bt_sco_param[SCO_I2SPCM_PARAM_SIZE] =
+{
+ SCO_I2SPCM_IF_MODE,
+ SCO_I2SPCM_IF_ROLE,
+ SCO_I2SPCM_IF_SAMPLE_RATE,
+ SCO_I2SPCM_IF_CLOCK_RATE
+};
+#endif
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/*****************************************************************************
+** Controller Initialization Static Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function hw_config_findpatch
+**
+** Description Search for a proper firmware patch file
+** The selected firmware patch file name with full path
+** will be stored in the input string parameter, i.e.
+** p_chip_id_str, when returns.
+**
+** Returns TRUE when found the target patch file, otherwise FALSE
+**
+*******************************************************************************/
+uint8_t hw_config_findpatch(char *p_chip_id_str)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ int filenamelen;
+ uint8_t retval = FALSE;
+
+ BTHWDBG("Chip-name = [%s]", p_chip_id_str);
+
+ if ((dirp = opendir(FW_PATCHFILE_LOCATION)) != NULL)
+ {
+ /* Fetch next filename in patchfile directory */
+ while ((dp = readdir(dirp)) != NULL)
+ {
+ /* Check if filename starts with chip-id name */
+ if ((strncmp(dp->d_name, p_chip_id_str, strlen(p_chip_id_str))) == 0)
+ {
+ /* Check if it has .hcd extenstion */
+ filenamelen = strlen(dp->d_name);
+ if ((filenamelen >= FW_PATCHFILE_EXTENSION_LEN) &&
+ ((strncmp(&dp->d_name[filenamelen-FW_PATCHFILE_EXTENSION_LEN], FW_PATCHFILE_EXTENSION, FW_PATCHFILE_EXTENSION_LEN)) == 0))
+ {
+ LOGI("Found patchfile: %s/%s", FW_PATCHFILE_LOCATION, dp->d_name);
+
+ /* Make sure length does not exceed maximum */
+ if ((filenamelen + strlen(FW_PATCHFILE_LOCATION)) > FW_PATCHFILE_PATH_MAXLEN)
+ {
+ LOGE("Invalid patchfile name (too long)");
+ }
+ else
+ {
+ memset(p_chip_id_str, 0, FW_PATCHFILE_PATH_MAXLEN);
+ /* Found patchfile. Store location and name */
+ strcpy(p_chip_id_str, FW_PATCHFILE_LOCATION);
+ if (FW_PATCHFILE_LOCATION[strlen(FW_PATCHFILE_LOCATION) - 1] != '/')
+ strcat(p_chip_id_str, "/");
+ strcat(p_chip_id_str, dp->d_name);
+ retval = TRUE;
+ }
+ break;
+ }
+ }
+ }
+ closedir(dirp);
+ }
+ else
+ {
+ LOGE("Could not open %s", FW_PATCHFILE_LOCATION);
+ }
+
+ return (retval);
+}
+
+/*******************************************************************************
+**
+** Function hw_config_cback
+**
+** Description Callback function for controller configuration
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_config_cback(VND_BT_HDR *p_evt_buf)
+{
+ char *p_name;
+ uint8_t *p, status;
+ uint16_t opcode;
+ VND_BT_HDR *p_buf=NULL;
+
+ status = *((uint8_t *)(p_evt_buf + 1) + 5);
+
+ /* Ask a new buffer big enough to hold any HCI commands sent in here */
+ if ((status == 0) && bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE+HCI_CMD_MAX_LEN);
+
+ if ((status != 0) || (p_buf == NULL))
+ {
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_evt_buf, (char *) (p_evt_buf + 1));
+ LOGE("vendor lib preload aborted [no buffer]");
+ bt_vendor_cbacks->preload_cb(NULL, BT_VENDOR_PRELOAD_FAIL);
+ }
+
+ hw_cfg_state = 0;
+ return;
+ }
+
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->len = 0;
+ p_buf->layer_specific = 0;
+
+ p = (uint8_t *) (p_buf + 1);
+
+ switch (hw_cfg_state)
+ {
+ case HW_CFG_SET_UART_BAUD_1:
+ /* update baud rate of host's UART port */
+ userial_change_baud(USERIAL_BAUD_3M);
+
+ /* read local name */
+ UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
+ *p = 0; /* parameter length */
+
+ p_buf->len = 3;
+ hw_cfg_state = HW_CFG_READ_LOCAL_NAME;
+
+ hci_h4_send_int_cmd(HCI_READ_LOCAL_NAME, p_buf, hw_config_cback);
+ break;
+
+ case HW_CFG_READ_LOCAL_NAME:
+ p_name = (char *) (p_evt_buf + 1) + 6;
+ strncpy(local_chip_name, p_name, 15);
+ local_chip_name[15] = 0;
+ if ((status = hw_config_findpatch(p_name)) == TRUE)
+ {
+ if ((fw_fd = open(p_name, O_RDONLY)) == -1)
+ {
+ LOGE("vendor lib preload aborted [Failed to open %s]", p_name);
+ bt_vendor_cbacks->preload_cb(NULL, BT_VENDOR_PRELOAD_FAIL);
+ hw_cfg_state = 0;
+ }
+ else
+ {
+ /* vsc_download_minidriver */
+ UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
+ *p = 0; /* parameter length */
+
+ p_buf->len = 3;
+ hw_cfg_state = HW_CFG_DL_MINIDRIVER;
+
+ hci_h4_send_int_cmd(HCI_VSC_DOWNLOAD_MINIDRV, p_buf, hw_config_cback);
+ }
+ }
+ else
+ {
+ LOGE("vendor lib preload aborted [Failed to locate firmware patch file]");
+ bt_vendor_cbacks->preload_cb(NULL, BT_VENDOR_PRELOAD_FAIL);
+ hw_cfg_state = 0;
+ }
+ break;
+
+ case HW_CFG_DL_MINIDRIVER:
+ /* give time for placing firmware in download mode */
+ utils_delay(50);
+ hw_cfg_state = HW_CFG_DL_FW_PATCH;
+ /* fall through intentionally */
+ case HW_CFG_DL_FW_PATCH:
+ p_buf->len = read(fw_fd, p, 3);
+ if (p_buf->len > 0)
+ {
+ p_buf->len += read(fw_fd, p+3, *(p+2));
+ STREAM_TO_UINT16(opcode,p);
+ hci_h4_send_int_cmd(opcode, p_buf, hw_config_cback);
+ break;
+ }
+
+ close(fw_fd);
+ fw_fd = -1;
+
+ /* Normally the firmware patch configuration file
+ * sets the new starting baud rate at 115200.
+ * So, we need update host's baud rate accordingly.
+ */
+ userial_change_baud(USERIAL_BAUD_115200);
+
+ /* Next, we would like to boost baud rate up again
+ * to desired working speed.
+ */
+ f_set_baud_2 = TRUE;
+
+ /* fall through intentionally */
+ case HW_CFG_START:
+ if (UART_TARGET_BAUD_RATE > 3000000)
+ {
+ /* set UART clock to 48MHz */
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
+ *p++ = 1; /* parameter length */
+ *p = 1; /* (1, "UART CLOCK 48 MHz")(2, "UART CLOCK 24 MHz") */
+
+ p_buf->len = 4;
+ hw_cfg_state = HW_CFG_SET_UART_CLOCK;
+
+ hci_h4_send_int_cmd(HCI_VSC_WRITE_UART_CLOCK_SETTING, p_buf, hw_config_cback);
+ break;
+ }
+ /* fall through intentionally */
+ case HW_CFG_SET_UART_CLOCK:
+ /* set controller's UART baud rate to 3M */
+ UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
+ *p++ = 6; /* parameter length */
+ *p++ = 0; /* encoded baud rate */
+ *p++ = 0; /* use encoded form */
+ UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);
+
+ p_buf->len = 9;
+ hw_cfg_state = (f_set_baud_2) ? HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;
+
+ hci_h4_send_int_cmd(HCI_VSC_UPDATE_BAUDRATE, p_buf, hw_config_cback);
+ break;
+
+ case HW_CFG_SET_UART_BAUD_2:
+ /* update baud rate of host's UART port */
+ userial_change_baud(USERIAL_BAUD_3M);
+
+ /* See if bda addr needs to be programmed */
+ if (memcmp(local_bd_addr, null_bdaddr, 6) != 0)
+ {
+ LOGI("Setting local bd addr to %02X:%02X:%02X:%02X:%02X:%02X",
+ local_bd_addr[0], local_bd_addr[1], local_bd_addr[2],
+ local_bd_addr[3], local_bd_addr[4], local_bd_addr[5]);
+
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_BD_ADDR);
+ *p++ = 6; /* parameter length */
+ *p++ = local_bd_addr[5];
+ *p++ = local_bd_addr[4];
+ *p++ = local_bd_addr[3];
+ *p++ = local_bd_addr[2];
+ *p++ = local_bd_addr[1];
+ *p = local_bd_addr[0];
+
+ p_buf->len = 9;
+ hw_cfg_state = HW_CFG_SET_BD_ADDR;
+
+ hci_h4_send_int_cmd(HCI_VSC_WRITE_BD_ADDR, p_buf, hw_config_cback);
+ break;
+ }
+ /* fall through intentionally */
+ case HW_CFG_SET_BD_ADDR:
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ LOGI("vendor lib preload completed");
+ bt_vendor_cbacks->preload_cb(NULL, BT_VENDOR_PRELOAD_SUCCESS);
+ }
+
+ hw_cfg_state = 0;
+ break;
+
+ }
+
+ /* Free the RX event buffer */
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc((TRANSAC) p_evt_buf, (char *) (p_evt_buf + 1));
+}
+
+
+/*****************************************************************************
+** LPM Static Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function hw_lpm_idle_timeout
+**
+** Description Timeout thread of transport idle timer
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_lpm_idle_timeout(union sigval arg)
+{
+ BTHWDBG("..hw_lpm_idle_timeout..");
+
+ if ((hw_lpm_cb.state == HW_LPM_ENABLED) && (hw_lpm_cb.btwake_state == LPM_BTWAKE_W4_TIMEOUT))
+ btvnd_signal_event(VND_EVENT_LPM_IDLE_TIMEOUT);
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_start_transport_idle_timer
+**
+** Description Launch transport idle timer
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_lpm_start_transport_idle_timer(void)
+{
+ int status;
+ struct itimerspec ts;
+ struct sigevent se;
+
+ if (hw_lpm_cb.state != HW_LPM_ENABLED)
+ return;
+
+ if (hw_lpm_cb.timer_created == FALSE)
+ {
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_value.sival_ptr = &hw_lpm_cb.timer_id;
+ se.sigev_notify_function = hw_lpm_idle_timeout;
+ se.sigev_notify_attributes = NULL;
+
+ /* set idle time to be LPM_IDLE_TIMEOUT_MULTIPLE times of host stack idle threshold (in 300ms/25ms) */
+ hw_lpm_cb.timeout_ms = (uint32_t)lpm_param.host_stack_idle_threshold * LPM_IDLE_TIMEOUT_MULTIPLE;
+
+ if (strstr(local_chip_name, "BCM4325") != NULL)
+ hw_lpm_cb.timeout_ms *= 25; // 12.5 or 25 ?
+ else
+ hw_lpm_cb.timeout_ms *= 300;
+
+ status = timer_create(CLOCK_MONOTONIC, &se, &hw_lpm_cb.timer_id);
+
+ if (status == 0)
+ hw_lpm_cb.timer_created = TRUE;
+ }
+
+ if (hw_lpm_cb.timer_created == TRUE)
+ {
+ ts.it_value.tv_sec = hw_lpm_cb.timeout_ms/1000;
+ ts.it_value.tv_nsec = 1000*(hw_lpm_cb.timeout_ms%1000);
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+
+ status = timer_settime(hw_lpm_cb.timer_id, 0, &ts, 0);
+ if (status == -1)
+ LOGE("[START] Failed to set LPM idle timeout");
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_stop_transport_idle_timer
+**
+** Description Launch transport idle timer
+**
+** Returns None
+**
+*******************************************************************************/
+static void hw_lpm_stop_transport_idle_timer(void)
+{
+ int status;
+ struct itimerspec ts;
+
+ if (hw_lpm_cb.timer_created == TRUE)
+ {
+ ts.it_value.tv_sec = 0;
+ ts.it_value.tv_nsec = 0;
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+
+ status = timer_settime(hw_lpm_cb.timer_id, 0, &ts, 0);
+ if (status == -1)
+ LOGE("[STOP] Failed to set LPM idle timeout");
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_ctrl_cback
+**
+** Description Callback function for lpm enable/disable rquest
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_lpm_ctrl_cback(VND_BT_HDR *p_evt_buf)
+{
+ uint8_t next_state;
+
+ if (*((uint8_t *)(p_evt_buf + 1) + 5) == 0)
+ {
+ /* Status == Success */
+ hw_lpm_cb.state = (hw_lpm_cb.state == HW_LPM_ENABLING) ? HW_LPM_ENABLED : HW_LPM_DISABLED;
+ }
+ else
+ {
+ hw_lpm_cb.state = (hw_lpm_cb.state == HW_LPM_ENABLING) ? HW_LPM_DISABLED : HW_LPM_ENABLED;
+ }
+
+ if (bt_vendor_cbacks)
+ {
+ if (hw_lpm_cb.state == HW_LPM_ENABLED)
+ bt_vendor_cbacks->lpm_cb(BT_VENDOR_LPM_ENABLED);
+ else
+ bt_vendor_cbacks->lpm_cb(BT_VENDOR_LPM_DISABLED);
+ }
+
+ if (hw_lpm_cb.state == HW_LPM_DISABLED)
+ {
+ if (hw_lpm_cb.timer_created == TRUE)
+ {
+ timer_delete(hw_lpm_cb.timer_id);
+ }
+
+ memset(&hw_lpm_cb, 0, sizeof(bt_lpm_cb_t));
+ }
+
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_evt_buf, (char *) (p_evt_buf + 1));
+ }
+}
+
+
+#if (SCO_CFG_INCLUDED == TRUE)
+/*****************************************************************************
+** SCO Configuration Static Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function hw_sco_cfg_cback
+**
+** Description Callback function for SCO configuration rquest
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_sco_cfg_cback(VND_BT_HDR *p_evt_buf)
+{
+ uint8_t *p;
+ uint16_t opcode;
+ VND_BT_HDR *p_buf=NULL;
+
+ p = (uint8_t *)(p_evt_buf + 1) + 3;
+ STREAM_TO_UINT16(opcode,p);
+
+ /* Free the RX event buffer */
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc((TRANSAC) p_evt_buf, (char *) (p_evt_buf+1));
+
+#if (SCO_USE_I2S_INTERFACE == FALSE)
+ if (opcode == HCI_VSC_WRITE_SCO_PCM_INT_PARAM)
+ {
+ uint8_t ret = FALSE;
+
+ /* Ask a new buffer to hold WRITE_PCM_DATA_FORMAT_PARAM command */
+ if (bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE + \
+ 3 + PCM_DATA_FORMAT_PARAM_SIZE);
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = 3 + PCM_DATA_FORMAT_PARAM_SIZE;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM);
+ *p++ = PCM_DATA_FORMAT_PARAM_SIZE;
+ memcpy(p, &bt_pcm_data_fmt_param, PCM_DATA_FORMAT_PARAM_SIZE);
+
+ if ((ret = hci_h4_send_int_cmd(HCI_VSC_WRITE_PCM_DATA_FORMAT_PARAM,\
+ p_buf, hw_sco_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ }
+ else
+ return;
+ }
+ }
+#endif // !SCO_USE_I2S_INTERFACE
+
+ hci_h4_get_acl_data_length();
+}
+#endif // SCO_CFG_INCLUDED
+
+/*****************************************************************************
+** Hardware Configuration Interface Functions
+*****************************************************************************/
+
+
+/*******************************************************************************
+**
+** Function hw_config_start
+**
+** Description Kick off controller initialization process
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_config_start(void)
+{
+ VND_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+
+ hw_cfg_state = 0;
+ f_set_baud_2 = FALSE;
+ hw_lpm_cb.state = HW_LPM_DISABLED;
+
+ /****************************************
+ * !!! TODO !!!
+ *
+ * === Custom Porting Required ===
+ *
+ * Unique Bluetooth address should be
+ * assigned to local_bd_addr[6] in
+ * production line for each device.
+ ****************************************/
+#if 0
+ local_bd_addr[5] = 0x12;
+ local_bd_addr[4] = 0x20;
+ local_bd_addr[3] = 0x5C;
+ local_bd_addr[2] = 0x0A;
+ local_bd_addr[1] = 0x30;
+ local_bd_addr[0] = 0x43;
+#endif
+
+ /* Start from sending HCI_RESET */
+
+ if (bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE+3);
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = 3;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_RESET);
+ *p = 0; /* parameter length */
+
+ hw_cfg_state = HW_CFG_START;
+
+ hci_h4_send_int_cmd(HCI_RESET, p_buf, hw_config_cback);
+ }
+ else
+ {
+ if (bt_vendor_cbacks)
+ {
+ LOGE("vendor lib preload aborted [no buffer]");
+ bt_vendor_cbacks->preload_cb(NULL, BT_VENDOR_PRELOAD_FAIL);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_enable
+**
+** Description Enalbe/Disable LPM
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t hw_lpm_enable(uint8_t turn_on)
+{
+ VND_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+ uint8_t ret = FALSE;
+
+ if ((hw_lpm_cb.state != HW_LPM_DISABLED) && (hw_lpm_cb.state != HW_LPM_ENABLED))
+ {
+ LOGW("Still busy on processing prior LPM enable/disable request...");
+ return FALSE;
+ }
+
+ if ((turn_on == TRUE) && (hw_lpm_cb.state == HW_LPM_ENABLED))
+ {
+ LOGI("LPM is already on!!!");
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->lpm_cb(BT_VENDOR_LPM_ENABLED);
+ return TRUE;
+ }
+ else if ((turn_on == FALSE) && (hw_lpm_cb.state == HW_LPM_DISABLED))
+ {
+ LOGI("LPM is already off!!!");
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->lpm_cb(BT_VENDOR_LPM_DISABLED);
+ return TRUE;
+ }
+
+ if (bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE+3+LPM_CMD_PARAMETER_LEN);
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = 3+LPM_CMD_PARAMETER_LEN;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_SLEEP_MODE);
+ *p++ = LPM_CMD_PARAMETER_LEN; /* parameter length */
+
+ if (turn_on)
+ {
+ memcpy(p, &lpm_param, LPM_CMD_PARAMETER_LEN);
+ hw_lpm_cb.state = HW_LPM_ENABLING;
+ }
+ else
+ {
+ memset(p, 0, LPM_CMD_PARAMETER_LEN);
+ hw_lpm_cb.state = HW_LPM_DISABLING;
+ }
+
+ if ((ret = hci_h4_send_int_cmd(HCI_VSC_WRITE_SLEEP_MODE, p_buf, hw_lpm_ctrl_cback)) == FALSE)
+ {
+ hw_lpm_cb.state = (hw_lpm_cb.state == HW_LPM_ENABLING) ? HW_LPM_DISABLED : HW_LPM_ENABLED;
+
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_tx_done
+**
+** Description This function is to inform the lpm module
+** if data is waiting in the Tx Q or not.
+**
+** IsTxDone: TRUE if All data in the Tx Q are gone
+** FALSE if any data is still in the Tx Q.
+** Typicaly this function must be called
+** before USERIAL Write and in the Tx Done routine
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_lpm_tx_done(uint8_t is_tx_done)
+{
+ hw_lpm_cb.no_tx_data = is_tx_done;
+
+ if ((hw_lpm_cb.btwake_state == LPM_BTWAKE_W4_TX_DONE) && (is_tx_done == TRUE))
+ {
+ hw_lpm_cb.btwake_state = LPM_BTWAKE_W4_TIMEOUT;
+ hw_lpm_start_transport_idle_timer();
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_assert_bt_wake
+**
+** Description Called to wake up Bluetooth chip.
+** Normally this is called when there is data to be sent
+** over UART.
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+void hw_lpm_assert_bt_wake(void)
+{
+ if (hw_lpm_cb.state != HW_LPM_DISABLED)
+ {
+ BTHWDBG("LPM assert BT_WAKE");
+ upio_set(UPIO_BT_WAKE, UPIO_ASSERT, lpm_param.bt_wake_polarity);
+
+ hw_lpm_stop_transport_idle_timer();
+
+ hw_lpm_cb.btwake_state = LPM_BTWAKE_ASSERTED;
+ }
+
+ hw_lpm_tx_done(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_allow_bt_device_sleep
+**
+** Description Start LPM idle timer if allowed
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_lpm_allow_bt_device_sleep(void)
+{
+ if ((hw_lpm_cb.state == HW_LPM_ENABLED) && (hw_lpm_cb.btwake_state == LPM_BTWAKE_ASSERTED))
+ {
+ if(hw_lpm_cb.no_tx_data == TRUE)
+ {
+ hw_lpm_cb.btwake_state = LPM_BTWAKE_W4_TIMEOUT;
+ hw_lpm_start_transport_idle_timer();
+ }
+ else
+ {
+ hw_lpm_cb.btwake_state = LPM_BTWAKE_W4_TX_DONE;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function hw_lpm_deassert_bt_wake
+**
+** Description Deassert bt_wake if allowed
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_lpm_deassert_bt_wake(void)
+{
+ if ((hw_lpm_cb.state == HW_LPM_ENABLED) && (hw_lpm_cb.no_tx_data == TRUE))
+ {
+ BTHWDBG("LPM deassert BT_WAKE");
+ upio_set(UPIO_BT_WAKE, UPIO_DEASSERT, lpm_param.bt_wake_polarity);
+ hw_lpm_cb.btwake_state = LPM_BTWAKE_DEASSERTED;
+ }
+}
+
+#if (SCO_CFG_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function hw_sco_config
+**
+** Description Configure SCO related hardware settings
+**
+** Returns None
+**
+*******************************************************************************/
+void hw_sco_config(void)
+{
+ VND_BT_HDR *p_buf = NULL;
+ uint8_t *p, ret;
+
+#if (SCO_USE_I2S_INTERFACE == FALSE)
+ uint16_t cmd_u16 = 3 + SCO_PCM_PARAM_SIZE;
+#else
+ uint16_t cmd_u16 = 3 + SCO_I2SPCM_PARAM_SIZE;
+#endif
+
+ if (bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE+cmd_u16);
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = cmd_u16;
+
+ p = (uint8_t *) (p_buf + 1);
+#if (SCO_USE_I2S_INTERFACE == FALSE)
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_SCO_PCM_INT_PARAM);
+ *p++ = SCO_PCM_PARAM_SIZE;
+ memcpy(p, &bt_sco_param, SCO_PCM_PARAM_SIZE);
+ cmd_u16 = HCI_VSC_WRITE_SCO_PCM_INT_PARAM;
+ LOGI("SCO PCM configure {%d, %d, %d, %d, %d}",
+ bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3], \
+ bt_sco_param[4]);
+
+#else
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
+ *p++ = SCO_I2SPCM_PARAM_SIZE;
+ memcpy(p, &bt_sco_param, SCO_I2SPCM_PARAM_SIZE);
+ cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
+ LOGI("SCO over I2SPCM interface {%d, %d, %d, %d}",
+ bt_sco_param[0], bt_sco_param[1], bt_sco_param[2], bt_sco_param[3]);
+#endif
+
+ if ((ret = hci_h4_send_int_cmd(cmd_u16, p_buf, hw_sco_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ }
+ else
+ return;
+ }
+
+ if (bt_vendor_cbacks)
+ {
+ LOGE("vendor lib postload aborted");
+ bt_vendor_cbacks->postload_cb(NULL, BT_VENDOR_POSTLOAD_FAIL);
+ }
+}
+#endif // SCO_CFG_INCLUDED
+
diff --git a/vendor/libvendor/src/hci_h4.c b/vendor/libvendor/src/hci_h4.c
new file mode 100644
index 0000000..5436d14
--- /dev/null
+++ b/vendor/libvendor/src/hci_h4.c
@@ -0,0 +1,1047 @@
+/************************************************************************************
+ *
+ * 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: hci_h4.c
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_h4"
+
+#include <utils/Log.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include "bt_vendor_brcm.h"
+#include "userial.h"
+#include "utils.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef HCIH4_DBG
+#define HCIH4_DBG FALSE
+#endif
+
+#if (HCIH4_DBG == TRUE)
+#define HCIH4DBG LOGD
+#else
+#define HCIH4DBG
+#endif
+
+/* Preamble length for HCI Commands:
+** 2-bytes for opcode and 1 byte for length
+*/
+#define HCI_CMD_PREAMBLE_SIZE 3
+
+/* Preamble length for HCI Events:
+** 1-byte for opcode and 1 byte for length
+*/
+#define HCI_EVT_PREAMBLE_SIZE 2
+
+/* Preamble length for SCO Data:
+** 2-byte for Handle and 1 byte for length
+*/
+#define HCI_SCO_PREAMBLE_SIZE 3
+
+/* Preamble length for ACL Data:
+** 2-byte for Handle and 2 byte for length
+*/
+#define HCI_ACL_PREAMBLE_SIZE 4
+
+/* Table of HCI preamble sizes for the different HCI message types */
+static const uint8_t hci_preamble_table[] =
+{
+ HCI_CMD_PREAMBLE_SIZE,
+ HCI_ACL_PREAMBLE_SIZE,
+ HCI_SCO_PREAMBLE_SIZE,
+ HCI_EVT_PREAMBLE_SIZE
+};
+
+/* HCI H4 message type definitions */
+#define H4_TYPE_COMMAND 1
+#define H4_TYPE_ACL_DATA 2
+#define H4_TYPE_SCO_DATA 3
+#define H4_TYPE_EVENT 4
+
+static const uint16_t msg_evt_table[] =
+{
+ MSG_VND_TO_STACK_HCI_ERR, /* H4_TYPE_COMMAND */
+ MSG_VND_TO_STACK_HCI_ACL, /* H4_TYPE_ACL_DATA */
+ MSG_VND_TO_STACK_HCI_SCO, /* H4_TYPE_SCO_DATA */
+ MSG_VND_TO_STACK_HCI_EVT /* H4_TYPE_EVENT */
+};
+
+#define ACL_RX_PKT_START 2
+#define ACL_RX_PKT_CONTINUE 1
+#define L2CAP_HEADER_SIZE 4
+
+/* Maximum numbers of allowed internal
+** outstanding command packets at any time
+*/
+#define INT_CMD_PKT_MAX_COUNT 8
+#define INT_CMD_PKT_IDX_MASK 0x07
+
+#define HCI_COMMAND_COMPLETE_EVT 0x0E
+#define HCI_COMMAND_STATUS_EVT 0x0F
+#define HCI_READ_BUFFER_SIZE 0x1005
+#define HCI_LE_READ_BUFFER_SIZE 0x2002
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/* H4 Rx States */
+typedef enum {
+ H4_RX_MSGTYPE_ST,
+ H4_RX_LEN_ST,
+ H4_RX_DATA_ST,
+ H4_RX_IGNORE_ST
+} tHCI_H4_RCV_STATE;
+
+/* Callback function for the returned event of internal issued command */
+typedef void (*tINT_CMD_CBACK)(VND_BT_HDR *p_buf);
+
+typedef struct
+{
+ uint16_t opcode; /* OPCODE of outstanding internal commands */
+ tINT_CMD_CBACK cback; /* Callback function if return of internal command is received */
+} tINT_CMD_Q;
+
+/* Control block for HCISU_H4 */
+typedef struct
+{
+ VND_BT_HDR *p_rcv_msg; /* Buffer for holding current incoming HCI message */
+ uint16_t rcv_len; /* Size of current incoming message */
+ uint8_t rcv_msg_type; /* Current incoming message type */
+ tHCI_H4_RCV_STATE rcv_state; /* Receive state of current incoming message */
+ uint16_t hc_acl_data_size; /* Host Controller's maximum ACL data length */
+ uint16_t hc_ble_acl_data_size; /* Host Controller's maximum BLE ACL data length */
+ BUFFER_Q acl_rx_q; /* Queue to hold base buffer for fragmented ACL pkts */
+ uint8_t preload_count; /* Count numbers of preload bytes */
+ uint8_t preload_buffer[6]; /* HCI_ACL_PREAMBLE_SIZE + 2 */
+ int int_cmd_rsp_pending; /* Numbers of internal commands pending for response */
+ uint8_t int_cmd_rd_idx; /* Read index of int_cmd_opcode queue */
+ uint8_t int_cmd_wrt_idx; /* Write index of int_cmd_opcode queue */
+ tINT_CMD_Q int_cmd[INT_CMD_PKT_MAX_COUNT]; /* FIFO queue */
+} tHCI_H4_CB;
+
+/************************************************************************************
+** Externs
+************************************************************************************/
+
+extern BUFFER_Q tx_q;
+
+void btsnoop_init(void);
+void btsnoop_open(void);
+void btsnoop_close(void);
+void btsnoop_cleanup (void);
+void btsnoop_capture(VND_BT_HDR *p_buf, uint8_t is_rcvd);
+uint8_t hci_h4_send_int_cmd(uint16_t opcode, VND_BT_HDR *p_buf, tINT_CMD_CBACK p_cback);
+void hw_lpm_assert_bt_wake(void);
+void hw_lpm_tx_done(uint8_t is_tx_done);
+
+/************************************************************************************
+** Variables
+************************************************************************************/
+
+volatile int num_hci_cmd_pkts = 1; /* Num of allowed outstanding HCI CMD packets */
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+static tHCI_H4_CB h4_cb;
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/*******************************************************************************
+**
+** Function is_snoop_enabled
+**
+** Description Enable bt snoop
+**
+** Returns TRUE(enabled)/FALSE
+**
+*******************************************************************************/
+static uint8_t is_snoop_enabled()
+{
+ char buf[8];
+ int flag = 0;
+ int fd = open(SNOOP_CONFIG_PATH, O_RDONLY, 0644);
+
+ if (fd < 0) {
+ LOGE("file failed to open %s ", SNOOP_CONFIG_PATH);
+ return FALSE;
+ }
+ read(fd, buf, sizeof(buf));
+ flag = atoi(buf);
+ return (flag == 1) ? TRUE : FALSE;
+}
+
+/*******************************************************************************
+**
+** Function get_acl_data_length_cback
+**
+** Description Callback function for HCI_READ_BUFFER_SIZE and
+** HCI_LE_READ_BUFFER_SIZE commands if they were sent because
+** of internal request.
+**
+** Returns None
+**
+*******************************************************************************/
+void get_acl_data_length_cback(VND_BT_HDR *p_buf)
+{
+ uint8_t *p, status;
+ uint16_t opcode, len=0;
+
+ p = (uint8_t *)(p_buf + 1) + 3;
+ STREAM_TO_UINT16(opcode, p)
+ status = *p++;
+ if (status == 0) /* Success */
+ STREAM_TO_UINT16(len, p)
+
+ if (opcode == HCI_READ_BUFFER_SIZE)
+ {
+ if (status == 0)
+ h4_cb.hc_acl_data_size = len;
+
+ /* reuse the rx buffer for sending HCI_LE_READ_BUFFER_SIZE command */
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = 3;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_LE_READ_BUFFER_SIZE);
+ *p = 0;
+
+ if ((status = hci_h4_send_int_cmd(HCI_LE_READ_BUFFER_SIZE, p_buf, get_acl_data_length_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ bt_vendor_cbacks->postload_cb(NULL, BT_VENDOR_POSTLOAD_SUCCESS);
+ }
+ }
+ else if (opcode == HCI_LE_READ_BUFFER_SIZE)
+ {
+ if (status == 0)
+ h4_cb.hc_ble_acl_data_size = (len) ? len : h4_cb.hc_acl_data_size;
+
+ if (bt_vendor_cbacks)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ LOGE("vendor lib postload completed");
+ bt_vendor_cbacks->postload_cb(NULL, BT_VENDOR_POSTLOAD_SUCCESS);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function internal_event_intercept
+**
+** Description This function is called to parse received HCI event and
+** - update the Num_HCI_Command_Packets
+** - intercept the event if it is the result of an early
+** issued internal command.
+**
+** Returns TRUE : if the event had been intercepted for internal process
+** FALSE : send this event to core stack
+**
+*******************************************************************************/
+uint8_t internal_event_intercept(void)
+{
+ uint8_t *p;
+ uint8_t event_code;
+ uint16_t opcode, len;
+ tHCI_H4_CB *p_cb = &h4_cb;
+
+ p = (uint8_t *)(p_cb->p_rcv_msg + 1);
+
+ event_code = *p++;
+ len = *p++;
+
+ if (event_code == HCI_COMMAND_COMPLETE_EVT)
+ {
+ num_hci_cmd_pkts = *p++;
+
+ if (p_cb->int_cmd_rsp_pending > 0)
+ {
+ STREAM_TO_UINT16(opcode, p)
+
+ if (opcode == p_cb->int_cmd[p_cb->int_cmd_rd_idx].opcode)
+ {
+ HCIH4DBG("Intercept CommandCompleteEvent for internal command (0x%04X)", opcode);
+ p_cb->int_cmd[p_cb->int_cmd_rd_idx].cback(p_cb->p_rcv_msg);
+ p_cb->int_cmd_rd_idx = ((p_cb->int_cmd_rd_idx+1) & INT_CMD_PKT_IDX_MASK);
+ p_cb->int_cmd_rsp_pending--;
+ return TRUE;
+ }
+ }
+ }
+ else if (event_code == HCI_COMMAND_STATUS_EVT)
+ {
+ num_hci_cmd_pkts = *(++p);
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function acl_rx_frame_buffer_alloc
+**
+** Description This function is called from the HCI transport when the
+** first 4 or 6 bytes of an HCI ACL packet have been received:
+** - Allocate a new buffer if it is a start pakcet of L2CAP
+** message.
+** - Return the buffer address of the starting L2CAP message
+** frame if the packet is the next segment of a fragmented
+** L2CAP message.
+**
+** Returns the address of the receive buffer H4 RX should use
+** (CR419: Modified to return NULL in case of error.)
+**
+** NOTE This assumes that the L2CAP MTU size is less than the size
+** of an HCI ACL buffer, so the maximum L2CAP message will fit
+** into one buffer.
+**
+*******************************************************************************/
+static VND_BT_HDR *acl_rx_frame_buffer_alloc (void)
+{
+ uint8_t *p;
+ uint16_t handle;
+ uint16_t hci_len;
+ uint16_t total_len;
+ uint8_t pkt_type;
+ VND_BT_HDR *p_return_buf = NULL;
+ tHCI_H4_CB *p_cb = &h4_cb;
+
+
+ p = p_cb->preload_buffer;
+
+ STREAM_TO_UINT16 (handle, p);
+ STREAM_TO_UINT16 (hci_len, p);
+ STREAM_TO_UINT16 (total_len, p);
+
+ pkt_type = (uint8_t)(((handle) >> 12) & 0x0003);
+ handle = (uint16_t)((handle) & 0x0FFF);
+
+ if (p_cb->acl_rx_q.count)
+ {
+ uint16_t save_handle;
+ VND_BT_HDR *p_hdr = p_cb->acl_rx_q.p_first;
+
+ while (p_hdr != NULL)
+ {
+ p = (uint8_t *)(p_hdr + 1);
+ STREAM_TO_UINT16 (save_handle, p);
+ save_handle = (uint16_t)((save_handle) & 0x0FFF);
+ if (save_handle == handle)
+ {
+ p_return_buf = p_hdr;
+ break;
+ }
+ p_hdr = utils_getnext(p_hdr);
+ }
+ }
+
+ if (pkt_type == ACL_RX_PKT_START) /*** START PACKET ***/
+ {
+ /* Might have read 2 bytes for the L2CAP payload length */
+ p_cb->rcv_len = (hci_len) ? (hci_len - 2) : 0;
+
+ /* Start of packet. If we were in the middle of receiving */
+ /* a packet on the same ACL handle, the original packet is incomplete. Drop it. */
+ if (p_return_buf)
+ {
+ LOGW("H4 - dropping incomplete ACL frame");
+
+ utils_remove_from_queue(&(p_cb->acl_rx_q), p_return_buf);
+
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc((TRANSAC) p_return_buf, (char *) (p_return_buf + 1));
+
+ p_return_buf = NULL;
+ }
+
+ /* Allocate a buffer for message */
+ if (bt_vendor_cbacks)
+ {
+ int len = total_len + HCI_ACL_PREAMBLE_SIZE + L2CAP_HEADER_SIZE + BT_VND_HDR_SIZE;
+ p_return_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(len);
+ }
+
+ if (p_return_buf)
+ {
+ /* Initialize buffer with preloaded data */
+ p_return_buf->offset = 0;
+ p_return_buf->layer_specific = 0;
+ p_return_buf->event = MSG_VND_TO_STACK_HCI_ACL;
+ p_return_buf->len = p_cb->preload_count;
+ memcpy((uint8_t *)(p_return_buf + 1), p_cb->preload_buffer, p_cb->preload_count);
+
+ if (hci_len && ((total_len + L2CAP_HEADER_SIZE) > hci_len))
+ {
+ /* Will expect to see fragmented ACL packets */
+ /* Keep the base buffer address in the watching queue */
+ utils_enqueue(&(p_cb->acl_rx_q), p_return_buf);
+ }
+ }
+ }
+ else /*** CONTINUATION PACKET ***/
+ {
+ p_cb->rcv_len = hci_len;
+
+ if (p_return_buf)
+ {
+ /* Packet continuation and found the original rx buffer */
+ uint8_t *p_f = p = (uint8_t *)(p_return_buf + 1) + 2;
+
+ STREAM_TO_UINT16 (total_len, p);
+
+ /* Update HCI header of first segment (base buffer) with new length */
+ total_len += hci_len;
+ UINT16_TO_STREAM (p_f, total_len);
+ }
+ }
+
+ return (p_return_buf);
+}
+
+/*******************************************************************************
+**
+** Function acl_rx_frame_end_chk
+**
+** Description This function is called from the HCI transport when the last
+** byte of an HCI ACL packet has been received. It checks if the
+** L2CAP message is complete, i.e. no more continuation packets
+** are expected.
+**
+** Returns TRUE if message complete, FALSE if continuation expected
+**
+*******************************************************************************/
+static uint8_t acl_rx_frame_end_chk (void)
+{
+ uint8_t *p;
+ uint16_t handle, hci_len, l2cap_len;
+ VND_BT_HDR *p_buf;
+ tHCI_H4_CB *p_cb = &h4_cb;
+ uint8_t frame_end=TRUE;
+
+ p_buf = p_cb->p_rcv_msg;
+ p = (uint8_t *)(p_buf + 1);
+
+ STREAM_TO_UINT16 (handle, p);
+ STREAM_TO_UINT16 (hci_len, p);
+ STREAM_TO_UINT16 (l2cap_len, p);
+
+ if (hci_len > 0)
+ {
+ if (l2cap_len > (p_buf->len - (HCI_ACL_PREAMBLE_SIZE + L2CAP_HEADER_SIZE)))
+ {
+ /* If the L2CAP length has not been reached, tell H4 not to send this buffer to stack */
+ frame_end = FALSE;
+ }
+ else
+ {
+ /*
+ * The current buffer coulb be in the watching list.
+ * Remove it from the list if it is in.
+ */
+ if (p_cb->acl_rx_q.count)
+ utils_remove_from_queue(&(p_cb->acl_rx_q), p_buf);
+ }
+ }
+
+ /****
+ ** Print snoop trace
+ ****/
+ if (p_buf->offset)
+ {
+ /* CONTINUATION PACKET */
+
+ /* save original p_buf->len content */
+ uint16_t tmp_u16 = p_buf->len;
+
+ /* borrow HCI_ACL_PREAMBLE_SIZE bytes from the payload section */
+ p = (uint8_t *)(p_buf + 1) + p_buf->offset - HCI_ACL_PREAMBLE_SIZE;
+
+ /* save contents */
+ memcpy(p_cb->preload_buffer, p, HCI_ACL_PREAMBLE_SIZE);
+
+ /* Set packet boundary flags to "continuation packet" */
+ handle = (handle & 0xCFFF) | 0x1000;
+
+ /* write handl & length info */
+ UINT16_TO_STREAM (p, handle);
+ UINT16_TO_STREAM (p, (p_buf->len - p_buf->offset));
+
+ /* roll pointer back */
+ p = p - HCI_ACL_PREAMBLE_SIZE;
+
+ /* adjust `p_buf->offset` & `p_buf->len` before calling btsnoop_capture() */
+ p_buf->offset = p_buf->offset - HCI_ACL_PREAMBLE_SIZE;
+ p_buf->len = p_buf->len - p_buf->offset;
+
+ btsnoop_capture(p_buf, TRUE);
+
+ /* restore contents */
+ memcpy(p, p_cb->preload_buffer, HCI_ACL_PREAMBLE_SIZE);
+
+ /* restore p_buf->len */
+ p_buf->len = tmp_u16;
+ }
+ else
+ {
+ /* START PACKET */
+ btsnoop_capture(p_buf, TRUE);
+ }
+
+ if (frame_end == TRUE)
+ p_buf->offset = 0;
+ else
+ p_buf->offset = p_buf->len; /* save current buffer-end position */
+
+ return frame_end;
+}
+
+/*****************************************************************************
+** HCI H4 INTERFACE FUNCTIONS
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function hci_h4_init
+**
+** Description Initialize H4 module
+**
+** Returns None
+**
+*******************************************************************************/
+void hci_h4_init(void)
+{
+ HCIH4DBG("hci_h4_init");
+
+ memset(&h4_cb, 0, sizeof(tHCI_H4_CB));
+ utils_queue_init(&(h4_cb.acl_rx_q));
+
+ /* Per HCI spec., always starts with 1 */
+ num_hci_cmd_pkts = 1;
+
+ /* Give an initial values of Host Controller's ACL data packet length
+ * Will update with an internal HCI(_LE)_Read_Buffer_Size request
+ */
+ h4_cb.hc_acl_data_size = 1021;
+ h4_cb.hc_ble_acl_data_size = 27;
+
+ btsnoop_init();
+ if (is_snoop_enabled() == TRUE)
+ {
+ btsnoop_open();
+ }
+}
+
+/*******************************************************************************
+**
+** Function hci_h4_cleanup
+**
+** Description Clean H4 module
+**
+** Returns None
+**
+*******************************************************************************/
+void hci_h4_cleanup(void)
+{
+ HCIH4DBG("hci_h4_cleanup");
+
+ btsnoop_close();
+ btsnoop_cleanup();
+}
+
+/*******************************************************************************
+**
+** Function hci_h4_send_msg
+**
+** Description Determine message type, set HCI H4 packet indicator, and
+** send message through USERIAL driver
+**
+** Returns None
+**
+*******************************************************************************/
+void hci_h4_send_msg(VND_BT_HDR *p_msg)
+{
+ uint8_t type = 0;
+ uint16_t handle;
+ uint16_t bytes_to_send, lay_spec;
+ uint8_t *p = ((uint8_t *)(p_msg + 1)) + p_msg->offset;
+ uint16_t event = p_msg->event & MSG_EVT_MASK;
+ uint16_t sub_event = p_msg->event & MSG_SUB_EVT_MASK;
+ uint16_t acl_pkt_size = 0, acl_data_size = 0;
+ uint16_t bytes_sent;
+
+ /* wake up BT device if its in sleep mode */
+ hw_lpm_assert_bt_wake();
+
+ if (event == MSG_STACK_TO_VND_HCI_ACL)
+ type = H4_TYPE_ACL_DATA;
+ else if (event == MSG_STACK_TO_VND_HCI_SCO)
+ type = H4_TYPE_SCO_DATA;
+ else if (event == MSG_STACK_TO_VND_HCI_CMD)
+ type = H4_TYPE_COMMAND;
+
+ if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID)
+ {
+ acl_data_size = h4_cb.hc_acl_data_size;
+ acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
+ }
+ else
+ {
+ acl_data_size = h4_cb.hc_ble_acl_data_size;
+ acl_pkt_size = h4_cb.hc_ble_acl_data_size + HCI_ACL_PREAMBLE_SIZE;
+ }
+
+ /* Check if sending ACL data that needs fragmenting */
+ if ((event == MSG_STACK_TO_VND_HCI_ACL) && (p_msg->len > acl_pkt_size))
+ {
+ /* Get the handle from the packet */
+ STREAM_TO_UINT16 (handle, p);
+
+ /* Set packet boundary flags to "continuation packet" */
+ handle = (handle & 0xCFFF) | 0x1000;
+
+ /* Do all the first chunks */
+ while (p_msg->len > acl_pkt_size)
+ {
+ /* remember layer_specific because uart borrow
+ one byte from layer_specific for packet type */
+ lay_spec = p_msg->layer_specific;
+
+ p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1;
+ *p = type;
+ bytes_to_send = acl_pkt_size + 1; /* packet_size + message type */
+
+ bytes_sent = userial_write((uint8_t *) p, bytes_to_send);
+
+ /* generate snoop trace message */
+ btsnoop_capture(p_msg, FALSE);
+
+ p_msg->layer_specific = lay_spec;
+ /* Adjust offset and length for what we just sent */
+ p_msg->offset += acl_data_size;
+ p_msg->len -= acl_data_size;
+
+ p = ((uint8_t *)(p_msg + 1)) + p_msg->offset;
+
+ UINT16_TO_STREAM (p, handle);
+
+ if (p_msg->len > acl_pkt_size)
+ {
+ UINT16_TO_STREAM (p, acl_data_size);
+ }
+ else
+ {
+ UINT16_TO_STREAM (p, p_msg->len - HCI_ACL_PREAMBLE_SIZE);
+ }
+
+ /* If we were only to send partial buffer, stop when done. */
+ /* Send the buffer back to L2CAP to send the rest of it later */
+ if (p_msg->layer_specific)
+ {
+ if (--p_msg->layer_specific == 0)
+ {
+ p_msg->event = MSG_VND_TO_STACK_L2C_SEG_XMIT;
+
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), BT_VENDOR_TX_FRAGMENT);
+
+ return;
+ }
+ }
+ }
+ }
+
+
+ /* remember layer_specific because uart borrow
+ one byte from layer_specific for packet type */
+ lay_spec = p_msg->layer_specific;
+
+ /* Put the HCI Transport packet type 1 byte before the message */
+ p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1;
+ *p = type;
+ bytes_to_send = p_msg->len + 1; /* message_size + message type */
+
+ bytes_sent = userial_write((uint8_t *) p, bytes_to_send);
+
+ p_msg->layer_specific = lay_spec;
+
+ if (event == MSG_STACK_TO_VND_HCI_CMD)
+ {
+ num_hci_cmd_pkts--;
+
+ /* If this is an internal Cmd packet, the layer_specific field would
+ * have stored with the opcode of HCI command.
+ * Retrieve the opcode from the Cmd packet.
+ */
+ p++;
+ STREAM_TO_UINT16(lay_spec, p);
+ }
+
+ /* generate snoop trace message */
+ btsnoop_capture(p_msg, FALSE);
+
+ if (bt_vendor_cbacks)
+ {
+ if ((event == MSG_STACK_TO_VND_HCI_CMD) && (h4_cb.int_cmd_rsp_pending > 0) && (p_msg->layer_specific == lay_spec))
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_msg, (char *) (p_msg + 1)); /* dealloc buffer of internal command */
+ }
+ else
+ {
+ bt_vendor_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), BT_VENDOR_TX_SUCCESS);
+ }
+ }
+
+ hw_lpm_tx_done(TRUE);
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function hci_h4_receive_msg
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+uint16_t hci_h4_receive_msg(void)
+{
+ uint16_t bytes_read = 0;
+ uint8_t byte;
+ uint16_t msg_len, len;
+ uint8_t msg_received;
+ tHCI_H4_CB *p_cb=&h4_cb;
+
+ while (TRUE)
+ {
+ /* Read one byte to see if there is anything waiting to be read */
+ if (userial_read(&byte, 1) == 0)
+ {
+ break;
+ }
+
+ bytes_read++;
+ msg_received = FALSE;
+
+ switch (p_cb->rcv_state)
+ {
+ case H4_RX_MSGTYPE_ST:
+ /* Start of new message */
+ if ((byte < H4_TYPE_ACL_DATA) || (byte > H4_TYPE_EVENT))
+ {
+ /* Unknown HCI message type */
+ /* Drop this byte */
+ LOGE( "[h4] Unknown HCI message type drop this byte 0x%x", byte);
+ break;
+ }
+
+ /* Initialize rx parameters */
+ p_cb->rcv_msg_type = byte;
+ p_cb->rcv_len = hci_preamble_table[byte-1];
+ memset(p_cb->preload_buffer, 0 , 6);
+ p_cb->preload_count = 0;
+ // p_cb->p_rcv_msg = NULL;
+ p_cb->rcv_state = H4_RX_LEN_ST; /* Next, wait for length to come in */
+ break;
+
+ case H4_RX_LEN_ST:
+ /* Receiving preamble */
+ p_cb->preload_buffer[p_cb->preload_count++] = byte;
+ p_cb->rcv_len--;
+
+ /* Check if we received entire preamble yet */
+ if (p_cb->rcv_len == 0)
+ {
+ if (p_cb->rcv_msg_type == H4_TYPE_ACL_DATA)
+ {
+ /* ACL data lengths are 16-bits */
+ msg_len = p_cb->preload_buffer[3];
+ msg_len = (msg_len << 8) + p_cb->preload_buffer[2];
+
+ if (msg_len && (p_cb->preload_count == 4))
+ {
+ /* Check if this is a start packet */
+ byte = ((p_cb->preload_buffer[1] >> 4) & 0x03);
+
+ if (byte == ACL_RX_PKT_START)
+ {
+ /*
+ * A start packet & with non-zero data payload length.
+ * We want to read 2 more bytes to get L2CAP payload length
+ */
+ p_cb->rcv_len = 2;
+
+ break;
+ }
+ }
+
+ /* Check for segmented packets. If this is a continuation packet, then */
+ /* we will continue appending data to the original rcv buffer. */
+ p_cb->p_rcv_msg = acl_rx_frame_buffer_alloc();
+ }
+ else
+ {
+ /* Received entire preamble. Length is in the last received byte */
+ msg_len = byte;
+ p_cb->rcv_len = msg_len;
+
+ /* Allocate a buffer for message */
+ if (bt_vendor_cbacks)
+ {
+ len = msg_len + p_cb->preload_count + BT_VND_HDR_SIZE;
+ p_cb->p_rcv_msg = (VND_BT_HDR *) bt_vendor_cbacks->alloc(len);
+ }
+
+ if (p_cb->p_rcv_msg)
+ {
+ /* Initialize buffer with preloaded data */
+ p_cb->p_rcv_msg->offset = 0;
+ p_cb->p_rcv_msg->layer_specific = 0;
+ p_cb->p_rcv_msg->event = msg_evt_table[p_cb->rcv_msg_type-1];
+ p_cb->p_rcv_msg->len = p_cb->preload_count;
+ memcpy((uint8_t *)(p_cb->p_rcv_msg + 1), p_cb->preload_buffer, p_cb->preload_count);
+ }
+ }
+
+ if (p_cb->p_rcv_msg == NULL)
+ {
+ /* Unable to acquire message buffer. */
+ LOGE("H4: Unable to acquire buffer for incoming HCI message.");
+
+ if (msg_len == 0)
+ {
+ p_cb->rcv_state = H4_RX_MSGTYPE_ST; /* Wait for next message */
+ }
+ else
+ {
+ p_cb->rcv_state = H4_RX_IGNORE_ST; /* Ignore rest of the packet */
+ }
+
+ break;
+ }
+
+ /* Message length is valid */
+ if (msg_len)
+ {
+ /* Read rest of message */
+ p_cb->rcv_state = H4_RX_DATA_ST;
+ }
+ else
+ {
+ /* Message has no additional parameters. (Entire message has been received) */
+ if (p_cb->rcv_msg_type == H4_TYPE_ACL_DATA)
+ acl_rx_frame_end_chk(); /* to print snoop trace */
+
+ msg_received = TRUE;
+ p_cb->rcv_state = H4_RX_MSGTYPE_ST; /* Next, wait for next message */
+ }
+ }
+ break;
+
+ case H4_RX_DATA_ST:
+ *((uint8_t *)(p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->len++) = byte;
+ p_cb->rcv_len--;
+
+ if (p_cb->rcv_len > 0)
+ {
+ /* Read in the rest of the message */
+ len = userial_read(((uint8_t *)(p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->len), p_cb->rcv_len);
+ p_cb->p_rcv_msg->len += len;
+ p_cb->rcv_len -= len;
+ bytes_read += len;
+ }
+
+ /* Check if we read in entire message yet */
+ if (p_cb->rcv_len == 0)
+ {
+ /* Received entire packet. */
+ /* Check for segmented l2cap packets */
+ if ((p_cb->rcv_msg_type == H4_TYPE_ACL_DATA) &&
+ !acl_rx_frame_end_chk())
+ {
+ /* Not the end of packet yet. */
+ p_cb->rcv_state = H4_RX_MSGTYPE_ST; /* Next, wait for next message */
+ }
+ else
+ {
+ msg_received = TRUE;
+ p_cb->rcv_state = H4_RX_MSGTYPE_ST; /* Next, wait for next message */
+ }
+ }
+ break;
+
+
+ case H4_RX_IGNORE_ST:
+ /* Ignore reset of packet */
+ p_cb->rcv_len--;
+
+ /* Check if we read in entire message yet */
+ if (p_cb->rcv_len == 0)
+ {
+ p_cb->rcv_state = H4_RX_MSGTYPE_ST; /* Next, wait for next message */
+ }
+ break;
+ }
+
+
+ /* If we received entire message, then send it to the task */
+ if (msg_received)
+ {
+ uint8_t intercepted = FALSE;
+
+ /* generate snoop trace message */
+ if (p_cb->p_rcv_msg->event != MSG_VND_TO_STACK_HCI_ACL) /* had done in acl_rx_frame_end_chk() */
+ btsnoop_capture(p_cb->p_rcv_msg, TRUE);
+
+ if (p_cb->p_rcv_msg->event == MSG_VND_TO_STACK_HCI_EVT)
+ intercepted = internal_event_intercept();
+
+ if ((bt_vendor_cbacks) && (intercepted == FALSE))
+ {
+ bt_vendor_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, (char *) (p_cb->p_rcv_msg + 1), p_cb->p_rcv_msg->len + BT_VND_HDR_SIZE);
+ }
+ p_cb->p_rcv_msg = NULL;
+ }
+ }
+
+ return (bytes_read);
+}
+
+
+/*******************************************************************************
+**
+** Function hci_h4_send_int_cmd
+**
+** Description
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t hci_h4_send_int_cmd(uint16_t opcode, VND_BT_HDR *p_buf, tINT_CMD_CBACK p_cback)
+{
+ if (h4_cb.int_cmd_rsp_pending > INT_CMD_PKT_MAX_COUNT)
+ {
+ LOGE("Currently we only allow %d outstanding internal command at a time [Reject 0x%04X]", INT_CMD_PKT_MAX_COUNT, opcode);
+ return FALSE;
+ }
+
+ h4_cb.int_cmd_rsp_pending++;
+ h4_cb.int_cmd[h4_cb.int_cmd_wrt_idx].opcode = opcode;
+ h4_cb.int_cmd[h4_cb.int_cmd_wrt_idx].cback = p_cback;
+ h4_cb.int_cmd_wrt_idx = ((h4_cb.int_cmd_wrt_idx + 1) & INT_CMD_PKT_IDX_MASK);
+
+ p_buf->layer_specific = opcode; /* signature to indicate an internal command */
+
+ utils_enqueue(&tx_q, (void *) p_buf);
+ btvnd_signal_event(VND_EVENT_TX);
+
+ return TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function hci_h4_get_acl_data_length
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+void hci_h4_get_acl_data_length(void)
+{
+ VND_BT_HDR *p_buf = NULL;
+ uint8_t *p, ret;
+
+ if (bt_vendor_cbacks)
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BT_VND_HDR_SIZE+3);
+
+ if (p_buf)
+ {
+ p_buf->event = MSG_STACK_TO_VND_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = 3;
+
+ p = (uint8_t *) (p_buf + 1);
+ UINT16_TO_STREAM(p, HCI_READ_BUFFER_SIZE);
+ *p = 0;
+
+ if ((ret = hci_h4_send_int_cmd(HCI_READ_BUFFER_SIZE, p_buf, get_acl_data_length_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ }
+ else
+ return;
+ }
+
+ if (bt_vendor_cbacks)
+ {
+ LOGE("vendor lib postload aborted");
+ bt_vendor_cbacks->postload_cb(NULL, BT_VENDOR_POSTLOAD_FAIL);
+ }
+}
+
diff --git a/vendor/libvendor/src/upio.c b/vendor/libvendor/src/upio.c
new file mode 100644
index 0000000..c8c51dc
--- /dev/null
+++ b/vendor/libvendor/src/upio.c
@@ -0,0 +1,322 @@
+/************************************************************************************
+ *
+ * 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: upio.c
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_upio"
+
+#include <utils/Log.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <cutils/properties.h>
+#include "bt_vendor_brcm.h"
+#include "upio.h"
+#include "userial.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef UPIO_DBG
+#define UPIO_DBG FALSE
+#endif
+
+#if (UPIO_DBG == TRUE)
+#define UPIODBG LOGD
+#else
+#define UPIODBG LOGV
+#endif
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+static uint8_t upio_state[UPIO_MAX_COUNT];
+static int rfkill_id = -1;
+static int bt_emul_enable = 0;
+static char *rfkill_state_path = NULL;
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/* for friendly debugging outpout string */
+static char *lpm_state[] = {
+ "UNKNOWN",
+ "de-asserted",
+ "asserted"
+};
+
+/*****************************************************************************
+** Bluetooth On/Off Static Functions
+*****************************************************************************/
+static int is_emulator_context(void)
+{
+ char value[PROPERTY_VALUE_MAX];
+
+ property_get("ro.kernel.qemu", value, "0");
+ UPIODBG("is_emulator_context : %s", value);
+ if (strcmp(value, "1") == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+static int is_rfkill_disabled(void)
+{
+ char value[PROPERTY_VALUE_MAX];
+
+ property_get("ro.rfkilldisabled", value, "0");
+ UPIODBG("is_rfkill_disabled ? [%s]", value);
+
+ if (strcmp(value, "1") == 0) {
+ return UPIO_BT_POWER_ON;
+ }
+
+ return UPIO_BT_POWER_OFF;
+}
+
+static int init_rfkill()
+{
+ char path[64];
+ char buf[16];
+ int fd, sz, id;
+
+ if (is_rfkill_disabled())
+ return -1;
+
+ for (id = 0; ; id++)
+ {
+ snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ {
+ LOGE("init_rfkill : open(%s) failed: %s (%d)\n", path, strerror(errno), errno);
+ return -1;
+ }
+
+ sz = read(fd, &buf, sizeof(buf));
+ close(fd);
+
+ if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)
+ {
+ rfkill_id = id;
+ break;
+ }
+ }
+
+ asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
+ return 0;
+}
+
+/*****************************************************************************
+** LPM Static Functions
+*****************************************************************************/
+
+/*****************************************************************************
+** UPIO Interface Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function upio_init
+**
+** Description Initialization
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_init(void)
+{
+ memset(upio_state, UPIO_UNKNOWN, UPIO_MAX_COUNT);
+}
+
+/*******************************************************************************
+**
+** Function upio_cleanup
+**
+** Description Clean up
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_cleanup(void)
+{
+}
+
+/*******************************************************************************
+**
+** Function upio_set_bluetooth_power
+**
+** Description Interact with low layer driver to set Bluetooth power
+** on/off.
+**
+** Returns 0 : SUCCESS or Not-Applicable
+** <0 : ERROR
+**
+*******************************************************************************/
+int upio_set_bluetooth_power(int on)
+{
+ int sz;
+ int fd = -1;
+ int ret = -1;
+ char buffer = '0';
+
+ switch(on)
+ {
+ case UPIO_BT_POWER_OFF:
+ buffer = '0';
+ break;
+
+ case UPIO_BT_POWER_ON:
+ buffer = '1';
+ break;
+ }
+
+ if (is_emulator_context())
+ {
+ /* if new value is same as current, return -1 */
+ if (bt_emul_enable == on)
+ return ret;
+
+ UPIODBG("set_bluetooth_power [emul] %d", on);
+
+ bt_emul_enable = on;
+ return 0;
+ }
+
+ /* check if we have rfkill interface */
+ if (is_rfkill_disabled())
+ return 0;
+
+ if (rfkill_id == -1)
+ {
+ if (init_rfkill())
+ return ret;
+ }
+
+ fd = open(rfkill_state_path, O_WRONLY);
+
+ if (fd < 0)
+ {
+ LOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",
+ rfkill_state_path, strerror(errno), errno);
+ return ret;
+ }
+
+ sz = write(fd, &buffer, 1);
+
+ if (sz < 0) {
+ LOGE("set_bluetooth_power : write(%s) failed: %s (%d)",
+ rfkill_state_path, strerror(errno),errno);
+ }
+ else
+ ret = 0;
+
+ if (fd >= 0)
+ close(fd);
+
+ return ret;
+}
+
+
+/*******************************************************************************
+**
+** Function upio_set
+**
+** Description Set i/o based on polarity
+**
+** Returns None
+**
+*******************************************************************************/
+void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
+{
+ int rc;
+
+ switch (pio)
+ {
+ case UPIO_BT_WAKE:
+
+ if (upio_state[UPIO_BT_WAKE] == action)
+ {
+ UPIODBG("BT_WAKE is %s already", lpm_state[action]);
+ return;
+ }
+
+ upio_state[UPIO_BT_WAKE] = action;
+
+ /****************************************
+ * !!! TODO !!!
+ *
+ * === Custom Porting Required ===
+ *
+ * Platform dependent user-to-kernel
+ * interface is required to set output
+ * state of physical BT_WAKE pin.
+ ****************************************/
+#if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE)
+ userial_ioctl(((action==UPIO_ASSERT) ? USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE), NULL);
+#endif
+ break;
+
+ case UPIO_HOST_WAKE:
+ UPIODBG("upio_set: UPIO_HOST_WAKE");
+ break;
+ }
+}
+
+
diff --git a/vendor/libvendor/src/userial.c b/vendor/libvendor/src/userial.c
new file mode 100644
index 0000000..c1742ca
--- /dev/null
+++ b/vendor/libvendor/src/userial.c
@@ -0,0 +1,745 @@
+/************************************************************************************
+ *
+ * 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: userial.c
+ *
+ * Description:
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_userial"
+
+#include <utils/Log.h>
+#include <pthread.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include "bt_vendor_brcm.h"
+#include "userial.h"
+#include "utils.h"
+
+/************************************************************************************
+** Constants & Macros
+************************************************************************************/
+
+#ifndef USERIAL_DBG
+#define USERIAL_DBG FALSE
+#endif
+
+#if (USERIAL_DBG == TRUE)
+#define USERIALDBG LOGD
+#else
+#define USERIALDBG
+#endif
+
+#define MAX_SERIAL_PORT (USERIAL_PORT_3 + 1)
+#define READ_LIMIT (BTVND_USERIAL_READ_MEM_SIZE - BT_VND_HDR_SIZE)
+
+enum {
+ USERIAL_RX_EXIT,
+ USERIAL_RX_FLOW_OFF,
+ USERIAL_RX_FLOW_ON
+};
+
+/************************************************************************************
+** Local type definitions
+************************************************************************************/
+
+typedef struct
+{
+ int sock;
+ uint8_t port;
+ pthread_t read_thread;
+ tUSERIAL_CFG cfg;
+ BUFFER_Q rx_q;
+ VND_BT_HDR *p_rx_hdr;
+} tUSERIAL_CB;
+
+/************************************************************************************
+** Static variables
+************************************************************************************/
+
+static tUSERIAL_CB userial_cb;
+static volatile uint8_t userial_running = 0;
+
+/* Mapping of USERIAL_PORT_x to device ports */
+char userial_dev[][256] =
+{
+ BLUETOOTH_UART_DEVICE_PORT /* USERIAL_PORT_1 (HCI)*/
+};
+
+/* for friendly debugging outpout string */
+static uint32_t userial_baud_tbl[] =
+{
+ 300, /* USERIAL_BAUD_300 0 */
+ 600, /* USERIAL_BAUD_600 1 */
+ 1200, /* USERIAL_BAUD_1200 2 */
+ 2400, /* USERIAL_BAUD_2400 3 */
+ 9600, /* USERIAL_BAUD_9600 4 */
+ 19200, /* USERIAL_BAUD_19200 5 */
+ 57600, /* USERIAL_BAUD_57600 6 */
+ 115200, /* USERIAL_BAUD_115200 7 */
+ 230400, /* USERIAL_BAUD_230400 8 */
+ 460800, /* USERIAL_BAUD_460800 9 */
+ 921600, /* USERIAL_BAUD_921600 10 */
+ 1000000, /* USERIAL_BAUD_1M 11 */
+ 1500000, /* USERIAL_BAUD_1_5M 12 */
+ 2000000, /* USERIAL_BAUD_2M 13 */
+ 3000000, /* USERIAL_BAUD_3M 14 */
+ 4000000 /* USERIAL_BAUD_4M 15 */
+};
+
+/************************************************************************************
+** Static functions
+************************************************************************************/
+
+/*****************************************************************************
+** Socket signal functions to wake up userial_read_thread for termination
+**
+** creating an unnamed pair of connected sockets
+** - signal_fds[0]: join fd_set in select call of userial_read_thread
+** - signal_fds[1]: trigger from userial_close
+*****************************************************************************/
+static int signal_fds[2]={0,1};
+static uint8_t rx_flow_on = TRUE;
+static inline int create_signal_fds(fd_set* set)
+{
+ if(signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
+ {
+ LOGE("create_signal_sockets:socketpair failed, errno: %d", errno);
+ return -1;
+ }
+ FD_SET(signal_fds[0], set);
+ return signal_fds[0];
+}
+static inline int send_wakeup_signal(char sig_cmd)
+{
+ return send(signal_fds[1], &sig_cmd, sizeof(sig_cmd), 0);
+}
+static inline char reset_signal()
+{
+ char sig_recv = -1;
+ recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ return sig_recv;
+}
+static inline int is_signaled(fd_set* set)
+{
+ return FD_ISSET(signal_fds[0], set);
+}
+
+/*******************************************************************************
+**
+** Function select_read
+**
+** Description check if fd is ready for reading and listen for termination
+** signal. need to use select in order to avoid collision
+** between read and close on the same fd
+**
+** Returns -1: termination
+** >=0: numbers of bytes read back from fd
+**
+*******************************************************************************/
+static int select_read(int fd, uint8_t *pbuf, int len)
+{
+ fd_set input;
+ int n = 0, ret = -1;
+ char reason = 0;
+
+ while (userial_running)
+ {
+ /* Initialize the input fd set */
+ FD_ZERO(&input);
+ if (rx_flow_on == TRUE)
+ {
+ FD_SET(fd, &input);
+ }
+ int fd_max = create_signal_fds(&input);
+ fd_max = fd_max > fd ? fd_max : fd;
+
+ /* Do the select */
+ n = select(fd_max+1, &input, NULL, NULL, NULL);
+ if(is_signaled(&input))
+ {
+ reason = reset_signal();
+ if (reason == USERIAL_RX_EXIT)
+ {
+ USERIALDBG("RX termination");
+ return -1;
+ }
+ else if (reason == USERIAL_RX_FLOW_OFF)
+ {
+ USERIALDBG("RX flow OFF");
+ rx_flow_on = FALSE;
+ }
+ else if (reason == USERIAL_RX_FLOW_ON)
+ {
+ USERIALDBG("RX flow ON");
+ rx_flow_on = TRUE;
+ }
+ }
+
+ if (n > 0)
+ {
+ /* We might have input */
+ if (FD_ISSET(fd, &input))
+ {
+ ret = read(fd, pbuf, (size_t)len);
+ if (0 == ret)
+ LOGW( "read() returned 0!" );
+
+ return ret;
+ }
+ }
+ else if (n < 0)
+ LOGW( "select() Failed");
+ else if (n == 0)
+ LOGW( "Got a select() TIMEOUT");
+
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function userial_read_thread
+**
+** Description
+**
+** Returns void *
+**
+*******************************************************************************/
+static void *userial_read_thread(void *arg)
+{
+ int rx_length = 0;
+ VND_BT_HDR *p_buf = NULL;
+ uint8_t *p;
+
+ USERIALDBG("Entering userial_read_thread()");
+
+ rx_flow_on = TRUE;
+ userial_running = 1;
+
+ while (userial_running)
+ {
+ if (bt_vendor_cbacks)
+ {
+ p_buf = (VND_BT_HDR *) bt_vendor_cbacks->alloc(BTVND_USERIAL_READ_MEM_SIZE);
+ }
+ else
+ p_buf = NULL;
+
+ if (p_buf != NULL)
+ {
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+
+ p = (uint8_t *) (p_buf + 1);
+ rx_length = select_read(userial_cb.sock, p, READ_LIMIT);
+ }
+ else
+ {
+ rx_length = 0;
+ utils_delay(100);
+ LOGW("userial_read_thread() failed to gain buffers");
+ continue;
+ }
+
+
+ if (rx_length > 0)
+ {
+ p_buf->len = (uint16_t)rx_length;
+ utils_enqueue(&(userial_cb.rx_q), p_buf);
+ btvnd_signal_event(VND_EVENT_RX);
+ }
+ else /* either 0 or < 0 */
+ {
+ LOGW("select_read return size <=0:%d, exiting userial_read_thread", rx_length);
+ /* if we get here, we should have a buffer */
+ bt_vendor_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1));
+ /* negative value means exit thread */
+ break;
+ }
+ } /* for */
+
+ userial_running = 0;
+ USERIALDBG("Leaving userial_read_thread()");
+ pthread_exit(NULL);
+
+ return NULL; // Compiler friendly
+}
+
+
+/*****************************************************************************
+** Helper Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function baud_userial_to_tcio
+**
+** Description helper function converts USERIAL baud rates into TCIO
+** conforming baud rates
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t userial_to_tcio_baud(uint8_t cfg_baud, uint32_t *baud)
+{
+ if (cfg_baud == USERIAL_BAUD_600)
+ *baud = B600;
+ else if (cfg_baud == USERIAL_BAUD_1200)
+ *baud = B1200;
+ else if (cfg_baud == USERIAL_BAUD_9600)
+ *baud = B9600;
+ else if (cfg_baud == USERIAL_BAUD_19200)
+ *baud = B19200;
+ else if (cfg_baud == USERIAL_BAUD_57600)
+ *baud = B57600;
+ else if (cfg_baud == USERIAL_BAUD_115200)
+ *baud = B115200;
+ else if (cfg_baud == USERIAL_BAUD_230400)
+ *baud = B230400;
+ else if (cfg_baud == USERIAL_BAUD_460800)
+ *baud = B460800;
+ else if (cfg_baud == USERIAL_BAUD_921600)
+ *baud = B921600;
+ else if (cfg_baud == USERIAL_BAUD_1M)
+ *baud = B1000000;
+ else if (cfg_baud == USERIAL_BAUD_2M)
+ *baud = B2000000;
+ else if (cfg_baud == USERIAL_BAUD_3M)
+ *baud = B3000000;
+ else if (cfg_baud == USERIAL_BAUD_4M)
+ *baud = B4000000;
+ else
+ {
+ LOGE( "userial_open: unsupported baud idx %i", cfg_baud);
+ *baud = B115200;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+/*******************************************************************************
+**
+** Function userial_ioctl_init_bt_wake
+**
+** Description helper function to set the open state of the bt_wake if ioctl
+** is used. it should not hurt in the rfkill case but it might
+** be better to compile it out.
+**
+** Returns none
+**
+*******************************************************************************/
+void userial_ioctl_init_bt_wake(int fd)
+{
+ uint32_t bt_wake_state;
+
+ /* assert BT_WAKE through ioctl */
+ ioctl( fd, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL);
+ ioctl( fd, USERIAL_IOCTL_BT_WAKE_GET_ST, &bt_wake_state);
+ USERIALDBG("userial_ioctl_init_bt_wake read back BT_WAKE state=%i", bt_wake_state);
+}
+#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+
+
+/*****************************************************************************
+** Userial API Functions
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function userial_init
+**
+** Description Initializes the userial driver
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t userial_init(void)
+{
+ USERIALDBG("userial_init");
+ memset(&userial_cb, 0, sizeof(tUSERIAL_CB));
+ userial_cb.sock = -1;
+ utils_queue_init(&(userial_cb.rx_q));
+ return TRUE;
+}
+
+
+/*******************************************************************************
+**
+** Function userial_open
+**
+** Description Open the indicated serial port with the given configuration
+**
+** Returns TRUE/FALSE
+**
+*******************************************************************************/
+uint8_t userial_open(uint8_t port, tUSERIAL_CFG *p_cfg)
+{
+ uint32_t baud;
+ uint8_t data_bits;
+ uint16_t parity;
+ uint8_t stop_bits;
+ struct termios termios;
+ struct sched_param param;
+ int policy;
+ pthread_attr_t thread_attr;
+ char device_name[20];
+
+ USERIALDBG("userial_open(port:%d, baud:%d)", port, p_cfg->baud);
+
+ if (userial_running)
+ {
+ /* Userial is open; close it first */
+ userial_close();
+ utils_delay(50);
+ }
+
+ if (port >= MAX_SERIAL_PORT)
+ {
+ LOGE("Port > MAX_SERIAL_PORT");
+ return FALSE;
+ }
+
+ if (!userial_to_tcio_baud(p_cfg->baud, &baud))
+ {
+ return FALSE;
+ }
+
+ if(p_cfg->fmt & USERIAL_DATABITS_8)
+ data_bits = CS8;
+ else if(p_cfg->fmt & USERIAL_DATABITS_7)
+ data_bits = CS7;
+ else if(p_cfg->fmt & USERIAL_DATABITS_6)
+ data_bits = CS6;
+ else if(p_cfg->fmt & USERIAL_DATABITS_5)
+ data_bits = CS5;
+ else
+ {
+ LOGE("userial_open: unsupported data bits");
+ return FALSE;
+ }
+
+ if(p_cfg->fmt & USERIAL_PARITY_NONE)
+ parity = 0;
+ else if(p_cfg->fmt & USERIAL_PARITY_EVEN)
+ parity = PARENB;
+ else if(p_cfg->fmt & USERIAL_PARITY_ODD)
+ parity = (PARENB | PARODD);
+ else
+ {
+ LOGE("userial_open: unsupported parity bit mode");
+ return FALSE;
+ }
+
+ if(p_cfg->fmt & USERIAL_STOPBITS_1)
+ stop_bits = 0;
+ else if(p_cfg->fmt & USERIAL_STOPBITS_2)
+ stop_bits = CSTOPB;
+ else
+ {
+ LOGE("userial_open: unsupported stop bits");
+ return FALSE;
+ }
+
+ sprintf(device_name, "%s", userial_dev[port]);
+ LOGI("userial_open: opening %s", device_name);
+
+ if ((userial_cb.sock = open(device_name, O_RDWR)) == -1)
+ {
+ LOGE("userial_open: unable to open %s", device_name);
+ return FALSE;
+ }
+
+ tcflush(userial_cb.sock, TCIOFLUSH);
+
+ tcgetattr(userial_cb.sock, &termios);
+ cfmakeraw(&termios);
+ termios.c_cflag |= (CRTSCTS | stop_bits);
+ tcsetattr(userial_cb.sock, TCSANOW, &termios);
+
+ tcflush(userial_cb.sock, TCIOFLUSH);
+
+ /* set input/output baudrate */
+ cfsetospeed(&termios, baud);
+ cfsetispeed(&termios, baud);
+ tcsetattr(userial_cb.sock, TCSANOW, &termios);
+
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+ userial_ioctl_init_bt_wake(userial_cb.sock);
+#endif
+
+ USERIALDBG( "sock = %d", userial_cb.sock);
+
+ userial_cb.port = port;
+ memcpy(&userial_cb.cfg, p_cfg, sizeof(tUSERIAL_CFG));
+
+
+ pthread_attr_init(&thread_attr);
+
+ if (pthread_create(&(userial_cb.read_thread), &thread_attr, userial_read_thread, NULL) != 0 )
+ {
+ LOGE("pthread_create failed!\n\r");
+ return FALSE;
+ }
+
+ if(pthread_getschedparam(userial_cb.read_thread, &policy, &param)==0)
+ {
+ policy = SCHED_FIFO;
+ param.sched_priority = BTVND_USERIAL_READ_THREAD_PRIORITY;
+ pthread_setschedparam(userial_cb.read_thread, policy, &param);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function userial_read
+**
+** Description Read data from the userial port
+**
+** Returns Number of bytes actually read from the userial port and
+** copied into p_data. This may be less than len.
+**
+*******************************************************************************/
+uint16_t userial_read(uint8_t *p_buffer, uint16_t len)
+{
+ uint16_t total_len = 0;
+ uint16_t copy_len = 0;
+ uint8_t *p_data = NULL;
+
+ do
+ {
+ if(userial_cb.p_rx_hdr != NULL)
+ {
+ p_data = ((uint8_t *)(userial_cb.p_rx_hdr + 1)) + (userial_cb.p_rx_hdr->offset);
+
+ if((userial_cb.p_rx_hdr->len) <= (len - total_len))
+ copy_len = userial_cb.p_rx_hdr->len;
+ else
+ copy_len = (len - total_len);
+
+ memcpy((p_buffer + total_len), p_data, copy_len);
+
+ total_len += copy_len;
+
+ userial_cb.p_rx_hdr->offset += copy_len;
+ userial_cb.p_rx_hdr->len -= copy_len;
+
+ if(userial_cb.p_rx_hdr->len == 0)
+ {
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc((TRANSAC) userial_cb.p_rx_hdr, (char *) (userial_cb.p_rx_hdr + 1));
+
+ userial_cb.p_rx_hdr = NULL;
+ }
+ }
+
+ if(userial_cb.p_rx_hdr == NULL)
+ {
+ userial_cb.p_rx_hdr = (VND_BT_HDR *)utils_dequeue(&(userial_cb.rx_q));
+ }
+ } while ((userial_cb.p_rx_hdr != NULL) && (total_len < len));
+
+#if 0
+ if (total_len < len)
+ USERIALDBG("userial_read() gives %d when asks %d", total_len, len);
+#endif
+
+ return total_len;
+}
+
+/*******************************************************************************
+**
+** Function userial_write
+**
+** Description Write data to the userial port
+**
+** Returns Number of bytes actually written to the userial port. This
+** may be less than len.
+**
+*******************************************************************************/
+uint16_t userial_write(uint8_t *p_data, uint16_t len)
+{
+ int ret, total = 0;
+
+ while(len != 0)
+ {
+ ret = write(userial_cb.sock, p_data+total, len);
+ total += ret;
+ len -= ret;
+ }
+
+#if 0
+ if (total < len)
+ USERIALDBG("userial_write() does %d when asks %d", total, len);
+#endif
+
+ return ((uint16_t)total);
+}
+
+/*******************************************************************************
+**
+** Function userial_close
+**
+** Description Close the userial port
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_close(void)
+{
+ int result;
+ TRANSAC p_buf;
+
+ USERIALDBG("userial_close(sock:%d)", userial_cb.sock);
+
+ if (userial_running)
+ send_wakeup_signal(USERIAL_RX_EXIT);
+
+ if ((result=pthread_join(userial_cb.read_thread, NULL)) < 0)
+ LOGE( "pthread_join() FAILED result:%d", result);
+
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+ /* de-assert bt_wake BEFORE closing port */
+ ioctl(userial_cb.sock, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL);
+#endif
+
+ if ((result=close(userial_cb.sock)) < 0)
+ LOGE( "close(sock:%d) FAILED result:%d", userial_cb.sock, result);
+
+ userial_cb.sock = -1;
+
+ if (bt_vendor_cbacks)
+ {
+ while ((p_buf = utils_dequeue (&(userial_cb.rx_q))) != NULL)
+ {
+ bt_vendor_cbacks->dealloc(p_buf, (char *) ((VND_BT_HDR *)p_buf + 1));
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function userial_change_baud
+**
+** Description Change baud rate of userial port
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_change_baud(uint8_t baud)
+{
+ struct termios termios;
+
+ USERIALDBG("userial_change_baud: Closing UART Port");
+ userial_close();
+
+ utils_delay(50);
+
+ /* change baud rate in settings - leave everything else the same */
+ userial_cb.cfg.baud = baud;
+
+ LOGI("userial_change_rate: Attempting to reopen the UART Port at %i", (unsigned int)userial_baud_tbl[baud]);
+
+ userial_open(userial_cb.port, &userial_cb.cfg);
+}
+
+/*******************************************************************************
+**
+** Function userial_ioctl
+**
+** Description ioctl inteface
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_ioctl(userial_ioctl_op_t op, void *p_data)
+{
+ switch(op)
+ {
+ case USERIAL_OP_RXFLOW_ON:
+ if (userial_running)
+ send_wakeup_signal(USERIAL_RX_FLOW_ON);
+ break;
+
+ case USERIAL_OP_RXFLOW_OFF:
+ if (userial_running)
+ send_wakeup_signal(USERIAL_RX_FLOW_OFF);
+ break;
+
+#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+ case USERIAL_OP_ASSERT_BT_WAKE:
+ USERIALDBG("##### userial_ioctl: Asserting BT_Wake ####");
+ ioctl(userial_cb.sock, USERIAL_IOCTL_BT_WAKE_ASSERT, NULL);
+ break;
+
+ case USERIAL_OP_DEASSERT_BT_WAKE:
+ USERIALDBG("##### userial_ioctl: De-asserting BT_Wake ####");
+ ioctl(userial_cb.sock, USERIAL_IOCTL_BT_WAKE_DEASSERT, NULL);
+ break;
+
+ case USERIAL_OP_GET_BT_WAKE_STATE:
+ ioctl(userial_cb.sock, USERIAL_IOCTL_BT_WAKE_GET_ST, p_data);
+ break;
+#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
+
+ case USERIAL_OP_INIT:
+ default:
+ break;
+ }
+}
+
diff --git a/vendor/libvendor/src/utils.c b/vendor/libvendor/src/utils.c
new file mode 100644
index 0000000..85336b5
--- /dev/null
+++ b/vendor/libvendor/src/utils.c
@@ -0,0 +1,312 @@
+/************************************************************************************
+ *
+ * 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:
+ *
+ ***********************************************************************************/
+
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+#include "bt_vendor_brcm.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)
+{
+ VND_BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (VND_BUFFER_HDR_T *) ((uint8_t *) p_buf - BT_VND_BUFFER_HDR_SIZE);
+
+ pthread_mutex_lock(&utils_mutex);
+
+ if (p_q->p_last)
+ {
+ VND_BUFFER_HDR_T *p_last_hdr = (VND_BUFFER_HDR_T *)((uint8_t *)p_q->p_last - BT_VND_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)
+{
+ VND_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 = (VND_BUFFER_HDR_T *)((uint8_t *)p_q->p_first - BT_VND_BUFFER_HDR_SIZE);
+
+ if (p_hdr->p_next)
+ p_q->p_first = ((uint8_t *)p_hdr->p_next + BT_VND_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_VND_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)
+{
+ VND_BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (VND_BUFFER_HDR_T *) ((uint8_t *) p_buf - BT_VND_BUFFER_HDR_SIZE);
+
+ if (p_hdr->p_next)
+ return ((uint8_t *)p_hdr->p_next + BT_VND_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)
+{
+ VND_BUFFER_HDR_T *p_prev;
+ VND_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 = (VND_BUFFER_HDR_T *)((uint8_t *)p_buf - BT_VND_BUFFER_HDR_SIZE);
+ p_prev = (VND_BUFFER_HDR_T *)((uint8_t *)p_q->p_first - BT_VND_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);
+}
+