NFC: Import baseline of third party libnfc-nci
Import baseline of third party libnfc-nci and hal.
(merged from branch "nxpnfc-project/br_android_ncihalx_m")
Change-Id: I258c2c854d4ffee4605041af3d2132540fd67d59
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/halimpl/bcm2079x/adaptation/CondVar.cpp b/halimpl/bcm2079x/adaptation/CondVar.cpp
new file mode 100644
index 0000000..c2dacdc
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.cpp
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "CondVar.h"
+#include <errno.h>
+#include <string.h>
+
+
+/*******************************************************************************
+**
+** Function: CondVar
+**
+** Description: Initialize member variables.
+**
+** Returns: None.
+**
+*******************************************************************************/
+CondVar::CondVar ()
+{
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ memset (&mCondition, 0, sizeof(mCondition));
+ int const res = pthread_cond_init (&mCondition, &attr);
+ if (res)
+ {
+ ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: ~CondVar
+**
+** Description: Cleanup all resources.
+**
+** Returns: None.
+**
+*******************************************************************************/
+CondVar::~CondVar ()
+{
+ int const res = pthread_cond_destroy (&mCondition);
+ if (res)
+ {
+ ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: wait
+**
+** Description: Block the caller and wait for a condition.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void CondVar::wait (Mutex& mutex)
+{
+ int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
+ if (res)
+ {
+ ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: wait
+**
+** Description: Block the caller and wait for a condition.
+** millisec: Timeout in milliseconds.
+**
+** Returns: True if wait is successful; false if timeout occurs.
+**
+*******************************************************************************/
+bool CondVar::wait (Mutex& mutex, long millisec)
+{
+ bool retVal = false;
+ struct timespec absoluteTime;
+
+ if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
+ {
+ ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
+ }
+ else
+ {
+ absoluteTime.tv_sec += millisec / 1000;
+ long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
+ if (ns > 1000000000)
+ {
+ absoluteTime.tv_sec++;
+ absoluteTime.tv_nsec = ns - 1000000000;
+ }
+ else
+ absoluteTime.tv_nsec = ns;
+ }
+
+ int waitResult = pthread_cond_timedwait (&mCondition, mutex.nativeHandle(), &absoluteTime);
+ if ((waitResult != 0) && (waitResult != ETIMEDOUT))
+ ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
+ retVal = (waitResult == 0); //waited successfully
+ return retVal;
+}
+
+
+/*******************************************************************************
+**
+** Function: notifyOne
+**
+** Description: Unblock the waiting thread.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void CondVar::notifyOne ()
+{
+ int const res = pthread_cond_signal (&mCondition);
+ if (res)
+ {
+ ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
+ }
+}
+
diff --git a/halimpl/bcm2079x/adaptation/CondVar.h b/halimpl/bcm2079x/adaptation/CondVar.h
new file mode 100644
index 0000000..afa3fbf
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/CondVar.h
@@ -0,0 +1,95 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Encapsulate a condition variable for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+#include "Mutex.h"
+
+
+class CondVar
+{
+public:
+ /*******************************************************************************
+ **
+ ** Function: CondVar
+ **
+ ** Description: Initialize member variables.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ CondVar ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: ~CondVar
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~CondVar ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the caller and wait for a condition.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void wait (Mutex& mutex);
+
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the caller and wait for a condition.
+ ** millisec: Timeout in milliseconds.
+ **
+ ** Returns: True if wait is successful; false if timeout occurs.
+ **
+ *******************************************************************************/
+ bool wait (Mutex& mutex, long millisec);
+
+
+ /*******************************************************************************
+ **
+ ** Function: notifyOne
+ **
+ ** Description: Unblock the waiting thread.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void notifyOne ();
+
+private:
+ pthread_cond_t mCondition;
+};
diff --git a/halimpl/bcm2079x/adaptation/HalAdaptation.cpp b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
new file mode 100644
index 0000000..c39bd1e
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/HalAdaptation.cpp
@@ -0,0 +1,415 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * HAL Adaptation Interface (HAI). This interface regulates the interaction
+ * between standard Android HAL and Broadcom-specific HAL. It adapts
+ * Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "HalAdaptation.h"
+#include "SyncEvent.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include <errno.h>
+#include <pthread.h>
+#include <cutils/properties.h>
+#include "buildcfg.h"
+#include "android_logmsg.h"
+extern void delete_hal_non_volatile_store (bool forceDelete);
+extern void verify_hal_non_volatile_store ();
+extern void resetConfig ();
+extern "C"
+{
+#include "userial.h"
+}
+
+extern void configureCrystalFrequency ();
+
+///////////////////////////////////////
+// private declaration, definition
+
+
+static nfc_stack_callback_t* gAndroidHalCallback = NULL;
+static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
+static SyncEvent gOpenCompletedEvent;
+static SyncEvent gPostInitCompletedEvent;
+static SyncEvent gCloseCompletedEvent;
+
+UINT32 ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL; //0x017F00;
+
+static void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status);
+static void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data);
+
+static bool isColdBoot = true;
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern const UINT8 nfca_version_string [];
+extern const UINT8 nfa_version_string [];
+
+tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1 [] =
+{
+ {0x0016403c, 0x00000008},
+ {0x0016403c, 0x00000000},
+ {0x0014008c, 0x00000001},
+ {0, 0}
+};
+
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+///////////////////////////////////////
+
+
+int HaiInitializeLibrary (const bcm2079x_dev_t* device)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ ALOGE ("%s: ver=%s nfa=%s", __FUNCTION__, nfca_version_string, nfa_version_string);
+ int retval = EACCES;
+ unsigned long freq = 0;
+ unsigned long num = 0;
+ char temp[120];
+ int8_t prop_value;
+ UINT8 logLevel = 0;
+
+ logLevel = InitializeGlobalAppLogLevel ();
+
+ if ( GetNumValue ( NAME_GLOBAL_RESET, &num, sizeof ( num ) ) )
+ {
+ if (num == 1)
+ {
+ // Send commands to disable boc
+ p_nfc_hal_dm_pre_set_mem = nfc_hal_pre_set_mem_20795a1;
+ }
+ }
+
+ configureCrystalFrequency ();
+ verify_hal_non_volatile_store ();
+ if ( GetNumValue ( NAME_PRESERVE_STORAGE, (char*)&num, sizeof ( num ) ) &&
+ (num == 1) )
+ ALOGD ("%s: preserve HAL NV store", __FUNCTION__);
+ else
+ {
+ delete_hal_non_volatile_store (false);
+ }
+
+ if ( GetNumValue ( NAME_USE_RAW_NCI_TRACE, &num, sizeof ( num ) ) )
+ {
+ if (num == 1)
+ {
+ // display protocol traces in raw format
+ ProtoDispAdapterUseRawOutput (TRUE);
+ }
+ }
+
+ // Initialize protocol logging level
+ InitializeProtocolLogLevel ();
+
+ tUSERIAL_OPEN_CFG cfg;
+ struct tUART_CONFIG uart;
+
+ if ( GetStrValue ( NAME_UART_PARITY, temp, sizeof ( temp ) ) )
+ {
+ if ( strcmp ( temp, "even" ) == 0 )
+ uart.m_iParity = USERIAL_PARITY_EVEN;
+ else if ( strcmp ( temp, "odd" ) == 0 )
+ uart.m_iParity = USERIAL_PARITY_ODD;
+ else if ( strcmp ( temp, "none" ) == 0 )
+ uart.m_iParity = USERIAL_PARITY_NONE;
+ }
+ else
+ uart.m_iParity = USERIAL_PARITY_NONE;
+
+ if ( GetStrValue ( NAME_UART_STOPBITS, temp, sizeof ( temp ) ) )
+ {
+ if ( strcmp ( temp, "1" ) == 0 )
+ uart.m_iStopbits = USERIAL_STOPBITS_1;
+ else if ( strcmp ( temp, "2" ) == 0 )
+ uart.m_iStopbits = USERIAL_STOPBITS_2;
+ else if ( strcmp ( temp, "1.5" ) == 0 )
+ uart.m_iStopbits = USERIAL_STOPBITS_1_5;
+ }
+ else if ( GetNumValue ( NAME_UART_STOPBITS, &num, sizeof ( num ) ) )
+ {
+ if ( num == 1 )
+ uart.m_iStopbits = USERIAL_STOPBITS_1;
+ else if ( num == 2 )
+ uart.m_iStopbits = USERIAL_STOPBITS_2;
+ }
+ else
+ uart.m_iStopbits = USERIAL_STOPBITS_1;
+
+ if ( GetNumValue ( NAME_UART_DATABITS, &num, sizeof ( num ) ) )
+ {
+ if ( 5 <= num && num <= 8 )
+ uart.m_iDatabits = ( 1 << ( num + 1 ) );
+ }
+ else
+ uart.m_iDatabits = USERIAL_DATABITS_8;
+
+ if ( GetNumValue ( NAME_UART_BAUD, &num, sizeof ( num ) ) )
+ {
+ if ( num == 300 ) uart.m_iBaudrate = USERIAL_BAUD_300;
+ else if ( num == 600 ) uart.m_iBaudrate = USERIAL_BAUD_600;
+ else if ( num == 1200 ) uart.m_iBaudrate = USERIAL_BAUD_1200;
+ else if ( num == 2400 ) uart.m_iBaudrate = USERIAL_BAUD_2400;
+ else if ( num == 9600 ) uart.m_iBaudrate = USERIAL_BAUD_9600;
+ else if ( num == 19200 ) uart.m_iBaudrate = USERIAL_BAUD_19200;
+ else if ( num == 57600 ) uart.m_iBaudrate = USERIAL_BAUD_57600;
+ else if ( num == 115200 ) uart.m_iBaudrate = USERIAL_BAUD_115200;
+ else if ( num == 230400 ) uart.m_iBaudrate = USERIAL_BAUD_230400;
+ else if ( num == 460800 ) uart.m_iBaudrate = USERIAL_BAUD_460800;
+ else if ( num == 921600 ) uart.m_iBaudrate = USERIAL_BAUD_921600;
+ }
+ else if ( GetStrValue ( NAME_UART_BAUD, temp, sizeof ( temp ) ) )
+ {
+ if ( strcmp ( temp, "auto" ) == 0 )
+ uart.m_iBaudrate = USERIAL_BAUD_AUTO;
+ }
+ else
+ uart.m_iBaudrate = USERIAL_BAUD_115200;
+
+ memset (&cfg, 0, sizeof(tUSERIAL_OPEN_CFG));
+ cfg.fmt = uart.m_iDatabits | uart.m_iParity | uart.m_iStopbits;
+ cfg.baud = uart.m_iBaudrate;
+
+ ALOGD ("%s: uart config=0x%04x, %d\n", __func__, cfg.fmt, cfg.baud);
+ USERIAL_Init(&cfg);
+
+ if ( GetNumValue ( NAME_NFCC_ENABLE_TIMEOUT, &num, sizeof ( num ) ) )
+ {
+ p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout = num;
+ }
+
+ if ( GetNumValue ( NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof ( num ) ) && num == 0 )
+ {
+ // Since NFA_MAX_EE_SUPPORTED is explicetly set to 0, no UICC support is needed.
+ p_nfc_hal_cfg->nfc_hal_hci_uicc_support = 0;
+ }
+
+ prop_value = property_get_bool("nfc.bcm2079x.isColdboot", 0);
+ if (prop_value) {
+ isColdBoot = true;
+ property_set("nfc.bcm2079x.isColdboot", "0");
+ }
+ // Set 'first boot' flag based on static variable that will get set to false
+ // after the stack has first initialized the EE.
+ p_nfc_hal_cfg->nfc_hal_first_boot = isColdBoot ? TRUE : FALSE;
+
+ HAL_NfcInitialize ();
+ HAL_NfcSetTraceLevel (logLevel); // Initialize HAL's logging level
+
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiTerminateLibrary ()
+{
+ int retval = EACCES;
+ ALOGD ("%s: enter", __FUNCTION__);
+
+ HAL_NfcTerminate ();
+ gAndroidHalCallback = NULL;
+ gAndroidHalDataCallback = NULL;
+ GKI_shutdown ();
+ resetConfig ();
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ gAndroidHalCallback = halCallbackFunc;
+ gAndroidHalDataCallback = halDataCallbackFunc;
+
+ SyncEventGuard guard (gOpenCompletedEvent);
+ HAL_NfcOpen (BroadcomHalCallback, BroadcomHalDataCallback);
+ gOpenCompletedEvent.wait ();
+
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+void BroadcomHalCallback (UINT8 event, tHAL_NFC_STATUS status)
+{
+ ALOGD ("%s: enter; event=0x%X", __FUNCTION__, event);
+ switch (event)
+ {
+ case HAL_NFC_OPEN_CPLT_EVT:
+ {
+ ALOGD ("%s: HAL_NFC_OPEN_CPLT_EVT; status=0x%X", __FUNCTION__, status);
+ SyncEventGuard guard (gOpenCompletedEvent);
+ gOpenCompletedEvent.notifyOne ();
+ break;
+ }
+
+ case HAL_NFC_POST_INIT_CPLT_EVT:
+ {
+ ALOGD ("%s: HAL_NFC_POST_INIT_CPLT_EVT", __FUNCTION__);
+ SyncEventGuard guard (gPostInitCompletedEvent);
+ gPostInitCompletedEvent.notifyOne ();
+ break;
+ }
+
+ case HAL_NFC_CLOSE_CPLT_EVT:
+ {
+ ALOGD ("%s: HAL_NFC_CLOSE_CPLT_EVT", __FUNCTION__);
+ SyncEventGuard guard (gCloseCompletedEvent);
+ gCloseCompletedEvent.notifyOne ();
+ break;
+ }
+
+ case HAL_NFC_ERROR_EVT:
+ {
+ ALOGD ("%s: HAL_NFC_ERROR_EVT", __FUNCTION__);
+ {
+ SyncEventGuard guard (gOpenCompletedEvent);
+ gOpenCompletedEvent.notifyOne ();
+ }
+ {
+ SyncEventGuard guard (gPostInitCompletedEvent);
+ gPostInitCompletedEvent.notifyOne ();
+ }
+ {
+ SyncEventGuard guard (gCloseCompletedEvent);
+ gCloseCompletedEvent.notifyOne ();
+ }
+ break;
+ }
+ }
+ gAndroidHalCallback (event, status);
+ ALOGD ("%s: exit; event=0x%X", __FUNCTION__, event);
+}
+
+
+void BroadcomHalDataCallback (UINT16 data_len, UINT8* p_data)
+{
+ ALOGD ("%s: enter; len=%u", __FUNCTION__, data_len);
+ gAndroidHalDataCallback (data_len, p_data);
+}
+
+
+int HaiClose (const bcm2079x_dev_t* device)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ SyncEventGuard guard (gCloseCompletedEvent);
+ HAL_NfcClose ();
+ gCloseCompletedEvent.wait ();
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ SyncEventGuard guard (gPostInitCompletedEvent);
+ HAL_NfcCoreInitialized (coreInitResponseParams);
+ gPostInitCompletedEvent.wait ();
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data)
+{
+ ALOGD ("%s: enter; len=%u", __FUNCTION__, dataLen);
+ int retval = EACCES;
+
+ HAL_NfcWrite (dataLen, const_cast<UINT8*> (data));
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiPreDiscover (const bcm2079x_dev_t* device)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ // This function is a clear indication that the stack is initializing
+ // EE. So we can reset the cold-boot flag here.
+ isColdBoot = false;
+ retval = HAL_NfcPreDiscover () ? 1 : 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiControlGranted (const bcm2079x_dev_t* device)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ HAL_NfcControlGranted ();
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiPowerCycle (const bcm2079x_dev_t* device)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ HAL_NfcPowerCycle ();
+ retval = 0;
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee)
+{
+ ALOGD ("%s: enter", __FUNCTION__);
+ int retval = EACCES;
+
+ // This function is a clear indication that the stack is initializing
+ // EE. So we can reset the cold-boot flag here.
+ isColdBoot = false;
+
+ if ( maxNfcee )
+ {
+ *maxNfcee = HAL_NfcGetMaxNfcee ();
+ ALOGD("%s: max_ee from HAL to use %d", __FUNCTION__, *maxNfcee);
+ retval = 0;
+ }
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
diff --git a/halimpl/bcm2079x/adaptation/Mutex.cpp b/halimpl/bcm2079x/adaptation/Mutex.cpp
new file mode 100644
index 0000000..f931493
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.cpp
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "Mutex.h"
+#include <errno.h>
+#include <string.h>
+
+/*******************************************************************************
+**
+** Function: Mutex
+**
+** Description: Initialize member variables.
+**
+** Returns: None.
+**
+*******************************************************************************/
+Mutex::Mutex ()
+{
+ memset (&mMutex, 0, sizeof(mMutex));
+ int res = pthread_mutex_init (&mMutex, NULL);
+ if (res != 0)
+ {
+ ALOGE ("Mutex::Mutex: fail init; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: ~Mutex
+**
+** Description: Cleanup all resources.
+**
+** Returns: None.
+**
+*******************************************************************************/
+Mutex::~Mutex ()
+{
+ int res = pthread_mutex_destroy (&mMutex);
+ if (res != 0)
+ {
+ ALOGE ("Mutex::~Mutex: fail destroy; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: lock
+**
+** Description: Block the thread and try lock the mutex.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void Mutex::lock ()
+{
+ int res = pthread_mutex_lock (&mMutex);
+ if (res != 0)
+ {
+ ALOGE ("Mutex::lock: fail lock; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: unlock
+**
+** Description: Unlock a mutex to unblock a thread.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void Mutex::unlock ()
+{
+ int res = pthread_mutex_unlock (&mMutex);
+ if (res != 0)
+ {
+ ALOGE ("Mutex::unlock: fail unlock; error=0x%X", res);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: tryLock
+**
+** Description: Try to lock the mutex.
+**
+** Returns: True if the mutex is locked.
+**
+*******************************************************************************/
+bool Mutex::tryLock ()
+{
+ int res = pthread_mutex_trylock (&mMutex);
+ if ((res != 0) && (res != EBUSY))
+ {
+ ALOGE ("Mutex::tryLock: error=0x%X", res);
+ }
+ return res == 0;
+}
+
+
+/*******************************************************************************
+**
+** Function: nativeHandle
+**
+** Description: Get the handle of the mutex.
+**
+** Returns: Handle of the mutex.
+**
+*******************************************************************************/
+pthread_mutex_t* Mutex::nativeHandle ()
+{
+ return &mMutex;
+}
+
+
diff --git a/halimpl/bcm2079x/adaptation/Mutex.h b/halimpl/bcm2079x/adaptation/Mutex.h
new file mode 100644
index 0000000..5091894
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/Mutex.h
@@ -0,0 +1,106 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Encapsulate a mutex for thread synchronization.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <pthread.h>
+
+
+class Mutex
+{
+public:
+ /*******************************************************************************
+ **
+ ** Function: Mutex
+ **
+ ** Description: Initialize member variables.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ Mutex ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: ~Mutex
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~Mutex ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: lock
+ **
+ ** Description: Block the thread and try lock the mutex.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void lock ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: unlock
+ **
+ ** Description: Unlock a mutex to unblock a thread.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void unlock ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: tryLock
+ **
+ ** Description: Try to lock the mutex.
+ **
+ ** Returns: True if the mutex is locked.
+ **
+ *******************************************************************************/
+ bool tryLock ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: nativeHandle
+ **
+ ** Description: Get the handle of the mutex.
+ **
+ ** Returns: Handle of the mutex.
+ **
+ *******************************************************************************/
+ pthread_mutex_t* nativeHandle ();
+
+private:
+ pthread_mutex_t mMutex;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
new file mode 100644
index 0000000..f921f99
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/NonVolatileStore.cpp
@@ -0,0 +1,275 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#define LOG_TAG "NfcNciHal"
+#include "gki.h"
+extern "C"
+{
+ #include "nfc_hal_target.h"
+ #include "nfc_hal_nv_ci.h"
+}
+#include "config.h"
+#include "CrcChecksum.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string>
+
+
+//directory of HAL's non-volatile storage
+static const char* default_location = "/data/nfc";
+static const char* filename_prefix = "/halStorage.bin";
+static const std::string get_storage_location ();
+void delete_hal_non_volatile_store (bool forceDelete);
+void verify_hal_non_volatile_store ();
+
+
+/*******************************************************************************
+**
+** Function nfc_hal_nv_co_read
+**
+** Description This function is called by NFA to read in data from the
+** previously opened file.
+**
+** Parameters p_buf - buffer to read the data into.
+** nbytes - number of bytes to read into the buffer.
+**
+** Returns void
+**
+** Note: Upon completion of the request, nfc_hal_nv_ci_read () is
+** called with the buffer of data, along with the number
+** of bytes read into the buffer, and a status. The
+** call-in function should only be called when ALL requested
+** bytes have been read, the end of file has been detected,
+** or an error has occurred.
+**
+*******************************************************************************/
+void nfc_hal_nv_co_read (UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+ std::string fn = get_storage_location();
+ char filename[256];
+
+ fn.append (filename_prefix);
+ if (fn.length() > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
+
+ ALOGD ("%s: buffer len=%u; file=%s", __FUNCTION__, nbytes, filename);
+ int fileStream = open (filename, O_RDONLY);
+ if (fileStream >= 0)
+ {
+ unsigned short checksum = 0;
+ size_t actualReadCrc = read (fileStream, &checksum, sizeof(checksum));
+ size_t actualReadData = read (fileStream, p_buf, nbytes);
+ close (fileStream);
+ if (actualReadData > 0)
+ {
+ ALOGD ("%s: data size=%u", __FUNCTION__, actualReadData);
+ nfc_hal_nv_ci_read (actualReadData, NFC_HAL_NV_CO_OK, block);
+ }
+ else
+ {
+ ALOGE ("%s: fail to read", __FUNCTION__);
+ nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+ }
+ }
+ else
+ {
+ ALOGD ("%s: fail to open", __FUNCTION__);
+ nfc_hal_nv_ci_read (0, NFC_HAL_NV_CO_FAIL, block);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_hal_nv_co_write
+**
+** Description This function is called by io to send file data to the
+** phone.
+**
+** Parameters p_buf - buffer to read the data from.
+** nbytes - number of bytes to write out to the file.
+**
+** Returns void
+**
+** Note: Upon completion of the request, nfc_hal_nv_ci_write () is
+** called with the file descriptor and the status. The
+** call-in function should only be called when ALL requested
+** bytes have been written, or an error has been detected,
+**
+*******************************************************************************/
+void nfc_hal_nv_co_write (const UINT8 *p_buf, UINT16 nbytes, UINT8 block)
+{
+ std::string fn = get_storage_location();
+ char filename[256];
+ int fileStream = 0;
+
+ fn.append (filename_prefix);
+ if (fn.length() > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), block);
+ ALOGD ("%s: bytes=%u; file=%s", __FUNCTION__, nbytes, filename);
+
+ fileStream = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fileStream >= 0)
+ {
+ unsigned short checksum = crcChecksumCompute (p_buf, nbytes);
+ size_t actualWrittenCrc = write (fileStream, &checksum, sizeof(checksum));
+ size_t actualWrittenData = write (fileStream, p_buf, nbytes);
+ ALOGD ("%s: %d bytes written", __FUNCTION__, actualWrittenData);
+ if ((actualWrittenData == nbytes) && (actualWrittenCrc == sizeof(checksum)))
+ {
+ nfc_hal_nv_ci_write (NFC_HAL_NV_CO_OK);
+ }
+ else
+ {
+ ALOGE ("%s: fail to write", __FUNCTION__);
+ nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+ }
+ close (fileStream);
+ }
+ else
+ {
+ ALOGE ("%s: fail to open, error = %d", __FUNCTION__, errno);
+ nfc_hal_nv_ci_write (NFC_HAL_NV_CO_FAIL);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function get_storage_location
+**
+** Description Get the absolute directory path of the HAL's storage location.
+**
+** Parameters none
+**
+** Returns Absolute path.
+**
+*******************************************************************************/
+const std::string get_storage_location ()
+{
+ char buffer [100];
+ memset (buffer, 0, sizeof(buffer));
+ if (!GetStrValue (NAME_NFA_STORAGE, buffer, sizeof(buffer)))
+ return default_location;
+ else
+ return std::string (buffer);
+}
+
+
+/*******************************************************************************
+**
+** Function delete_hal_non_volatile_store
+**
+** Description Delete all the content of the HAL's storage location.
+**
+** Parameters forceDelete: unconditionally delete the storage.
+**
+** Returns none
+**
+*******************************************************************************/
+void delete_hal_non_volatile_store (bool forceDelete)
+{
+ static bool firstTime = true;
+ std::string fn = get_storage_location();
+ char filename[256];
+ int stat = 0;
+
+ if ((firstTime == false) && (forceDelete == false))
+ return;
+ firstTime = false;
+
+ ALOGD ("%s", __FUNCTION__);
+
+ fn.append (filename_prefix);
+ if (fn.length() > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+ remove (filename);
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+ remove (filename);
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+ remove (filename);
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+ remove (filename);
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+ remove (filename);
+}
+
+
+/*******************************************************************************
+**
+** Function verify_hal_non_volatile_store
+**
+** Description Verify the content of all non-volatile store.
+**
+** Parameters none
+**
+** Returns none
+**
+*******************************************************************************/
+void verify_hal_non_volatile_store ()
+{
+ ALOGD ("%s", __FUNCTION__);
+ std::string fn = get_storage_location();
+ char filename[256];
+ bool isValid = false;
+
+ fn.append (filename_prefix);
+ if (fn.length() > 200)
+ {
+ ALOGE ("%s: filename too long", __FUNCTION__);
+ return;
+ }
+
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), DH_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F3_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F4_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F2_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ {
+ snprintf (filename, sizeof(filename), "%s%u", fn.c_str(), HC_F5_NV_BLOCK);
+ if (crcChecksumVerifyIntegrity (filename))
+ isValid = true;
+ }
+ }
+ }
+ }
+
+ if (isValid == false)
+ delete_hal_non_volatile_store (true);
+}
diff --git a/halimpl/bcm2079x/adaptation/OverrideLog.cpp b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
new file mode 100644
index 0000000..ce40d8a
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/OverrideLog.cpp
@@ -0,0 +1,102 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Override the ALOGD(), ALOGE(), and other logging macros from
+ * /system/core/include/cutils/log.h
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include <cutils/properties.h>
+#include <string.h>
+#include "config.h"
+#include "android_logmsg.h"
+#define LOG_TAG "NfcNciHal"
+
+
+unsigned char appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+
+/*******************************************************************************
+**
+** Function: InitializeGlobalAppLogLevel
+**
+** Description: Initialize and get global logging level from
+** Android property nfc.app_log_level.
+**
+** Returns: Global log level:
+** BT_TRACE_LEVEL_NONE 0 * No trace messages to be generated
+** BT_TRACE_LEVEL_ERROR 1 * Error condition trace messages
+** BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+** BT_TRACE_LEVEL_API 3 * API traces
+** BT_TRACE_LEVEL_EVENT 4 * Debug messages for events
+** BT_TRACE_LEVEL_DEBUG 5 * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ()
+{
+ unsigned long num = 0;
+ char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+ num = 1;
+ if (GetNumValue (NAME_APPL_TRACE_LEVEL, &num, sizeof(num)))
+ appl_trace_level = (unsigned char) num;
+
+ int len = property_get ("nfc.app_log_level", valueStr, "");
+ if (len > 0)
+ {
+ //let Android property override default value
+ sscanf (valueStr, "%lu", &num);
+ appl_trace_level = (unsigned char) num;
+ }
+
+ //0xFF is a special value used by the stack to query the current
+ //trace level; it does not change any trace level
+ if (appl_trace_level == 0xFF)
+ appl_trace_level = BT_TRACE_LEVEL_DEBUG;
+ ALOGD ("%s: level=%u", __FUNCTION__, appl_trace_level);
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ {
+ //display protocol traces in raw format
+ ProtoDispAdapterUseRawOutput (TRUE);
+ }
+ return appl_trace_level;
+}
+
+UINT32 InitializeProtocolLogLevel () {
+ UINT32 num = 0;
+ char valueStr [PROPERTY_VALUE_MAX] = {0};
+
+ if ( GetNumValue ( NAME_PROTOCOL_TRACE_LEVEL, &num, sizeof ( num ) ) )
+ ScrProtocolTraceFlag = num;
+
+ int len = property_get ("nfc.enable_protocol_log", valueStr, "");
+ if (len > 0)
+ {
+ if (strncmp("0", valueStr, 1) == 0)
+ {
+ ScrProtocolTraceFlag = 0;
+ } else {
+ ScrProtocolTraceFlag = ~0;
+ }
+ }
+
+ return ScrProtocolTraceFlag;
+}
+
diff --git a/halimpl/bcm2079x/adaptation/StartupConfig.cpp b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
new file mode 100644
index 0000000..f296763
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/StartupConfig.cpp
@@ -0,0 +1,155 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "StartupConfig.h"
+
+
+const UINT8 StartupConfig::mMaxLength = 255;
+
+
+/*******************************************************************************
+**
+** Function: initialize
+**
+** Description: Initialize all member variables.
+**
+** Returns: None
+**
+*******************************************************************************/
+StartupConfig::StartupConfig ()
+{
+ //set first byte to 0, which is length of payload
+ mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function: initialize
+**
+** Description: Reset all member variables.
+**
+** Returns: None
+**
+*******************************************************************************/
+void StartupConfig::initialize ()
+{
+ mBuffer.clear ();
+ //set first byte to 0, which is length of payload
+ mBuffer.append ((uint8_string::size_type) 1, (uint8_string::value_type) 0);
+}
+
+
+/*******************************************************************************
+**
+** Function: getInternalBuffer
+**
+** Description: Get the pointer to buffer that contains multiple
+** Type-Length-Value contents.
+**
+** Returns: Pointer to buffer.
+**
+*******************************************************************************/
+const UINT8* StartupConfig::getInternalBuffer ()
+{
+ return mBuffer.data ();
+}
+
+
+/*******************************************************************************
+**
+** Function: append
+**
+** Description: Append new config data to internal buffer.
+** newContent: buffer containing new content; newContent[0] is
+** payload length; newContent[1..end] is payload.
+** newContentLen: total length of newContent.
+**
+** Returns: True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::append (const UINT8* newContent, UINT8 newContentLen)
+{
+ static const char fn [] = "StartupConfig::append";
+ if ((newContentLen+mBuffer.size()) > mMaxLength)
+ {
+ ALOGE ("%s: exceed max length", fn);
+ return false;
+ }
+
+ ALOGD ("%s: try append %u bytes", fn, (uint8_string::size_type) (newContentLen));
+ //append new payload into private buffer
+ mBuffer.append (newContent+1, (uint8_string::size_type) (newContentLen-1));
+ //increase size counter of payload in private buffer
+ mBuffer[0] = mBuffer[0] + newContentLen-1;
+ ALOGD ("%s: new size %u bytes", fn, mBuffer[0]);
+ return true;
+};
+
+
+/*******************************************************************************
+**
+** Function: disableSecureElement
+**
+** Description: Adjust a TLV to disable secure element(s). The TLV's type is 0xC2.
+** bitmask: 0xC0 = do not detect any secure element.
+** 0x40 = do not detect secure element in slot 0.
+** 0x80 = do not detect secure element in slot 1.
+**
+** Returns: True if ok.
+**
+*******************************************************************************/
+bool StartupConfig::disableSecureElement (UINT8 bitmask)
+{
+ const UINT8 maxLen = mBuffer[0];
+ UINT8 index = 1, tlvType = 0, tlvLen = 0;
+ bool found0xC2 = false;
+
+ while (true)
+ {
+ if (index > maxLen)
+ break;
+ tlvType = mBuffer [index];
+ index++;
+ tlvLen = mBuffer [index];
+ index++;
+ if (tlvType == 0xC2) //this TLV controls secure elements
+ {
+ index++; //index of second byte in TLV's value
+ mBuffer [index] = mBuffer [index] | bitmask; //turn on certain bits
+ found0xC2 = true;
+ }
+ else
+ index += tlvLen;
+ }
+
+ if (found0xC2 == false)
+ {
+ UINT8 tlv [] = {0x04, 0xC2, 0x02, 0x61, 0x00};
+ tlv [4] = tlv [4] | bitmask;
+ found0xC2 = append (tlv, 5);
+ }
+ return found0xC2;
+}
diff --git a/halimpl/bcm2079x/adaptation/SyncEvent.h b/halimpl/bcm2079x/adaptation/SyncEvent.h
new file mode 100644
index 0000000..2a56aca
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/SyncEvent.h
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Synchronize two or more threads using a condition variable and a mutex.
+ *
+ ******************************************************************************/
+#pragma once
+#include "CondVar.h"
+#include "Mutex.h"
+
+
+class SyncEvent
+{
+public:
+ /*******************************************************************************
+ **
+ ** Function: ~SyncEvent
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~SyncEvent ()
+ {
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function: start
+ **
+ ** Description: Start a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void start ()
+ {
+ mMutex.lock ();
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the thread and wait for the event to occur.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void wait ()
+ {
+ mCondVar.wait (mMutex);
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the thread and wait for the event to occur.
+ ** millisec: Timeout in milliseconds.
+ **
+ ** Returns: True if wait is successful; false if timeout occurs.
+ **
+ *******************************************************************************/
+ bool wait (long millisec)
+ {
+ bool retVal = mCondVar.wait (mMutex, millisec);
+ return retVal;
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function: notifyOne
+ **
+ ** Description: Notify a blocked thread that the event has occured. Unblocks it.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void notifyOne ()
+ {
+ mCondVar.notifyOne ();
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function: end
+ **
+ ** Description: End a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void end ()
+ {
+ mMutex.unlock ();
+ }
+
+private:
+ CondVar mCondVar;
+ Mutex mMutex;
+};
+
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+
+/*****************************************************************************
+**
+** Name: SyncEventGuard
+**
+** Description: Automatically start and end a synchronization event.
+**
+*****************************************************************************/
+class SyncEventGuard
+{
+public:
+ /*******************************************************************************
+ **
+ ** Function: SyncEventGuard
+ **
+ ** Description: Start a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ SyncEventGuard (SyncEvent& event)
+ : mEvent (event)
+ {
+ event.start (); //automatically start operation
+ };
+
+
+ /*******************************************************************************
+ **
+ ** Function: ~SyncEventGuard
+ **
+ ** Description: End a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~SyncEventGuard ()
+ {
+ mEvent.end (); //automatically end operation
+ };
+
+private:
+ SyncEvent& mEvent;
+};
+
diff --git a/halimpl/bcm2079x/adaptation/android_logmsg.cpp b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
new file mode 100644
index 0000000..86fc9b8
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/android_logmsg.cpp
@@ -0,0 +1,360 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "android_logmsg.h"
+#include "nfc_target.h"
+#include "buildcfg.h"
+#include <cutils/log.h>
+
+
+extern UINT32 ScrProtocolTraceFlag;
+#define MAX_NCI_PACKET_SIZE 259
+#define BTE_LOG_BUF_SIZE 1024
+#define BTE_LOG_MAX_SIZE (BTE_LOG_BUF_SIZE - 12)
+#define MAX_LOGCAT_LINE 4096
+#define PRINT(s) __android_log_write (ANDROID_LOG_DEBUG, "BrcmNci", s)
+static char log_line [MAX_LOGCAT_LINE];
+static const char* sTable = "0123456789abcdef";
+static BOOLEAN sIsUseRaw = FALSE;
+static void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize);
+static void dumpbin (const char* data, int size, UINT32 trace_layer, UINT32 trace_type);
+static inline void word2hex (const char* data, char** hex);
+static inline void byte2char (const char* data, char** str);
+static inline void byte2hex (const char* data, char** str);
+
+
+void BTDISP_LOCK_LOG()
+{
+}
+
+
+void BTDISP_UNLOCK_LOG()
+{
+}
+
+
+void BTDISP_INIT_LOCK()
+{
+}
+
+
+void BTDISP_UNINIT_LOCK()
+{
+}
+
+
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw)
+{
+ sIsUseRaw = isUseRaw;
+}
+
+
+void ProtoDispAdapterDisplayNciPacket (UINT8 *nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv)
+{
+ //Protocol decoder is not available, so decode NCI packet into hex numbers.
+ if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_NCI))
+ return;
+ char line_buf [(MAX_NCI_PACKET_SIZE*2)+1];
+ ToHex (nciPacket, nciPacketLen, line_buf, sizeof(line_buf));
+ __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmNciR": "BrcmNciX", line_buf);
+}
+
+
+void ToHex (const UINT8* data, UINT16 len, char* hexString, UINT16 hexStringSize)
+{
+ int i=0, j=0;
+ for(i = 0, j = 0; i < len && j < hexStringSize-3; i++)
+ {
+ hexString [j++] = sTable [(*data >> 4) & 0xf];
+ hexString [j++] = sTable [*data & 0xf];
+ data++;
+ }
+ hexString [j] = '\0';
+}
+
+
+//Protodisp code calls ScrLog() to print decoded texts.
+void ScrLog (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+ static char buffer [BTE_LOG_BUF_SIZE];
+ va_list ap;
+
+ va_start (ap, fmt_str);
+ vsnprintf (buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+ va_end (ap);
+ __android_log_write(ANDROID_LOG_INFO, "BrcmNci", buffer);
+}
+
+
+UINT8 *scru_dump_hex (UINT8 *p, char *pTitle, UINT32 len, UINT32 layer, UINT32 type)
+{
+ if(pTitle && *pTitle)
+ PRINT(pTitle);
+ dumpbin((char*) p, len, layer, type);
+ return p;
+}
+
+
+void dumpbin(const char* data, int size, UINT32 trace_layer, UINT32 trace_type)
+{
+ char line_buff[256];
+ char *line;
+ int i, j, addr;
+ const int width = 16;
+ if(size <= 0)
+ return;
+ for(i = 0; i < size / width; i++)
+ {
+ line = line_buff;
+ //write address:
+ addr = i*width;
+ word2hex((const char*)&addr, &line);
+ *line++ = ':'; *line++ = ' ';
+ //write hex of data
+ for(j = 0; j < width; j++)
+ {
+ byte2hex(&data[j], &line);
+ *line++ = ' ';
+ }
+ //write char of data
+ for(j = 0; j < width; j++)
+ byte2char(data++, &line);
+ //wirte the end of line
+ *line = 0;
+ //output the line
+ PRINT(line_buff);
+ }
+ //last line of left over if any
+ int leftover = size % width;
+ if(leftover > 0)
+ {
+ line = line_buff;
+ //write address:
+ addr = i*width;
+ word2hex((const char*)&addr, &line);
+ *line++ = ':'; *line++ = ' ';
+ //write hex of data
+ for(j = 0; j < leftover; j++)
+ {
+ byte2hex(&data[j], &line);
+ *line++ = ' ';
+ }
+ //write hex padding
+ for(; j < width; j++)
+ {
+ *line++ = ' ';
+ *line++ = ' ';
+ *line++ = ' ';
+ }
+ //write char of data
+ for(j = 0; j < leftover; j++)
+ byte2char(data++, &line);
+ //write the end of line
+ *line = 0;
+ //output the line
+ PRINT(line_buff);
+ }
+}
+
+
+inline void word2hex (const char* data, char** hex)
+{
+ byte2hex(&data[1], hex);
+ byte2hex(&data[0], hex);
+}
+
+
+inline void byte2char (const char* data, char** str)
+{
+ **str = *data < ' ' ? '.' : *data > '~' ? '.' : *data;
+ ++(*str);
+}
+
+
+inline void byte2hex (const char* data, char** str)
+{
+ **str = sTable[(*data >> 4) & 0xf];
+ ++*str;
+ **str = sTable[*data & 0xf];
+ ++*str;
+}
+
+
+ //Decode a few Bluetooth HCI packets into hex numbers.
+ void DispHciCmd (BT_HDR *p_buf)
+ {
+ UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+ UINT8* data = (UINT8*) p_buf;
+ int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ return;
+
+ if (nBytes > sizeof(log_line))
+ return;
+
+ ToHex (data, data_len, log_line, sizeof(log_line));
+ __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciX", log_line);
+ }
+
+
+ //Decode a few Bluetooth HCI packets into hex numbers.
+ void DispHciEvt (BT_HDR *p_buf)
+ {
+ UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+ UINT8* data = (UINT8*) p_buf;
+ int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ return;
+
+ if (nBytes > sizeof(log_line))
+ return;
+
+ ToHex (data, data_len, log_line, sizeof(log_line));
+ __android_log_write (ANDROID_LOG_DEBUG, "BrcmHciR", log_line);
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function DispLLCP
+ **
+ ** Description Log LLCP packet as hex-ascii bytes.
+ **
+ ** Returns None.
+ **
+ *******************************************************************************/
+ void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv)
+ {
+ UINT32 nBytes = ((BT_HDR_SIZE + p_buf->offset + p_buf->len)*2)+1;
+ UINT8 * data = (UINT8*) p_buf;
+ int data_len = BT_HDR_SIZE + p_buf->offset + p_buf->len;
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ return;
+
+ if (nBytes > sizeof(log_line))
+ return;
+
+ ToHex (data, data_len, log_line, sizeof(log_line));
+ __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmLlcpR": "BrcmLlcpX", log_line);
+ }
+
+
+ /*******************************************************************************
+ **
+ ** Function DispHcp
+ **
+ ** Description Log raw HCP packet as hex-ascii bytes
+ **
+ ** Returns None.
+ **
+ *******************************************************************************/
+ void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv)
+ {
+ UINT32 nBytes = (len*2)+1;
+
+ if (appl_trace_level < BT_TRACE_LEVEL_DEBUG)
+ return;
+
+ // Only trace HCP if we're tracing HCI as well
+ if (!(ScrProtocolTraceFlag & SCR_PROTO_TRACE_HCI_SUMMARY))
+ return;
+
+ if (nBytes > sizeof(log_line))
+ return;
+
+ ToHex (data, len, log_line, sizeof(log_line));
+ __android_log_write (ANDROID_LOG_DEBUG, (is_recv) ? "BrcmHcpR": "BrcmHcpX", log_line);
+ }
+
+
+ void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx) {}
+ void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx) {}
+ void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx) {}
+ void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+ void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx) {}
+ void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond) {}
+ void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv) {}
+
+
+/*******************************************************************************
+**
+** Function: LogMsg
+**
+** Description: Print messages from NFC stack.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...)
+{
+ static char buffer [BTE_LOG_BUF_SIZE];
+ va_list ap;
+ UINT32 trace_type = trace_set_mask & 0x07; //lower 3 bits contain trace type
+ int android_log_type = ANDROID_LOG_INFO;
+
+ va_start (ap, fmt_str);
+ vsnprintf (buffer, BTE_LOG_MAX_SIZE, fmt_str, ap);
+ va_end (ap);
+ if (trace_type == TRACE_TYPE_ERROR)
+ android_log_type = ANDROID_LOG_ERROR;
+ __android_log_write (android_log_type, LOGMSG_TAG_NAME, buffer);
+}
+
+
+void LogMsg_0 (UINT32 maskTraceSet, const char *p_str)
+{
+ LogMsg (maskTraceSet, p_str);
+}
+
+
+void LogMsg_1 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1)
+{
+ LogMsg (maskTraceSet, fmt_str, p1);
+}
+
+
+void LogMsg_2 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2)
+{
+ LogMsg (maskTraceSet, fmt_str, p1, p2);
+}
+
+
+void LogMsg_3 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3)
+{
+ LogMsg (maskTraceSet, fmt_str, p1, p2, p3);
+}
+
+
+void LogMsg_4 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4)
+{
+ LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4);
+}
+
+void LogMsg_5 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5)
+{
+ LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5);
+}
+
+
+void LogMsg_6 (UINT32 maskTraceSet, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6)
+{
+ LogMsg (maskTraceSet, fmt_str, p1, p2, p3, p4, p5, p6);
+}
diff --git a/halimpl/bcm2079x/adaptation/config.cpp b/halimpl/bcm2079x/adaptation/config.cpp
new file mode 100644
index 0000000..f847389
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/config.cpp
@@ -0,0 +1,736 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include <stdio.h>
+#include <string>
+#include <vector>
+#include <list>
+
+#define LOG_TAG "NfcNciHal"
+
+const char transport_config_path[] = "/etc/";
+
+#define config_name "libnfc-brcm.conf"
+#define extra_config_base "libnfc-brcm-"
+#define extra_config_ext ".conf"
+#define IsStringValue 0x80000000
+
+using namespace::std;
+
+class CNfcParam : public string
+{
+public:
+ CNfcParam();
+ CNfcParam(const char* name, const string& value);
+ CNfcParam(const char* name, unsigned long value);
+ virtual ~CNfcParam();
+ unsigned long numValue() const {return m_numValue;}
+ const char* str_value() const {return m_str_value.c_str();}
+ size_t str_len() const {return m_str_value.length();}
+private:
+ string m_str_value;
+ unsigned long m_numValue;
+};
+
+class CNfcConfig : public vector<const CNfcParam*>
+{
+public:
+ virtual ~CNfcConfig();
+ static CNfcConfig& GetInstance();
+ friend void readOptionalConfig(const char* optional);
+
+ bool getValue(const char* name, char* pValue, size_t& len) const;
+ bool getValue(const char* name, unsigned long& rValue) const;
+ bool getValue(const char* name, unsigned short & rValue) const;
+ const CNfcParam* find(const char* p_name) const;
+ void clean();
+private:
+ CNfcConfig();
+ bool readConfig(const char* name, bool bResetContent);
+ void moveFromList();
+ void moveToList();
+ void add(const CNfcParam* pParam);
+ list<const CNfcParam*> m_list;
+ bool mValidFile;
+
+ unsigned long state;
+
+ inline bool Is(unsigned long f) {return (state & f) == f;}
+ inline void Set(unsigned long f) {state |= f;}
+ inline void Reset(unsigned long f) {state &= ~f;}
+};
+
+/*******************************************************************************
+**
+** Function: isPrintable()
+**
+** Description: detremine if a char is printable
+**
+** Returns: none
+**
+*******************************************************************************/
+inline bool isPrintable(char c)
+{
+ return (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '/' || c == '_' || c == '-' || c == '.';
+}
+
+/*******************************************************************************
+**
+** Function: isDigit()
+**
+** Description: detremine if a char is numeral digit
+**
+** Returns: none
+**
+*******************************************************************************/
+inline bool isDigit(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return true;
+ if (base == 16)
+ {
+ if (('A' <= c && c <= 'F') ||
+ ('a' <= c && c <= 'f') )
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: getDigitValue()
+**
+** Description: return numercal value of a char
+**
+** Returns: none
+**
+*******************************************************************************/
+inline int getDigitValue(char c, int base)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if (base == 16)
+ {
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ else if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::readConfig()
+**
+** Description: read Config settings and parse them into a linked list
+** move the element from linked list to a array at the end
+**
+** Returns: none
+**
+*******************************************************************************/
+bool CNfcConfig::readConfig(const char* name, bool bResetContent)
+{
+ enum {
+ BEGIN_LINE = 1,
+ TOKEN,
+ STR_VALUE,
+ NUM_VALUE,
+ BEGIN_HEX,
+ BEGIN_QUOTE,
+ END_LINE
+ };
+
+ FILE* fd = NULL;
+ string token;
+ string strValue;
+ unsigned long numValue = 0;
+ CNfcParam* pParam = NULL;
+ int i = 0;
+ int base = 0;
+ char c = 0;
+
+ state = BEGIN_LINE;
+ /* open config file, read it into a buffer */
+ if ((fd = fopen(name, "rb")) == NULL)
+ {
+ ALOGD("%s Cannot open config file %s\n", __func__, name);
+ if (bResetContent)
+ {
+ ALOGD("%s Using default value for all settings\n", __func__);
+ mValidFile = false;
+ }
+ return false;
+ }
+ ALOGD("%s Opened %s config %s\n", __func__, (bResetContent ? "base" : "optional"), name);
+
+ mValidFile = true;
+ if (size() > 0)
+ {
+ if (bResetContent)
+ clean();
+ else
+ moveToList();
+ }
+
+ while (!feof(fd) && fread(&c, 1, 1, fd) == 1)
+ {
+ switch (state & 0xff)
+ {
+ case BEGIN_LINE:
+ if (c == '#')
+ state = END_LINE;
+ else if (isPrintable(c))
+ {
+ i = 0;
+ token.erase();
+ strValue.erase();
+ state = TOKEN;
+ token.push_back(c);
+ }
+ break;
+ case TOKEN:
+ if (c == '=')
+ {
+ token.push_back('\0');
+ state = BEGIN_QUOTE;
+ }
+ else if (isPrintable(c))
+ token.push_back(c);
+ else
+ state = END_LINE;
+ break;
+ case BEGIN_QUOTE:
+ if (c == '"')
+ {
+ state = STR_VALUE;
+ base = 0;
+ }
+ else if (c == '0')
+ state = BEGIN_HEX;
+ else if (isDigit(c, 10))
+ {
+ state = NUM_VALUE;
+ base = 10;
+ numValue = getDigitValue(c, base);
+ i = 0;
+ }
+ else if (c == '{')
+ {
+ state = NUM_VALUE;
+ base = 16;
+ i = 0;
+ Set(IsStringValue);
+ }
+ else
+ state = END_LINE;
+ break;
+ case BEGIN_HEX:
+ if (c == 'x' || c == 'X')
+ {
+ state = NUM_VALUE;
+ base = 16;
+ numValue = 0;
+ i = 0;
+ break;
+ }
+ else if (isDigit(c, 10))
+ {
+ state = NUM_VALUE;
+ base = 10;
+ numValue = getDigitValue(c, base);
+ break;
+ }
+ else if (c != '\n' && c != '\r')
+ {
+ state = END_LINE;
+ break;
+ }
+ // fal through to numValue to handle numValue
+
+ case NUM_VALUE:
+ if (isDigit(c, base))
+ {
+ numValue *= base;
+ numValue += getDigitValue(c, base);
+ ++i;
+ }
+ else if (base == 16 && (c == ':' || c == '-' || c == ' ' || c == '}'))
+ {
+ if (i > 0)
+ {
+ int n = (i+1) / 2;
+ while (n-- > 0)
+ {
+ unsigned char c = (numValue >> (n * 8)) & 0xFF;
+ strValue.push_back(c);
+ }
+ }
+ Set(IsStringValue);
+ numValue = 0;
+ i = 0;
+ }
+ else
+ {
+ if (c == '\n' || c == '\r')
+ state = BEGIN_LINE;
+ else
+ state = END_LINE;
+ if (Is(IsStringValue) && base == 16 && i > 0)
+ {
+ int n = (i+1) / 2;
+ while (n-- > 0)
+ strValue.push_back(((numValue >> (n * 8)) & 0xFF));
+ }
+ if (strValue.length() > 0)
+ pParam = new CNfcParam(token.c_str(), strValue);
+ else
+ pParam = new CNfcParam(token.c_str(), numValue);
+ add(pParam);
+ strValue.erase();
+ numValue = 0;
+ }
+ break;
+ case STR_VALUE:
+ if (c == '"')
+ {
+ strValue.push_back('\0');
+ state = END_LINE;
+ pParam = new CNfcParam(token.c_str(), strValue);
+ add(pParam);
+ }
+ else if (isPrintable(c))
+ strValue.push_back(c);
+ break;
+ case END_LINE:
+ if (c == '\n' || c == '\r')
+ state = BEGIN_LINE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ fclose(fd);
+
+ moveFromList();
+ return size() > 0;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::CNfcConfig()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig::CNfcConfig() :
+ mValidFile(true)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::~CNfcConfig()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig::~CNfcConfig()
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::GetInstance()
+**
+** Description: get class singleton object
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcConfig& CNfcConfig::GetInstance()
+{
+ static CNfcConfig theInstance;
+
+ if (theInstance.size() == 0 && theInstance.mValidFile)
+ {
+ string strPath;
+ strPath.assign(transport_config_path);
+ strPath += config_name;
+ theInstance.readConfig(strPath.c_str(), true);
+ }
+
+ return theInstance;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a string value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, char* pValue, size_t& len) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() > 0)
+ {
+ memset(pValue, 0, len);
+ if (len > pParam->str_len())
+ len = pParam->str_len();
+ memcpy(pValue, pParam->str_value(), len);
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a long numerical value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned long& rValue) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() == 0)
+ {
+ rValue = static_cast<unsigned long>(pParam->numValue());
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::getValue()
+**
+** Description: get a short numerical value of a setting
+**
+** Returns: true if setting exists
+** false if setting does not exist
+**
+*******************************************************************************/
+bool CNfcConfig::getValue(const char* name, unsigned short& rValue) const
+{
+ const CNfcParam* pParam = find(name);
+ if (pParam == NULL)
+ return false;
+
+ if (pParam->str_len() == 0)
+ {
+ rValue = static_cast<unsigned short>(pParam->numValue());
+ return true;
+ }
+ return false;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::find()
+**
+** Description: search if a setting exist in the setting array
+**
+** Returns: pointer to the setting object
+**
+*******************************************************************************/
+const CNfcParam* CNfcConfig::find(const char* p_name) const
+{
+ if (size() == 0)
+ return NULL;
+
+ for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ {
+ if (**it < p_name)
+ continue;
+ else if (**it == p_name)
+ {
+ if((*it)->str_len() > 0)
+ ALOGD("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
+ else
+ ALOGD("%s found %s=(0x%lX)\n", __func__, p_name, (*it)->numValue());
+ return *it;
+ }
+ else
+ break;
+ }
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::clean()
+**
+** Description: reset the setting array
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::clean()
+{
+ if (size() == 0)
+ return;
+
+ for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ delete *it;
+ clear();
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::Add()
+**
+** Description: add a setting object to the list
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::add(const CNfcParam* pParam)
+{
+ if (m_list.size() == 0)
+ {
+ m_list.push_back(pParam);
+ return;
+ }
+ for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+ {
+ if (**it < pParam->c_str())
+ continue;
+ m_list.insert(it, pParam);
+ return;
+ }
+ m_list.push_back(pParam);
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::moveFromList()
+**
+** Description: move the setting object from list to array
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::moveFromList()
+{
+ if (m_list.size() == 0)
+ return;
+
+ for (list<const CNfcParam*>::iterator it = m_list.begin(), itEnd = m_list.end(); it != itEnd; ++it)
+ push_back(*it);
+ m_list.clear();
+}
+
+/*******************************************************************************
+**
+** Function: CNfcConfig::moveToList()
+**
+** Description: move the setting object from array to list
+**
+** Returns: none
+**
+*******************************************************************************/
+void CNfcConfig::moveToList()
+{
+ if (m_list.size() != 0)
+ m_list.clear();
+
+ for (iterator it = begin(), itEnd = end(); it != itEnd; ++it)
+ m_list.push_back(*it);
+ clear();
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam() :
+ m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::~CNfcParam()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::~CNfcParam()
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, const string& value) :
+ string(name),
+ m_str_value(value),
+ m_numValue(0)
+{
+}
+
+/*******************************************************************************
+**
+** Function: CNfcParam::CNfcParam()
+**
+** Description: class copy constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+CNfcParam::CNfcParam(const char* name, unsigned long value) :
+ string(name),
+ m_numValue(value)
+{
+}
+
+/*******************************************************************************
+**
+** Function: GetStrValue
+**
+** Description: API function for getting a string value of a setting
+**
+** Returns: none
+**
+*******************************************************************************/
+extern "C" int GetStrValue(const char* name, char* pValue, unsigned long l)
+{
+ size_t len = l;
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+ bool b = rConfig.getValue(name, pValue, len);
+ return b ? len : 0;
+}
+
+/*******************************************************************************
+**
+** Function: GetNumValue
+**
+** Description: API function for getting a numerical value of a setting
+**
+** Returns: none
+**
+*******************************************************************************/
+extern "C" int GetNumValue(const char* name, void* pValue, unsigned long len)
+{
+ if (!pValue)
+ return false;
+
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+ const CNfcParam* pParam = rConfig.find(name);
+
+ if (pParam == NULL)
+ return false;
+ unsigned long v = pParam->numValue();
+ if (v == 0 && pParam->str_len() > 0 && pParam->str_len() < 4)
+ {
+ const unsigned char* p = (const unsigned char*)pParam->str_value();
+ for (size_t i = 0 ; i < pParam->str_len(); ++i)
+ {
+ v *= 256;
+ v += *p++;
+ }
+ }
+ switch (len)
+ {
+ case sizeof(unsigned long):
+ *(static_cast<unsigned long*>(pValue)) = (unsigned long)v;
+ break;
+ case sizeof(unsigned short):
+ *(static_cast<unsigned short*>(pValue)) = (unsigned short)v;
+ break;
+ case sizeof(unsigned char):
+ *(static_cast<unsigned char*> (pValue)) = (unsigned char)v;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+/*******************************************************************************
+**
+** Function: resetConfig
+**
+** Description: reset settings array
+**
+** Returns: none
+**
+*******************************************************************************/
+extern void resetConfig()
+{
+ CNfcConfig& rConfig = CNfcConfig::GetInstance();
+
+ rConfig.clean();
+}
+
+/*******************************************************************************
+**
+** Function: readOptionalConfig()
+**
+** Description: read Config settings from an optional conf file
+**
+** Returns: none
+**
+*******************************************************************************/
+void readOptionalConfig(const char* extra)
+{
+ string strPath;
+ strPath.assign(transport_config_path);
+ strPath += extra_config_base;
+ strPath += extra;
+ strPath += extra_config_ext;
+ CNfcConfig::GetInstance().readConfig(strPath.c_str(), false);
+}
+
diff --git a/halimpl/bcm2079x/adaptation/patchram.cpp b/halimpl/bcm2079x/adaptation/patchram.cpp
new file mode 100644
index 0000000..76947b9
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/patchram.cpp
@@ -0,0 +1,621 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "OverrideLog.h"
+#include "config.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+extern "C"
+{
+ #include "nfc_hal_post_reset.h"
+}
+#include <malloc.h>
+#include <string>
+#include <cutils/properties.h>
+#include "spdhelper.h"
+#include "StartupConfig.h"
+
+#define LOG_TAG "NfcNciHal"
+
+#define FW_PRE_PATCH "FW_PRE_PATCH"
+#define FW_PATCH "FW_PATCH"
+#define MAX_RF_DATA_CREDITS "MAX_RF_DATA_CREDITS"
+
+#define MAX_BUFFER (512)
+static char sPrePatchFn[MAX_BUFFER+1];
+static char sPatchFn[MAX_BUFFER+1];
+static void * sPrmBuf = NULL;
+static void * sI2cFixPrmBuf = NULL;
+
+#define CONFIG_MAX_LEN 256
+static UINT8 sConfig [CONFIG_MAX_LEN];
+static StartupConfig sStartupConfig;
+static StartupConfig sLptdConfig;
+static StartupConfig sPreDiscoveryConfig;
+static StartupConfig sXtalCustomParam;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg; //defined in the HAL
+static UINT8 nfa_dm_start_up_vsc_cfg[CONFIG_MAX_LEN];
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_lptd_cfg; //defined in the HAL
+static UINT8 sDontSendLptd[] = { 0 };
+extern UINT8 *p_nfc_hal_pre_discover_cfg; //defined in the HAL
+extern UINT8 *p_nfc_hal_dm_xtal_params_cfg; //defined in HAL
+
+extern tSNOOZE_MODE_CONFIG gSnoozeModeCfg;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+static void mayDisableSecureElement (StartupConfig& config);
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_PATCHFILE_NAME "\0"
+#endif
+
+/* Default patchfile (in NCD format) */
+#ifndef NFA_APP_DEFAULT_I2C_PATCHFILE_NAME
+#define NFA_APP_DEFAULT_I2C_PATCHFILE_NAME "\0"
+#endif
+
+tNFC_POST_RESET_CB nfc_post_reset_cb =
+{
+ /* Default Patch & Pre-Patch */
+ NFA_APP_DEFAULT_PATCHFILE_NAME,
+ NULL,
+ NFA_APP_DEFAULT_I2C_PATCHFILE_NAME,
+ NULL,
+
+ /* Default UART baud rate */
+ NFC_HAL_DEFAULT_BAUD,
+
+ /* Default tNFC_HAL_DEV_INIT_CFG (flags, num_xtal_cfg, {brcm_hw_id, xtal-freq, xtal-index} ) */
+ {
+ 2, /* number of valid entries */
+ {
+ {0x43341000, 37400, NFC_HAL_XTAL_INDEX_37400}, // All revisions of 43341 use 37,400
+ {0x20795000, 26000, NFC_HAL_XTAL_INDEX_26000},
+ {0, 0, 0},
+ {0, 0, 0},
+ {0, 0, 0},
+ }
+ },
+
+ /* Default low power mode settings */
+ NFC_HAL_LP_SNOOZE_MODE_NONE, /* Snooze Mode */
+ NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host */
+ NFC_HAL_LP_IDLE_THRESHOLD_HC, /* Idle Threshold HC */
+ NFC_HAL_LP_ACTIVE_LOW, /* NFC_WAKE Active Mode */
+ NFC_HAL_LP_ACTIVE_HIGH, /* DH_WAKE Active Mode */
+
+ NFA_APP_MAX_NUM_REINIT, /* max retry to get NVM type */
+ 0, /* current retry count */
+ TRUE, /* debug mode for downloading patchram */
+ FALSE /* skip downloading patchram after reinit because of patch download failure */
+};
+
+
+/*******************************************************************************
+**
+** Function getFileLength
+**
+** Description return the size of a file
+**
+** Returns file size in number of bytes
+**
+*******************************************************************************/
+static long getFileLength(FILE* fp)
+{
+ long sz;
+ fseek(fp, 0L, SEEK_END);
+ sz = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+
+ return (sz > 0) ? sz : 0;
+}
+
+/*******************************************************************************
+**
+** Function isFileExist
+**
+** Description Check if file name exists (android does not support fexists)
+**
+** Returns TRUE if file exists
+**
+*******************************************************************************/
+static BOOLEAN isFileExist(const char *pFilename)
+{
+ FILE *pf;
+
+ if ((pf = fopen(pFilename, "r")) != NULL)
+ {
+ fclose(pf);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function findPatchramFile
+**
+** Description Find the patchram file name specified in the .conf
+**
+** Returns pointer to the file name
+**
+*******************************************************************************/
+static const char* findPatchramFile(const char * pConfigName, char * pBuffer, int bufferLen)
+{
+ ALOGD("%s: config=%s", __FUNCTION__, pConfigName);
+
+ if (pConfigName == NULL)
+ {
+ ALOGD("%s No patchfile defined\n", __FUNCTION__);
+ return NULL;
+ }
+
+ if (GetStrValue(pConfigName, &pBuffer[0], bufferLen))
+ {
+ ALOGD("%s found patchfile %s\n", __FUNCTION__, pBuffer);
+ return (pBuffer[0] == '\0') ? NULL : pBuffer;
+ }
+
+ ALOGD("%s Cannot find patchfile '%s'\n", __FUNCTION__, pConfigName);
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function: continueAfterSetSnoozeMode
+**
+** Description: Called after Snooze Mode is enabled.
+**
+** Returns: none
+**
+*******************************************************************************/
+static void continueAfterSetSnoozeMode(tHAL_NFC_STATUS status)
+{
+ ALOGD("%s: status=%u", __FUNCTION__, status);
+ //let stack download firmware during next initialization
+ nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE;
+ if (status == NCI_STATUS_OK)
+ HAL_NfcPreInitDone (HAL_NFC_STATUS_OK);
+ else
+ HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function: postDownloadPatchram
+**
+** Description: Called after patch download
+**
+** Returns: none
+**
+*******************************************************************************/
+static void postDownloadPatchram(tHAL_NFC_STATUS status)
+{
+ ALOGD("%s: status=%i", __FUNCTION__, status);
+ GetStrValue (NAME_SNOOZE_MODE_CFG, (char*)&gSnoozeModeCfg, sizeof(gSnoozeModeCfg));
+ if (status != HAL_NFC_STATUS_OK)
+ {
+ ALOGE("%s: Patch download failed", __FUNCTION__);
+ if (status == HAL_NFC_STATUS_REFUSED)
+ {
+ SpdHelper::setPatchAsBad();
+ }
+ else
+ SpdHelper::incErrorCount();
+
+ /* If in SPD Debug mode, fail immediately and obviously */
+ if (SpdHelper::isSpdDebug())
+ HAL_NfcPreInitDone (HAL_NFC_STATUS_FAILED);
+ else
+ {
+ /* otherwise, power cycle the chip and let the stack startup normally */
+ ALOGD("%s: re-init; don't download firmware", __FUNCTION__);
+ //stop stack from downloading firmware during next initialization
+ nfc_post_reset_cb.spd_skip_on_power_cycle = TRUE;
+ USERIAL_PowerupDevice(0);
+ HAL_NfcReInit ();
+ }
+ }
+ /* Set snooze mode here */
+ else if (gSnoozeModeCfg.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+ {
+ status = HAL_NfcSetSnoozeMode(gSnoozeModeCfg.snooze_mode,
+ gSnoozeModeCfg.idle_threshold_dh,
+ gSnoozeModeCfg.idle_threshold_nfcc,
+ gSnoozeModeCfg.nfc_wake_active_mode,
+ gSnoozeModeCfg.dh_wake_active_mode,
+ continueAfterSetSnoozeMode);
+ if (status != NCI_STATUS_OK)
+ {
+ ALOGE("%s: Setting snooze mode failed, status=%i", __FUNCTION__, status);
+ HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+ }
+ }
+ else
+ {
+ ALOGD("%s: Not using Snooze Mode", __FUNCTION__);
+ HAL_NfcPreInitDone(HAL_NFC_STATUS_OK);
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: prmCallback
+**
+** Description: Patchram callback (for static patchram mode)
+**
+** Returns: none
+**
+*******************************************************************************/
+void prmCallback(UINT8 event)
+{
+ ALOGD("%s: event=0x%x", __FUNCTION__, event);
+ switch (event)
+ {
+ case NFC_HAL_PRM_CONTINUE_EVT:
+ /* This event does not occur if static patchram buf is used */
+ break;
+
+ case NFC_HAL_PRM_COMPLETE_EVT:
+ postDownloadPatchram(HAL_NFC_STATUS_OK);
+ break;
+
+ case NFC_HAL_PRM_ABORT_EVT:
+ postDownloadPatchram(HAL_NFC_STATUS_FAILED);
+ break;
+
+ case NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT:
+ ALOGD("%s: invalid patch...skipping patch download", __FUNCTION__);
+ postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+ break;
+
+ case NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT:
+ ALOGD("%s: patch authentication failed", __FUNCTION__);
+ postDownloadPatchram(HAL_NFC_STATUS_REFUSED);
+ break;
+
+ case NFC_HAL_PRM_ABORT_NO_NVM_EVT:
+ ALOGD("%s: No NVM detected", __FUNCTION__);
+ HAL_NfcPreInitDone(HAL_NFC_STATUS_FAILED);
+ break;
+
+ default:
+ ALOGD("%s: not handled event=0x%x", __FUNCTION__, event);
+ break;
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function getNfaValues
+**
+** Description Get configuration values needed by NFA layer
+**
+** Returns: None
+**
+*******************************************************************************/
+static void getNfaValues (UINT32 chipid)
+{
+ unsigned long num = 0;
+ int actualLen = 0;
+
+ sStartupConfig.initialize ();
+ sLptdConfig.initialize ();
+ sPreDiscoveryConfig.initialize();
+
+ actualLen = GetStrValue (NAME_NFA_DM_START_UP_CFG, (char*)sConfig, sizeof(sConfig));
+ if (actualLen)
+ sStartupConfig.append (sConfig, actualLen);
+
+ // Set antenna tuning configuration if configured.
+ actualLen = GetStrValue(NAME_PREINIT_DSP_CFG, (char*)sConfig, sizeof(sConfig));
+ if (actualLen)
+ sStartupConfig.append (sConfig, actualLen);
+
+ if ( GetStrValue ( NAME_NFA_DM_START_UP_VSC_CFG, (char*)nfa_dm_start_up_vsc_cfg, sizeof (nfa_dm_start_up_vsc_cfg) ) )
+ {
+ p_nfc_hal_dm_start_up_vsc_cfg = &nfa_dm_start_up_vsc_cfg[0];
+ ALOGD ( "START_UP_VSC_CFG[0] = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ nfa_dm_start_up_vsc_cfg[0],
+ nfa_dm_start_up_vsc_cfg[1],
+ nfa_dm_start_up_vsc_cfg[2],
+ nfa_dm_start_up_vsc_cfg[3],
+ nfa_dm_start_up_vsc_cfg[4],
+ nfa_dm_start_up_vsc_cfg[5],
+ nfa_dm_start_up_vsc_cfg[6],
+ nfa_dm_start_up_vsc_cfg[7] );
+ }
+
+ actualLen = GetStrValue(NAME_LPTD_CFG, (char*)sConfig, sizeof(sConfig));
+ if (actualLen)
+ {
+ sLptdConfig.append (sConfig, actualLen);
+ p_nfc_hal_dm_lptd_cfg = const_cast<UINT8*> (sLptdConfig.getInternalBuffer ());
+ }
+ else
+ {
+ // Default to not sending any LPTD setting.
+ p_nfc_hal_dm_lptd_cfg = sDontSendLptd;
+ }
+
+ mayDisableSecureElement (sStartupConfig);
+ p_nfc_hal_dm_start_up_cfg = const_cast<UINT8*> (sStartupConfig.getInternalBuffer ());
+
+ actualLen = GetStrValue(NAME_NFA_DM_PRE_DISCOVERY_CFG, (char*)sConfig, sizeof(sConfig));
+ if (actualLen)
+ {
+ sPreDiscoveryConfig.append (sConfig, actualLen);
+ mayDisableSecureElement (sPreDiscoveryConfig);
+ p_nfc_hal_pre_discover_cfg = const_cast<UINT8*> (sPreDiscoveryConfig.getInternalBuffer ());
+ }
+
+ //configure how many secure elements are available for each type of chip
+ if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support > 0)
+ {
+ if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20791_GEN)
+ {
+ nfc_hal_cb.max_ee = BRCM_NFC_20791_GEN_MAX_EE;
+ p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+ }
+ else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_43341_GEN)
+ {
+ nfc_hal_cb.max_ee = BRCM_NFC_43341_GEN_MAX_EE;
+ p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST;
+ }
+ else if ((chipid & BRCM_NFC_GEN_MASK) == BRCM_NFC_20795_GEN)
+ {
+ nfc_hal_cb.max_ee = BRCM_NFC_20795_GEN_MAX_EE;
+ p_nfc_hal_cfg->nfc_hal_hci_uicc_support = HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST;
+ }
+
+ //let .conf variable determine how many EE's to discover
+ if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)))
+ nfc_hal_cb.max_ee = num;
+ }
+}
+
+/*******************************************************************************
+**
+** Function StartPatchDownload
+**
+** Description Reads configuration settings, and begins the download
+** process if patch files are configured.
+**
+** Returns: None
+**
+*******************************************************************************/
+static void StartPatchDownload(UINT32 chipid)
+{
+ ALOGD ("%s: chipid=%lx",__FUNCTION__, chipid);
+
+ char chipID[30];
+ sprintf(chipID, "%lx", chipid);
+ ALOGD ("%s: chidId=%s", __FUNCTION__, chipID);
+
+ readOptionalConfig(chipID); // Read optional chip specific settings
+ readOptionalConfig("fime"); // Read optional FIME specific settings
+ getNfaValues(chipid); // Get NFA configuration values into variables
+
+ findPatchramFile(FW_PATCH, sPatchFn, sizeof(sPatchFn));
+ findPatchramFile(FW_PRE_PATCH, sPrePatchFn, sizeof(sPatchFn));
+
+ {
+ FILE *fd;
+ /* If an I2C fix patch file was specified, then tell the stack about it */
+ if (sPrePatchFn[0] != '\0')
+ {
+ if ((fd = fopen(sPrePatchFn, "rb")) != NULL)
+ {
+ UINT32 lenPrmBuffer = getFileLength(fd);
+
+ if ((sI2cFixPrmBuf = malloc(lenPrmBuffer)) != NULL)
+ {
+ size_t actualLen = fread(sI2cFixPrmBuf, 1, lenPrmBuffer, fd);
+ if (actualLen == lenPrmBuffer)
+ {
+ ALOGD("%s Setting I2C fix to %s (size: %lu)", __FUNCTION__, sPrePatchFn, lenPrmBuffer);
+ HAL_NfcPrmSetI2cPatch((UINT8*)sI2cFixPrmBuf, (UINT16)lenPrmBuffer, 0);
+ }
+ else
+ ALOGE("%s fail reading i2c fix; actual len=%u; expected len=%lu", __FUNCTION__, actualLen, lenPrmBuffer);
+ }
+ else
+ {
+ ALOGE("%s Unable to get buffer to i2c fix (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+ }
+
+ fclose(fd);
+ }
+ else
+ {
+ ALOGE("%s Unable to open i2c fix patchfile %s", __FUNCTION__, sPrePatchFn);
+ }
+ }
+ }
+
+ {
+ FILE *fd;
+
+ /* If a patch file was specified, then download it now */
+ if (sPatchFn[0] != '\0')
+ {
+ UINT32 bDownloadStarted = false;
+
+ /* open patchfile, read it into a buffer */
+ if ((fd = fopen(sPatchFn, "rb")) != NULL)
+ {
+ UINT32 lenPrmBuffer = getFileLength(fd);
+ ALOGD("%s Downloading patchfile %s (size: %lu) format=%u", __FUNCTION__, sPatchFn, lenPrmBuffer, NFC_HAL_PRM_FORMAT_NCD);
+ if ((sPrmBuf = malloc(lenPrmBuffer)) != NULL)
+ {
+ size_t actualLen = fread(sPrmBuf, 1, lenPrmBuffer, fd);
+ if (actualLen == lenPrmBuffer)
+ {
+ if (!SpdHelper::isPatchBad((UINT8*)sPrmBuf, lenPrmBuffer))
+ {
+ /* Download patch using static memeory mode */
+ HAL_NfcPrmDownloadStart(NFC_HAL_PRM_FORMAT_NCD, 0, (UINT8*)sPrmBuf, lenPrmBuffer, 0, prmCallback);
+ bDownloadStarted = true;
+ }
+ }
+ else
+ ALOGE("%s fail reading patchram", __FUNCTION__);
+ }
+ else
+ ALOGE("%s Unable to buffer to hold patchram (%lu bytes)", __FUNCTION__, lenPrmBuffer);
+
+ fclose(fd);
+ }
+ else
+ ALOGE("%s Unable to open patchfile %s", __FUNCTION__, sPatchFn);
+
+ /* If the download never got started */
+ if (!bDownloadStarted)
+ {
+ /* If debug mode, fail in an obvious way, otherwise try to start stack */
+ postDownloadPatchram(SpdHelper::isSpdDebug() ? HAL_NFC_STATUS_FAILED :
+ HAL_NFC_STATUS_OK);
+ }
+ }
+ else
+ {
+ ALOGE("%s: No patchfile specified or disabled. Proceeding to post-download procedure...", __FUNCTION__);
+ postDownloadPatchram(HAL_NFC_STATUS_OK);
+ }
+ }
+
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function: nfc_hal_post_reset_init
+**
+** Description: Called by the NFC HAL after controller has been reset.
+** Begin to download firmware patch files.
+**
+** Returns: none
+**
+*******************************************************************************/
+void nfc_hal_post_reset_init (UINT32 brcm_hw_id, UINT8 nvm_type)
+{
+ ALOGD("%s: brcm_hw_id=0x%lx, nvm_type=%d", __FUNCTION__, brcm_hw_id, nvm_type);
+ tHAL_NFC_STATUS stat = HAL_NFC_STATUS_FAILED;
+ UINT8 max_credits = 1, allow_no_nvm=0;
+
+ p_nfc_hal_cfg->nfc_hal_prm_nvm_required = TRUE; //don't download firmware if controller cannot detect EERPOM
+
+ if (nvm_type == NCI_SPD_NVM_TYPE_NONE)
+ {
+ GetNumValue(NAME_ALLOW_NO_NVM, &allow_no_nvm, sizeof(allow_no_nvm));
+ if (allow_no_nvm == 0)
+ {
+ ALOGD("%s: No NVM detected, FAIL the init stage to force a retry", __FUNCTION__);
+ USERIAL_PowerupDevice (0);
+ stat = HAL_NfcReInit ();
+ return;
+ }
+
+ p_nfc_hal_cfg->nfc_hal_prm_nvm_required = FALSE; //allow download firmware if controller cannot detect EERPOM
+ }
+
+ /* Start downloading the patch files */
+ StartPatchDownload(brcm_hw_id);
+
+ if (GetNumValue(MAX_RF_DATA_CREDITS, &max_credits, sizeof(max_credits)) && (max_credits > 0))
+ {
+ ALOGD("%s : max_credits=%d", __FUNCTION__, max_credits);
+ HAL_NfcSetMaxRfDataCredits(max_credits);
+ }
+ }
+
+
+/*******************************************************************************
+**
+** Function: mayDisableSecureElement
+**
+** Description: Optionally adjust a TLV to disable secure element. This feature
+** is enabled by setting the system property
+** nfc.disable_secure_element to a bit mask represented by a hex
+** octet: C0 = do not detect any secure element.
+** 40 = do not detect secure element in slot 0.
+** 80 = do not detect secure element in slot 1.
+**
+** config: a sequence of TLV's.
+**
+*******************************************************************************/
+void mayDisableSecureElement (StartupConfig& config)
+{
+ unsigned int bitmask = 0;
+ char valueStr [PROPERTY_VALUE_MAX] = {0};
+ int len = property_get ("nfc.disable_secure_element", valueStr, "");
+ if (len > 0)
+ {
+ sscanf (valueStr, "%x", &bitmask); //read system property as a hex octet
+ ALOGD ("%s: disable 0x%02X", __FUNCTION__, (UINT8) bitmask);
+ config.disableSecureElement ((UINT8) (bitmask & 0xC0));
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function: configureCrystalFrequency
+**
+** Description: Configure controller's crystal frequency by reading values from
+** .conf file. If .conf file does not define any value, then use
+** default values defined in struct nfc_post_reset_cb.
+**
+** Returns: none
+**
+*******************************************************************************/
+void configureCrystalFrequency ()
+{
+ unsigned long num = 0;
+ UINT32 hwId = 0;
+ UINT16 xtalFreq = 0;
+ UINT8 xtalIndex = 0;
+ int actualLen = 0;
+
+ if (GetNumValue (NAME_XTAL_HARDWARE_ID, &num, sizeof(num)))
+ hwId = num;
+
+ if (GetNumValue (NAME_XTAL_FREQUENCY, &num, sizeof(num)))
+ xtalFreq = (UINT16) num;
+
+ if (GetNumValue (NAME_XTAL_FREQ_INDEX, &num, sizeof(num)))
+ xtalIndex = (UINT8) num;
+
+ actualLen = GetStrValue (NAME_XTAL_PARAMS_CFG, (char*)sConfig, sizeof(sConfig));
+ if (actualLen && (xtalIndex == NFC_HAL_XTAL_INDEX_SPECIAL)) //whether to use custom crystal frequency
+ {
+ sXtalCustomParam.append (sConfig, actualLen);
+ p_nfc_hal_dm_xtal_params_cfg = const_cast<UINT8*> (sXtalCustomParam.getInternalBuffer ());
+ }
+
+ if ((hwId == 0) && (xtalFreq == 0) && (xtalIndex == 0))
+ return;
+
+ ALOGD ("%s: hwId=0x%lX; freq=%u; index=%u", __FUNCTION__, hwId, xtalFreq, xtalIndex);
+ nfc_post_reset_cb.dev_init_config.xtal_cfg[0].brcm_hw_id = (hwId & BRCM_NFC_GEN_MASK);
+ nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_freq = xtalFreq;
+ nfc_post_reset_cb.dev_init_config.xtal_cfg[0].xtal_index = xtalIndex;
+ nfc_post_reset_cb.dev_init_config.num_xtal_cfg = 1;
+}
diff --git a/halimpl/bcm2079x/adaptation/spdhelper.cpp b/halimpl/bcm2079x/adaptation/spdhelper.cpp
new file mode 100644
index 0000000..3d87e0e
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/spdhelper.cpp
@@ -0,0 +1,108 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include "spdhelper.h"
+#include "config.h"
+
+void SpdHelper::setPatchAsBad()
+{
+ getInstance().setPatchAsBadImpl();
+}
+
+void SpdHelper::incErrorCount()
+{
+ getInstance().incErrorCountImpl();
+}
+
+bool SpdHelper::isPatchBad(UINT8* prm, UINT32 len)
+{
+ return getInstance().isPatchBadImpl(prm, len);
+}
+
+bool SpdHelper::isSpdDebug()
+{
+ bool b = getInstance().isSpdDebugImpl();
+ ALOGD("%s SpdDebug is %s", __func__, (b ? "TRUE" : "FALSE"));
+ return b;
+}
+
+void SpdHelper::incErrorCountImpl()
+{
+ if (++mErrorCount >= mMaxErrorCount)
+ {
+ setPatchAsBadImpl();
+ }
+}
+
+void SpdHelper::setPatchAsBadImpl()
+{
+ mIsPatchBad = true;
+}
+
+inline const char * toHex(UINT8 b)
+{
+ static char hex[] = "0123456789ABCDEF";
+ static char c[3];
+ c[0] = hex[((b >> 4) & 0x0F)];
+ c[1] = hex[((b >> 0) & 0x0F)];
+ c[2] = '\0';
+ return &c[0];
+}
+
+bool SpdHelper::isPatchBadImpl(UINT8* prm, UINT32 len)
+{
+ string strNew;
+
+ // Get the patch ID from the prm data.
+ for (int i = 0; i < 8 && i < len; ++i)
+ strNew.append(toHex(*prm++));
+
+ // If it is not the same patch as before, then reset things.
+ if ( strNew != mPatchId )
+ {
+ mPatchId = strNew;
+ mErrorCount = 0;
+ mIsPatchBad = false;
+ }
+
+ // Otherwise the 'mIsPatchBad' will tell if its bad or not.
+ ALOGD("%s '%s' (%d) is %sa known bad patch file", __func__, mPatchId.c_str(), mErrorCount, (mIsPatchBad ? "" : "not "));
+
+ return mIsPatchBad;
+}
+
+SpdHelper& SpdHelper::getInstance()
+{
+ static SpdHelper* theInstance = NULL;
+ if (theInstance == NULL)
+ theInstance= new SpdHelper;
+ return *theInstance;
+}
+
+SpdHelper::SpdHelper()
+{
+ mErrorCount = 0;
+ mPatchId.erase();
+ if(!GetNumValue((char*)NAME_SPD_MAXRETRYCOUNT, &mMaxErrorCount, sizeof(mMaxErrorCount)))
+ mMaxErrorCount = DEFAULT_SPD_MAXRETRYCOUNT;
+ mIsPatchBad = false;
+ if (!GetNumValue((char*)NAME_SPD_DEBUG, &mSpdDebug, sizeof(mSpdDebug)))
+ mSpdDebug = false;
+}
diff --git a/halimpl/bcm2079x/adaptation/userial_linux.c b/halimpl/bcm2079x/adaptation/userial_linux.c
new file mode 100644
index 0000000..f41f296
--- /dev/null
+++ b/halimpl/bcm2079x/adaptation/userial_linux.c
@@ -0,0 +1,1795 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#include "OverrideLog.h"
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+#include "nfc_target.h"
+
+#include <pthread.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <gki_int.h>
+#include "hcidefs.h"
+#include <poll.h>
+#include "upio.h"
+#include "bcm2079x.h"
+#include "config.h"
+
+#define HCISU_EVT EVENT_MASK(APPL_EVT_0)
+#define MAX_ERROR 10
+#define default_transport "/dev/bcm2079x"
+
+#define NUM_RESET_ATTEMPTS 5
+#define NFC_WAKE_ASSERTED_ON_POR UPIO_OFF
+
+#ifndef BTE_APPL_MAX_USERIAL_DEV_NAME
+#define BTE_APPL_MAX_USERIAL_DEV_NAME (256)
+#endif
+extern UINT8 appl_trace_level;
+
+
+/* Mapping of USERIAL_PORT_x to linux */
+extern UINT32 ScrProtocolTraceFlag;
+static tUPIO_STATE current_nfc_wake_state = UPIO_OFF;
+int uart_port = 0;
+int isLowSpeedTransport = 0;
+int nfc_wake_delay = 0;
+int nfc_write_delay = 0;
+int gPowerOnDelay = 300;
+static int gPrePowerOffDelay = 0; // default value
+static int gPostPowerOffDelay = 0; // default value
+static pthread_mutex_t close_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+char userial_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+char power_control_dev[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+tSNOOZE_MODE_CONFIG gSnoozeModeCfg = {
+ NFC_HAL_LP_SNOOZE_MODE_SPI_I2C, /* Sleep Mode (0=Disabled 1=UART 8=SPI/I2C) */
+ NFC_HAL_LP_IDLE_THRESHOLD_HOST, /* Idle Threshold Host */
+ NFC_HAL_LP_IDLE_THRESHOLD_HC, /* Idle Threshold HC */
+ NFC_HAL_LP_ACTIVE_LOW, /* NFC Wake active mode (0=ActiveLow 1=ActiveHigh) */
+ NFC_HAL_LP_ACTIVE_HIGH /* Host Wake active mode (0=ActiveLow 1=ActiveHigh) */
+};
+
+UINT8 bcmi2cnfc_client_addr = 0;
+UINT8 bcmi2cnfc_read_multi_packets = 0;
+
+#define USERIAL_Debug_verbose ((ScrProtocolTraceFlag & 0x80000000) == 0x80000000)
+
+#include <sys/socket.h>
+
+#define LOG_TAG "USERIAL_LINUX"
+
+static UINT8 spi_negotiation[10] = { 0xF0, /* CMD */
+ 0x00, /* SPI PARM Negotiation */
+ 0x01, /* SPI Version */
+ 0x00, /* SPI Mode:0, SPI_INT active low */
+ 0x00, /* 8Bit, MSB first, Little Endian byte order */
+ 0x00, /* Reserved */
+ 0xFF, /* Sleep timeout Lower Byte */
+ 0xFF, /* Sleep timeout Upper Byte */
+ 0x00, /* Reserved */
+ 0x00 /* Reserved */
+};
+static UINT8 spi_nego_res[20];
+
+/* Modes used when powering off (independent
+ of what the stack/jni has configured */
+#define POM_NORMAL (0) /* Normal */
+#define POM_CE3SO (1) /* Go to CE3-SO */
+#define POM_NFC_OFF (2) /* Set NFC Off bit */
+
+static int gPowerOffMode = POM_NORMAL;
+
+static UINT8 ce3_so_cmd[10] = { 0x10,
+ 0x2F, /* CMD */
+ 0x08,
+ 0x06, /* size of cmd */
+ 0x02, /* CE3 power-level */
+ 0xF3, /* LpmUicc */
+ 0x01, /* LpmListenTech */
+ 0x01, /* Param */
+ 0x00, /* Forced */
+ 0x00 /* Debug */
+};
+
+static UINT8 set_nfc_off_cmd[5] = {
+ 0x10,
+ 0x2F, /* CMD */
+ 0x38,
+ 0x01, /* size of cmd */
+ 0x01 /* setNfcOff */
+};
+
+#include <ctype.h>
+
+#define USING_BRCM_USB TRUE
+
+/* use tc interface to change baudrate instead of close/open sequence which can fail on some platforms
+ * due to tx line movement when opeing/closing the UART. the 43xx do not like this. */
+#ifndef USERIAL_USE_TCIO_BAUD_CHANGE
+#define USERIAL_USE_TCIO_BAUD_CHANGE FALSE
+#endif
+
+#ifndef USERIAL_USE_IO_BT_WAKE
+#define USERIAL_USE_IO_BT_WAKE FALSE
+#endif
+
+/* this are the ioctl values used for bt_wake ioctl via UART driver. you may need to redefine at for
+ * you platform! Logically they need to be unique and not colide with existing uart ioctl's.
+ */
+#ifndef USERIAL_IO_BT_WAKE_ASSERT
+#define USERIAL_IO_BT_WAKE_ASSERT 0x8003
+#endif
+#ifndef USERIAL_IO_BT_WAKE_DEASSERT
+#define USERIAL_IO_BT_WAKE_DEASSERT 0x8004
+#endif
+#ifndef USERIAL_IO_BT_WAKE_GET_ST
+#define USERIAL_IO_BT_WAKE_GET_ST 0x8005
+#endif
+
+/* the read limit in this current implementation depends on the GKI_BUF3_SIZE
+ * It would be better to use some ring buffer from the USERIAL_Read() is reading
+ * instead of putting it into GKI buffers.
+ */
+#define READ_LIMIT (USERIAL_POOL_BUF_SIZE-BT_HDR_SIZE)
+/*
+ * minimum buffer size requirement to read a full sized packet from NFCC = 255 + 4 byte header
+ */
+#define MIN_BUFSIZE 259
+#define POLL_TIMEOUT 1000
+/* priority of the reader thread */
+#define USERIAL_READ_TRHEAD_PRIO 90
+/* time (ms) to wait before trying to allocate again a GKI buffer */
+#define NO_GKI_BUFFER_RECOVER_TIME 100
+#define MAX_SERIAL_PORT (USERIAL_PORT_15 + 1)
+
+extern void dumpbin(const char* data, int size);
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+
+static pthread_t worker_thread1 = 0;
+
+typedef struct {
+ volatile unsigned long bt_wake_state;
+ int sock;
+ tUSERIAL_CBACK *ser_cb;
+ UINT16 baud;
+ UINT8 data_bits;
+ UINT16 parity;
+ UINT8 stop_bits;
+ UINT8 port;
+ tUSERIAL_OPEN_CFG open_cfg;
+ int sock_power_control;
+ int client_device_address;
+ struct timespec write_time;
+} tLINUX_CB;
+
+static tLINUX_CB linux_cb; /* case of multipel port support use array : [MAX_SERIAL_PORT] */
+
+void userial_close_thread(UINT32 params);
+
+static UINT8 device_name[BTE_APPL_MAX_USERIAL_DEV_NAME+1];
+static int bSerialPortDevice = FALSE;
+static int _timeout = POLL_TIMEOUT;
+static BOOLEAN is_close_thread_is_waiting = FALSE;
+
+static int change_client_addr(int addr);
+
+int perf_log_every_count = 0;
+typedef struct {
+ const char* label;
+ long lapse;
+ long bytes;
+ long count;
+ long overhead;
+} tPERF_DATA;
+
+/*******************************************************************************
+**
+** Function perf_reset
+**
+** Description reset performance measurement data
+**
+** Returns none
+**
+*******************************************************************************/
+void perf_reset(tPERF_DATA* t)
+{
+ t->count =
+ t->bytes =
+ t->lapse = 0;
+}
+
+/*******************************************************************************
+**
+** Function perf_log
+**
+** Description produce a log entry of cvurrent performance data
+**
+** Returns none
+**
+*******************************************************************************/
+void perf_log(tPERF_DATA* t)
+{
+ // round to nearest ms
+ // t->lapse += 500;
+ // t->lapse /= 1000;
+ if (t->lapse)
+ {
+ if (t->bytes)
+ ALOGD( "%s:%s, bytes=%ld, lapse=%ld (%d.%02d kbps) (bus data rate %d.%02d kbps) overhead %d(%d percent)\n",
+ __func__,
+ t->label, t->bytes, t->lapse,
+ (int)(8 * t->bytes / t->lapse), (int)(800 * t->bytes / (t->lapse)) % 100,
+ (int)(9 * (t->bytes + t->count * t->overhead) / t->lapse), (int)(900 * (t->bytes + t->count * t->overhead) / (t->lapse)) % 100,
+ (int)(t->count * t->overhead), (int)(t->count * t->overhead * 100 / t->bytes)
+ );
+ else
+ ALOGD( "%s:%s, lapse=%ld (average %ld)\n", __func__,
+ t->label, t->lapse, (int)t->lapse / t->count
+ );
+ }
+ perf_reset(t);
+}
+
+/*******************************************************************************
+**
+** Function perf_update
+**
+** Description update perforamnce measurement data
+**
+** Returns none
+**
+*******************************************************************************/
+void perf_update(tPERF_DATA* t, long lapse, long bytes)
+{
+ if (!perf_log_every_count)
+ return;
+ // round to nearest ms
+ lapse += 500;
+ lapse /= 1000;
+ t->count++;
+ t->bytes += bytes;
+ t->lapse += lapse;
+ if (t->count == perf_log_every_count)
+ perf_log(t);
+}
+
+static tPERF_DATA perf_poll = {"USERIAL_Poll", 0, 0, 0, 0};
+static tPERF_DATA perf_read = {"USERIAL_Read", 0, 0, 0, 9};
+static tPERF_DATA perf_write = {"USERIAL_Write", 0, 0, 0, 3};
+static tPERF_DATA perf_poll_2_poll = {"USERIAL_Poll_to_Poll", 0, 0, 0, 0};
+static clock_t _poll_t0 = 0;
+
+static UINT32 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 */
+};
+
+/*******************************************************************************
+**
+** Function wake_state
+**
+** Description return current state of NFC_WAKE gpio
+**
+** Returns GPIO value to wake NFCC
+**
+*******************************************************************************/
+static inline int wake_state()
+{
+ return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+}
+
+/*******************************************************************************
+**
+** Function sleep_state
+**
+** Description return current state of NFC_WAKE gpio
+**
+** Returns GPIO value to allow NFCC to goto sleep
+**
+*******************************************************************************/
+static inline int sleep_state()
+{
+ return ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_OFF : UPIO_ON);
+}
+
+/*******************************************************************************
+**
+** Function isWake
+**
+** Description return current state of NFC_WAKE gpio based on the active mode setting
+**
+** Returns asserted_state if it's awake, deasserted_state if it's allowed to sleep
+**
+*******************************************************************************/
+static inline int isWake(int state)
+{
+ int asserted_state = ((gSnoozeModeCfg.nfc_wake_active_mode == NFC_HAL_LP_ACTIVE_HIGH) ? UPIO_ON : UPIO_OFF);
+ return (state != -1) ?
+ state == asserted_state :
+ current_nfc_wake_state == asserted_state;
+}
+
+/*******************************************************************************
+**
+** Function setWriteDelay
+**
+** Description Record a delay for the next write operation
+**
+** Input Parameter delay in milliseconds
+**
+** Comments use this function to register a delay before next write,
+** This is used in three instances: power up delay, wake delay
+** and write delay
+**
+*******************************************************************************/
+static void setWriteDelay(int delay)
+{
+ if (delay <= 0) {
+ // Set a minimum delay of 5ms between back-to-back writes
+ delay = 5;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &linux_cb.write_time);
+ if (delay > 1000)
+ {
+ linux_cb.write_time.tv_sec += delay / 1000;
+ delay %= 1000;
+ }
+ unsigned long write_delay = delay * 1000 * 1000;
+ linux_cb.write_time.tv_nsec += write_delay;
+ if (linux_cb.write_time.tv_nsec > 1000*1000*1000)
+ {
+ linux_cb.write_time.tv_nsec -= 1000*1000*1000;
+ linux_cb.write_time.tv_sec++;
+ }
+}
+
+/*******************************************************************************
+**
+** Function doWriteDelay
+**
+** Description Execute a delay as registered in setWriteDelay()
+**
+** Output Parameter none
+**
+** Returns none
+**
+** Comments This function calls GKI_Delay to execute a delay to fulfill
+** the delay registered earlier.
+**
+*******************************************************************************/
+static void doWriteDelay()
+{
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ long delay = 0;
+
+ if (now.tv_sec > linux_cb.write_time.tv_sec)
+ return;
+ else if (now.tv_sec == linux_cb.write_time.tv_sec)
+ {
+ if (now.tv_nsec > linux_cb.write_time.tv_nsec)
+ return;
+ delay = (linux_cb.write_time.tv_nsec - now.tv_nsec) / 1000000;
+ }
+ else
+ delay = (linux_cb.write_time.tv_sec - now.tv_sec) * 1000 + linux_cb.write_time.tv_nsec / 1000000 - now.tv_nsec / 1000000;
+
+ if (delay > 0 && delay < 1000)
+ {
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "doWriteDelay() delay %ld ms", delay);
+ GKI_delay(delay);
+ }
+}
+
+/*******************************************************************************
+**
+** Function create_signal_fds
+**
+** Description create a socketpair for read thread to use
+**
+** Returns file descriptor
+**
+*******************************************************************************/
+
+static int signal_fds[2];
+static inline int create_signal_fds(struct pollfd* set)
+{
+ if (signal_fds[0] == 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0)
+ {
+ ALOGE("%s create_signal_sockets:socketpair failed, errno: %d", __func__, errno);
+ return -1;
+ }
+ set->fd = signal_fds[0];
+ return signal_fds[0];
+}
+
+/*******************************************************************************
+**
+** Function close_signal_fds
+**
+** Description close the socketpair
+**
+** Returns none
+**
+*******************************************************************************/
+static inline void close_signal_fds()
+{
+ int stat = 0;
+
+ stat = close(signal_fds[0]);
+ if (stat == -1)
+ ALOGE ("%s, fail close index 0; errno=%d", __FUNCTION__, errno);
+ signal_fds[0] = 0;
+
+ stat = close(signal_fds[1]);
+ if (stat == -1)
+ ALOGE ("%s, fail close index 1; errno=%d", __FUNCTION__, errno);
+ signal_fds[1] = 0;
+}
+
+/*******************************************************************************
+**
+** Function send_wakeup_signal
+**
+** Description send a one byte data to the socket as signal to the read thread
+** for it to stop
+**
+** Returns number of bytes sent, or error no
+**
+*******************************************************************************/
+static inline int send_wakeup_signal()
+{
+ char sig_on = 1;
+ ALOGD("%s: Sending signal to %d", __func__, signal_fds[1]);
+ return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+}
+
+/*******************************************************************************
+**
+** Function reset_signal
+**
+** Description read the one byte data from the socket
+**
+** Returns received data
+**
+*******************************************************************************/
+static inline int reset_signal()
+{
+ char sig_recv = 0;
+ ALOGD("%s: Receiving signal from %d", __func__, signal_fds[0]);
+ recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ return (int)sig_recv;
+}
+
+/*******************************************************************************
+**
+** Function is_signaled
+**
+** Description test if there's data waiting on the socket
+**
+** Returns TRUE is data is available
+**
+*******************************************************************************/
+static inline int is_signaled(struct pollfd* set)
+{
+ return ((set->revents & POLLIN) == POLLIN) || ((set->revents & POLLRDNORM) == POLLRDNORM) ;
+}
+
+/******************************************************************************/
+
+typedef unsigned char uchar;
+
+BUFFER_Q Userial_in_q;
+
+/*******************************************************************************
+ **
+ ** Function USERIAL_GetLineSpeed
+ **
+ ** Description This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter None
+ **
+ ** Returns line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud)
+{
+ return (baud <= USERIAL_BAUD_4M) ?
+ userial_baud_tbl[baud-USERIAL_BAUD_300] : 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function USERIAL_GetBaud
+ **
+ ** Description This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter None
+ **
+ ** Returns line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed)
+{
+ UINT8 i;
+ for (i = USERIAL_BAUD_300; i <= USERIAL_BAUD_921600; i++)
+ {
+ if (userial_baud_tbl[i-USERIAL_BAUD_300] == line_speed)
+ return i;
+ }
+
+ return USERIAL_BAUD_AUTO;
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Init
+**
+** Description This function initializes the serial driver.
+**
+** Output Parameter None
+**
+** Returns Nothing
+**
+*******************************************************************************/
+
+UDRV_API void USERIAL_Init(void * p_cfg)
+{
+ ALOGI(__FUNCTION__);
+
+ //if userial_close_thread() is waiting to run; let it go first;
+ //let it finish; then continue this function
+ while (TRUE)
+ {
+ pthread_mutex_lock(&close_thread_mutex);
+ if (is_close_thread_is_waiting)
+ {
+ pthread_mutex_unlock(&close_thread_mutex);
+ ALOGI("USERIAL_Init(): wait for close-thread");
+ sleep (1);
+ }
+ else
+ break;
+ }
+
+ memset(&linux_cb, 0, sizeof(linux_cb));
+ linux_cb.sock = -1;
+ linux_cb.ser_cb = NULL;
+ linux_cb.sock_power_control = -1;
+ linux_cb.client_device_address = 0;
+ GKI_init_q(&Userial_in_q);
+ pthread_mutex_unlock(&close_thread_mutex);
+}
+
+/*******************************************************************************
+ **
+ ** Function my_read
+ **
+ ** Description This function read a packet from driver.
+ **
+ ** Output Parameter None
+ **
+ ** Returns number of bytes in the packet or error code
+ **
+ *******************************************************************************/
+int my_read(int fd, uchar *pbuf, int len)
+{
+ struct pollfd fds[2];
+
+ int n = 0;
+ int ret = 0;
+ int count = 0;
+ int offset = 0;
+ clock_t t1, t2;
+
+ if (!isLowSpeedTransport && _timeout != POLL_TIMEOUT)
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter, pbuf=%lx, len = %d\n", __func__, (unsigned long)pbuf, len);
+ memset(pbuf, 0, len);
+ /* need to use select in order to avoid collistion between read and close on same fd */
+ /* Initialize the input set */
+ fds[0].fd = fd;
+ fds[0].events = POLLIN | POLLERR | POLLRDNORM;
+ fds[0].revents = 0;
+
+ create_signal_fds(&fds[1]);
+ fds[1].events = POLLIN | POLLERR | POLLRDNORM;
+ fds[1].revents = 0;
+ t1 = clock();
+ n = poll(fds, 2, _timeout);
+ t2 = clock();
+ perf_update(&perf_poll, t2 - t1, 0);
+ if (_poll_t0)
+ perf_update(&perf_poll_2_poll, t2 - _poll_t0, 0);
+
+ _poll_t0 = t2;
+ /* See if there was an error */
+ if (n < 0)
+ {
+ ALOGD( "select failed; errno = %d\n", errno);
+ return -errno;
+ }
+ else if (n == 0)
+ return -EAGAIN;
+
+ if (is_signaled(&fds[1]))
+ {
+ ALOGD( "%s: exit signal received\n", __func__);
+ reset_signal();
+ return -1;
+ }
+ if (!bSerialPortDevice || len < MIN_BUFSIZE)
+ count = len;
+ else
+ count = 1;
+ do {
+ t2 = clock();
+ ret = read(fd, pbuf+offset, (size_t)count);
+ if (ret > 0)
+ perf_update(&perf_read, clock()-t2, ret);
+
+ if (ret <= 0 || !bSerialPortDevice || len < MIN_BUFSIZE)
+ break;
+
+ if (isLowSpeedTransport)
+ goto done;
+
+ if (offset == 0)
+ {
+ if (pbuf[offset] == HCIT_TYPE_NFC)
+ count = 3;
+ else if (pbuf[offset] == HCIT_TYPE_EVENT)
+ count = 2;
+ else
+ {
+ ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x\n", __func__, offset, pbuf[offset]);
+ break;
+ }
+ offset = 1;
+ }
+ else if (offset == 1)
+ {
+ offset += count;
+ count = pbuf[offset-1];
+ if (count > (len - offset)) //if (count > (remaining buffer size))
+ count = len - offset; //only read what the remaining buffer size can hold
+ }
+ else
+ {
+ offset += ret;
+ count -= ret;
+ }
+ if (count == 0)
+ {
+ ret = offset;
+ break;
+ }
+ } while (count > 0);
+
+
+ #if VALIDATE_PACKET
+/*
+ * vallidate the packet structure
+ */
+ if (ret > 0 && len >= MIN_BUFSIZE)
+ {
+ count = 0;
+ while (count < ret)
+ {
+ if (pbuf[count] == HCIT_TYPE_NFC)
+ {
+ if (USERIAL_Debug_verbose)
+ scru_dump_hex(pbuf+count, NULL, pbuf[count+3]+4, 0, 0);
+ count += pbuf[count+3]+4;
+ }
+ else if (pbuf[count] == HCIT_TYPE_EVENT)
+ {
+ if (USERIAL_Debug_verbose)
+ scru_dump_hex(pbuf+count, NULL, pbuf[count+2]+3, 0, 0);
+ count += pbuf[count+2]+3;
+ }
+ else
+ {
+ ALOGD( "%s: unknown HCIT type header pbuf[%d] = %x, remain %d bytes\n", __func__, count, pbuf[count], ret-count);
+ scru_dump_hex(pbuf+count, NULL, ret - count, 0, 0);
+ break;
+ }
+ } /* while*/
+ }
+#endif
+done:
+ if (!isLowSpeedTransport)
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: return %d(0x%x) bytes, errno=%d count=%d, n=%d, timeout=%d\n", __func__,
+ ret, ret, errno, count, n, _timeout);
+ if (_timeout == POLL_TIMEOUT)
+ _timeout = -1;
+ return ret;
+}
+extern BOOLEAN gki_chk_buf_damage(void *p_buf);
+static int sRxLength = 0;
+
+/*******************************************************************************
+ **
+ ** Function userial_read_thread
+ **
+ ** Description entry point of read thread.
+ **
+ ** Output Parameter None
+ **
+ ** Returns 0
+ **
+ *******************************************************************************/
+UINT32 userial_read_thread(UINT32 arg)
+{
+ int rx_length;
+ int error_count = 0;
+ int bErrorReported = 0;
+ int iMaxError = MAX_ERROR;
+ BT_HDR *p_buf = NULL;
+
+ worker_thread1 = pthread_self();
+
+ ALOGD( "start userial_read_thread, id=%lx", worker_thread1);
+ _timeout = POLL_TIMEOUT;
+
+ for (;linux_cb.sock > 0;)
+ {
+ BT_HDR *p_buf;
+ UINT8 *current_packet;
+
+ if ((p_buf = (BT_HDR *) GKI_getpoolbuf( USERIAL_POOL_ID ) )!= NULL)
+ {
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+
+ current_packet = (UINT8 *) (p_buf + 1);
+ rx_length = my_read(linux_cb.sock, current_packet, READ_LIMIT);
+
+ }
+ else
+ {
+ ALOGE( "userial_read_thread(): unable to get buffer from GKI p_buf = %p poolid = %d\n", p_buf, USERIAL_POOL_ID);
+ rx_length = 0; /* paranoia setting */
+ GKI_delay( NO_GKI_BUFFER_RECOVER_TIME );
+ continue;
+ }
+ if (rx_length > 0)
+ {
+ bErrorReported = 0;
+ error_count = 0;
+ iMaxError = 3;
+ if (rx_length > sRxLength)
+ sRxLength = rx_length;
+ p_buf->len = (UINT16)rx_length;
+ GKI_enqueue(&Userial_in_q, p_buf);
+ if (!isLowSpeedTransport)
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "userial_read_thread(): enqueued p_buf=%p, count=%d, length=%d\n",
+ p_buf, Userial_in_q.count, rx_length);
+
+ if (linux_cb.ser_cb != NULL)
+ (*linux_cb.ser_cb)(linux_cb.port, USERIAL_RX_READY_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+ GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+ }
+ else
+ {
+ GKI_freebuf( p_buf );
+ if (rx_length == -EAGAIN)
+ continue;
+ else if (rx_length == -1)
+ {
+ ALOGD( "userial_read_thread(): exiting\n");
+ break;
+ }
+ else if (rx_length == 0 && !isWake(-1))
+ continue;
+ ++error_count;
+ if (rx_length <= 0 && ((error_count > 0) && ((error_count % iMaxError) == 0)))
+ {
+ if (bErrorReported == 0)
+ {
+ ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d return USERIAL_ERR_EVT\n",
+ rx_length, error_count, errno);
+ if (linux_cb.ser_cb != NULL)
+ (*linux_cb.ser_cb)(linux_cb.port, USERIAL_ERR_EVT, (tUSERIAL_EVT_DATA *)p_buf);
+
+ GKI_send_event(USERIAL_HAL_TASK, HCISU_EVT);
+ ++bErrorReported;
+ }
+ if (sRxLength == 0)
+ {
+ ALOGE( "userial_read_thread(): my_read returned (%d) error count = %d, errno=%d exit read thread\n",
+ rx_length, error_count, errno);
+ break;
+ }
+ }
+ }
+ } /* for */
+
+ ALOGD( "userial_read_thread(): freeing GKI_buffers\n");
+ while ((p_buf = (BT_HDR *) GKI_dequeue (&Userial_in_q)) != NULL)
+ {
+ GKI_freebuf(p_buf);
+ ALOGD("userial_read_thread: dequeued buffer from Userial_in_q\n");
+ }
+
+ GKI_exit_task (GKI_get_taskid ());
+ ALOGD( "USERIAL READ: EXITING TASK\n");
+
+ return 0;
+}
+
+/*******************************************************************************
+ **
+ ** Function userial_to_tcio_baud
+ **
+ ** Description helper function converts USERIAL baud rates into TCIO conforming baud rates
+ **
+ ** Output Parameter None
+ **
+ ** Returns TRUE - success
+ ** FALSE - unsupported baud rate, default of 115200 is used
+ **
+ *******************************************************************************/
+BOOLEAN userial_to_tcio_baud(UINT8 cfg_baud, UINT32 * 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 | CBAUDEX;
+ 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
+ {
+ ALOGE( "userial_to_tcio_baud: unsupported baud idx %i", cfg_baud );
+ *baud = B115200;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+/*******************************************************************************
+ **
+ ** Function userial_io_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_io_init_bt_wake( int fd, unsigned long * p_wake_state )
+{
+ /* assert BT_WAKE for ioctl. should NOT hurt on rfkill version */
+ ioctl( fd, USERIAL_IO_BT_WAKE_ASSERT, NULL);
+ ioctl( fd, USERIAL_IO_BT_WAKE_GET_ST, p_wake_state );
+ if ( *p_wake_state == 0)
+ ALOGI("\n***userial_io_init_bt_wake(): Ooops, asserted BT_WAKE signal, but still got BT_WAKE state == to %d\n",
+ *p_wake_state );
+
+ *p_wake_state = 1;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function USERIAL_Open
+**
+** Description Open the indicated serial port with the given configuration
+**
+** Output Parameter None
+**
+** Returns Nothing
+**
+*******************************************************************************/
+UDRV_API void USERIAL_Open(tUSERIAL_PORT port, tUSERIAL_OPEN_CFG *p_cfg, tUSERIAL_CBACK *p_cback)
+{
+ UINT32 baud = 0;
+ UINT8 data_bits = 0;
+ UINT16 parity = 0;
+ UINT8 stop_bits = 0;
+ struct termios termios;
+ const char ttyusb[] = "/dev/ttyUSB";
+ const char devtty[] = "/dev/tty";
+ unsigned long num = 0;
+ int ret = 0;
+
+ ALOGI("USERIAL_Open(): enter");
+
+ //if userial_close_thread() is waiting to run; let it go first;
+ //let it finish; then continue this function
+ while (TRUE)
+ {
+ pthread_mutex_lock(&close_thread_mutex);
+ if (is_close_thread_is_waiting)
+ {
+ pthread_mutex_unlock(&close_thread_mutex);
+ ALOGI("USERIAL_Open(): wait for close-thread");
+ sleep (1);
+ }
+ else
+ break;
+ }
+
+ // restore default power off delay settings incase they were changed in userial_set_poweroff_delays()
+ gPrePowerOffDelay = 0;
+ gPostPowerOffDelay = 0;
+
+ if ( !GetStrValue ( NAME_TRANSPORT_DRIVER, userial_dev, sizeof ( userial_dev ) ) )
+ strcpy ( userial_dev, default_transport );
+ if ( GetNumValue ( NAME_UART_PORT, &num, sizeof ( num ) ) )
+ uart_port = num;
+ if ( GetNumValue ( NAME_LOW_SPEED_TRANSPORT, &num, sizeof ( num ) ) )
+ isLowSpeedTransport = num;
+ if ( GetNumValue ( NAME_NFC_WAKE_DELAY, &num, sizeof ( num ) ) )
+ nfc_wake_delay = num;
+ if ( GetNumValue ( NAME_NFC_WRITE_DELAY, &num, sizeof ( num ) ) )
+ nfc_write_delay = num;
+ if ( GetNumValue ( NAME_PERF_MEASURE_FREQ, &num, sizeof ( num ) ) )
+ perf_log_every_count = num;
+ if ( GetNumValue ( NAME_POWER_ON_DELAY, &num, sizeof ( num ) ) )
+ gPowerOnDelay = num;
+ if ( GetNumValue ( NAME_PRE_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+ gPrePowerOffDelay = num;
+ if ( GetNumValue ( NAME_POST_POWER_OFF_DELAY, &num, sizeof ( num ) ) )
+ gPostPowerOffDelay = num;
+ if ( GetNumValue ( NAME_POWER_OFF_MODE, &num, sizeof ( num ) ) )
+ gPowerOffMode = num;
+ ALOGI("USERIAL_Open() device: %s port=%d, uart_port=%d WAKE_DELAY(%d) WRITE_DELAY(%d) POWER_ON_DELAY(%d) PRE_POWER_OFF_DELAY(%d) POST_POWER_OFF_DELAY(%d)",
+ (char*)userial_dev, port, uart_port, nfc_wake_delay, nfc_write_delay, gPowerOnDelay, gPrePowerOffDelay,
+ gPostPowerOffDelay);
+
+ strcpy((char*)device_name, (char*)userial_dev);
+ sRxLength = 0;
+ _poll_t0 = 0;
+
+ if ((strncmp(userial_dev, ttyusb, sizeof(ttyusb)-1) == 0) ||
+ (strncmp(userial_dev, devtty, sizeof(devtty)-1) == 0) )
+ {
+ if (uart_port >= MAX_SERIAL_PORT)
+ {
+ ALOGD( "Port > MAX_SERIAL_PORT\n");
+ goto done_open;
+ }
+ bSerialPortDevice = TRUE;
+ sprintf((char*)device_name, "%s%d", (char*)userial_dev, uart_port);
+ ALOGI("USERIAL_Open() using device_name: %s ", (char*)device_name);
+ if (!userial_to_tcio_baud(p_cfg->baud, &baud))
+ goto done_open;
+
+ 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
+ goto done_open;
+
+ 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
+ goto done_open;
+
+ if (p_cfg->fmt & USERIAL_STOPBITS_1)
+ stop_bits = 0;
+ else if (p_cfg->fmt & USERIAL_STOPBITS_2)
+ stop_bits = CSTOPB;
+ else
+ goto done_open;
+ }
+ else
+ strcpy((char*)device_name, (char*)userial_dev);
+
+ {
+ ALOGD("%s Opening %s\n", __FUNCTION__, device_name);
+ if ((linux_cb.sock = open((char*)device_name, O_RDWR | O_NOCTTY )) == -1)
+ {
+ ALOGI("%s unable to open %s", __FUNCTION__, device_name);
+ GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+ goto done_open;
+ }
+ ALOGD( "%s sock = %d\n", __FUNCTION__, linux_cb.sock);
+ if (GetStrValue ( NAME_POWER_CONTROL_DRIVER, power_control_dev, sizeof ( power_control_dev ) ) &&
+ power_control_dev[0] != '\0')
+ {
+ if (strcmp(power_control_dev, userial_dev) == 0)
+ linux_cb.sock_power_control = linux_cb.sock;
+ else
+ {
+ if ((linux_cb.sock_power_control = open((char*)power_control_dev, O_RDWR | O_NOCTTY )) == -1)
+ {
+ ALOGI("%s unable to open %s", __FUNCTION__, power_control_dev);
+ }
+ }
+ }
+ if ( bSerialPortDevice )
+ {
+ tcflush(linux_cb.sock, TCIOFLUSH);
+ tcgetattr(linux_cb.sock, &termios);
+
+ termios.c_cflag &= ~(CSIZE | PARENB);
+ termios.c_cflag = CLOCAL|CREAD|data_bits|stop_bits|parity;
+ if (!parity)
+ termios.c_cflag |= IGNPAR;
+ // termios.c_cflag &= ~CRTSCTS;
+ termios.c_oflag = 0;
+ termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
+ termios.c_iflag &= ~(BRKINT | ICRNL | INLCR | ISTRIP | IXON | IGNBRK | PARMRK | INPCK);
+ termios.c_lflag = 0;
+ termios.c_iflag = 0;
+ cfsetospeed(&termios, baud);
+ cfsetispeed(&termios, baud);
+
+ termios.c_cc[VTIME] = 0;
+ termios.c_cc[VMIN] = 1;
+ tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+ tcflush(linux_cb.sock, TCIOFLUSH);
+
+#if (USERIAL_USE_IO_BT_WAKE==TRUE)
+ userial_io_init_bt_wake( linux_cb.sock, &linux_cb.bt_wake_state );
+#endif
+ GKI_delay(gPowerOnDelay);
+ }
+ else
+ {
+ USERIAL_PowerupDevice(port);
+ }
+ }
+
+ linux_cb.ser_cb = p_cback;
+ linux_cb.port = port;
+ memcpy(&linux_cb.open_cfg, p_cfg, sizeof(tUSERIAL_OPEN_CFG));
+ GKI_create_task ((TASKPTR)userial_read_thread, USERIAL_HAL_TASK, (INT8*)"USERIAL_HAL_TASK", 0, 0, (pthread_cond_t*)NULL, NULL);
+
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+ ALOGD( "Leaving USERIAL_Open\n");
+#endif
+
+#if (SERIAL_AMBA == TRUE)
+ /* give 20ms time for reader thread */
+ GKI_delay(20);
+#endif
+
+done_open:
+ pthread_mutex_unlock(&close_thread_mutex);
+ ALOGI("USERIAL_Open(): exit");
+ return;
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Read
+**
+** Description Read data from a serial port using byte buffers.
+**
+** Output Parameter None
+**
+** Returns Number of bytes actually read from the serial port and
+** copied into p_data. This may be less than len.
+**
+*******************************************************************************/
+
+static BT_HDR *pbuf_USERIAL_Read = NULL;
+
+UDRV_API UINT16 USERIAL_Read(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+ UINT16 total_len = 0;
+ UINT16 copy_len = 0;
+ UINT8 * current_packet = NULL;
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+ ALOGD( "%s ++ len=%d pbuf_USERIAL_Read=%p, p_data=%p\n", __func__, len, pbuf_USERIAL_Read, p_data);
+#endif
+ do
+ {
+ if (pbuf_USERIAL_Read != NULL)
+ {
+ current_packet = ((UINT8 *)(pbuf_USERIAL_Read + 1)) + (pbuf_USERIAL_Read->offset);
+
+ if ((pbuf_USERIAL_Read->len) <= (len - total_len))
+ copy_len = pbuf_USERIAL_Read->len;
+ else
+ copy_len = (len - total_len);
+
+ memcpy((p_data + total_len), current_packet, copy_len);
+
+ total_len += copy_len;
+
+ pbuf_USERIAL_Read->offset += copy_len;
+ pbuf_USERIAL_Read->len -= copy_len;
+
+ if (pbuf_USERIAL_Read->len == 0)
+ {
+ GKI_freebuf(pbuf_USERIAL_Read);
+ pbuf_USERIAL_Read = NULL;
+ }
+ }
+
+ if (pbuf_USERIAL_Read == NULL && (total_len < len))
+ pbuf_USERIAL_Read = (BT_HDR *)GKI_dequeue(&Userial_in_q);
+
+ } while ((pbuf_USERIAL_Read != NULL) && (total_len < len));
+
+#if (defined USERIAL_DEBUG) && (USERIAL_DEBUG == TRUE)
+ ALOGD( "%s: returned %d bytes", __func__, total_len);
+#endif
+ return total_len;
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Readbuf
+**
+** Description Read data from a serial port using GKI buffers.
+**
+** Output Parameter Pointer to a GKI buffer which contains the data.
+**
+** Returns Nothing
+**
+** Comments The caller of this function is responsible for freeing the
+** GKI buffer when it is finished with the data. If there is
+** no data to be read, the value of the returned pointer is
+** NULL.
+**
+*******************************************************************************/
+
+UDRV_API void USERIAL_ReadBuf(tUSERIAL_PORT port, BT_HDR **p_buf)
+{
+
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_WriteBuf
+**
+** Description Write data to a serial port using a GKI buffer.
+**
+** Output Parameter None
+**
+** Returns TRUE if buffer accepted for write.
+** FALSE if there is already a buffer being processed.
+**
+** Comments The buffer will be freed by the serial driver. Therefore,
+** the application calling this function must not free the
+** buffer.
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT port, BT_HDR *p_buf)
+{
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Write
+**
+** Description Write data to a serial port using a byte buffer.
+**
+** Output Parameter None
+**
+** Returns Number of bytes actually written to the transport. This
+** may be less than len.
+**
+*******************************************************************************/
+UDRV_API UINT16 USERIAL_Write(tUSERIAL_PORT port, UINT8 *p_data, UINT16 len)
+{
+ int ret = 0, total = 0;
+ int i = 0;
+ clock_t t;
+
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write: (%d bytes)", len);
+ pthread_mutex_lock(&close_thread_mutex);
+
+ doWriteDelay();
+ t = clock();
+ while (len != 0 && linux_cb.sock != -1)
+ {
+ ret = write(linux_cb.sock, p_data + total, len);
+ if (ret < 0)
+ {
+ ALOGE("USERIAL_Write len = %d, ret = %d, errno = %d", len, ret, errno);
+ break;
+ }
+ else
+ {
+ ALOGD_IF((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "USERIAL_Write len = %d, ret = %d", len, ret);
+ }
+
+ total += ret;
+ len -= ret;
+ }
+ perf_update(&perf_write, clock() - t, total);
+
+ /* register a delay for next write */
+ setWriteDelay(total * nfc_write_delay / 1000);
+
+ pthread_mutex_unlock(&close_thread_mutex);
+
+ return ((UINT16)total);
+}
+
+/*******************************************************************************
+**
+** Function userial_change_rate
+**
+** Description change naud rate
+**
+** Output Parameter None
+**
+** Returns None
+**
+*******************************************************************************/
+void userial_change_rate(UINT8 baud)
+{
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+ struct termios termios;
+#endif
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==TRUE)
+ UINT32 tcio_baud;
+#endif
+
+#if defined (USING_BRCM_USB) && (USING_BRCM_USB == FALSE)
+ tcflush(linux_cb.sock, TCIOFLUSH);
+
+ tcgetattr(linux_cb.sock, &termios);
+
+ cfmakeraw(&termios);
+ cfsetospeed(&termios, baud);
+ cfsetispeed(&termios, baud);
+
+ termios.c_cflag |= (CLOCAL | CREAD | CRTSCTS | stop_bits);
+
+ tcsetattr(linux_cb.sock, TCSANOW, &termios);
+ tcflush(linux_cb.sock, TCIOFLUSH);
+
+#else
+#if (USERIAL_USE_TCIO_BAUD_CHANGE==FALSE)
+ fprintf(stderr, "userial_change_rate: Closing UART Port\n");
+ ALOGI("userial_change_rate: Closing UART Port\n");
+ USERIAL_Close(linux_cb.port);
+
+ GKI_delay(50);
+
+ /* change baud rate in settings - leave everything else the same */
+ linux_cb.open_cfg.baud = baud;
+
+ ALOGD( "userial_change_rate: Attempting to reopen the UART Port at 0x%08x\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+ ALOGI("userial_change_rate: Attempting to reopen the UART Port at %i\n", (unsigned int)USERIAL_GetLineSpeed(baud));
+
+ USERIAL_Open(linux_cb.port, &linux_cb.open_cfg, linux_cb.ser_cb);
+#else /* amba uart */
+ fprintf(stderr, "userial_change_rate(): changeing baud rate via TCIO \n");
+ ALOGI( "userial_change_rate: (): changeing baud rate via TCIO \n");
+ /* change baud rate in settings - leave everything else the same */
+ linux_cb.open_cfg.baud = baud;
+ if (!userial_to_tcio_baud(linux_cb.open_cfg.baud, &tcio_baud))
+ return;
+
+ tcflush(linux_cb.sock, TCIOFLUSH);
+
+ /* get current settings. they should be fine besides baud rate we want to change */
+ tcgetattr(linux_cb.sock, &termios);
+
+ /* set input/output baudrate */
+ cfsetospeed(&termios, tcio_baud);
+ cfsetispeed(&termios, tcio_baud);
+ tcsetattr(linux_cb.sock, TCSANOW, &termios);
+
+ tcflush(linux_cb.sock, TCIOFLUSH);
+#endif
+#endif /* USING_BRCM_USB */
+}
+
+/*******************************************************************************
+**
+** Function userial_close_port
+**
+** Description close the transport driver
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void userial_close_port( void )
+{
+ USERIAL_Close(linux_cb.port);
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Ioctl
+**
+** Description Perform an operation on a serial port.
+**
+** Output Parameter The p_data parameter is either an input or output depending
+** on the operation.
+**
+** Returns Nothing
+**
+*******************************************************************************/
+
+UDRV_API void USERIAL_Ioctl(tUSERIAL_PORT port, tUSERIAL_OP op, tUSERIAL_IOCTL_DATA *p_data)
+{
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+ USB_SCO_CONTROL ioctl_data;
+
+ /* just ignore port parameter as we are using USB in this case */
+#endif
+
+ switch (op)
+ {
+ case USERIAL_OP_FLUSH:
+ break;
+ case USERIAL_OP_FLUSH_RX:
+ break;
+ case USERIAL_OP_FLUSH_TX:
+ break;
+ case USERIAL_OP_BAUD_WR:
+ ALOGI( "USERIAL_Ioctl: Received USERIAL_OP_BAUD_WR on port: %d, ioctl baud%i\n", port, p_data->baud);
+ linux_cb.port = port;
+ userial_change_rate(p_data->baud);
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function USERIAL_SetPowerOffDelays
+**
+** Description Set power off delays used during USERIAL_Close(). The
+** values in the conf. file setting override these if set.
+**
+** Returns None.
+**
+*******************************************************************************/
+UDRV_API void USERIAL_SetPowerOffDelays(int pre_poweroff_delay, int post_poweroff_delay)
+{
+ gPrePowerOffDelay = pre_poweroff_delay;
+ gPostPowerOffDelay = post_poweroff_delay;
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Close
+**
+** Description Close a serial port
+**
+** Output Parameter None
+**
+** Returns Nothing
+**
+*******************************************************************************/
+UDRV_API void USERIAL_Close(tUSERIAL_PORT port)
+{
+ pthread_attr_t attr;
+ pthread_t close_thread;
+ UINT8 res[10];
+ UINT32 delay = 100;
+
+ ALOGD ("%s: enter; gPowerOffMode=%d", __FUNCTION__, gPowerOffMode);
+
+ /* Do we need to put NFCC into certain mode before switching off?... */
+ if (gPowerOffMode != POM_NORMAL)
+ {
+ switch (gPowerOffMode)
+ {
+ case POM_CE3SO:
+ ALOGD ("%s: Sending Set_PwrLevel cmd to go to CE3-SO mode", __FUNCTION__);
+ USERIAL_Write(port, ce3_so_cmd, sizeof (ce3_so_cmd));
+ delay = 1000;
+ break;
+
+ case POM_NFC_OFF:
+ ALOGD ("%s: Sending Set_NfcOff cmd", __FUNCTION__);
+ USERIAL_Write(port, set_nfc_off_cmd, sizeof (set_nfc_off_cmd));
+ break;
+ }
+
+ USERIAL_Read(port, res, sizeof ( res ));
+ GKI_delay(delay);
+ }
+
+ // check to see if thread is already running
+ if (pthread_mutex_trylock(&close_thread_mutex) == 0)
+ {
+ // mutex aquired so thread is not running
+ is_close_thread_is_waiting = TRUE;
+ pthread_mutex_unlock(&close_thread_mutex);
+
+ // close transport in a new thread so we don't block the caller
+ // make thread detached, no other thread will join
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create( &close_thread, &attr, (void *)userial_close_thread, NULL);
+ pthread_attr_destroy(&attr);
+ }
+ else
+ {
+ // mutex not aquired to thread is already running
+ ALOGD( "USERIAL_Close(): already closing \n");
+ }
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+/*******************************************************************************
+**
+** Function userial_close_thread
+**
+** Description Thread to close USERIAL
+**
+** Returns None.
+**
+*******************************************************************************/
+void userial_close_thread(UINT32 params)
+{
+ BT_HDR *p_buf = NULL;
+ int result;
+
+ ALOGD( "%s: closing transport (%d)\n", __FUNCTION__, linux_cb.sock);
+ pthread_mutex_lock(&close_thread_mutex);
+ is_close_thread_is_waiting = FALSE;
+
+ if (linux_cb.sock <= 0)
+ {
+ ALOGD( "%s: already closed (%d)\n", __FUNCTION__, linux_cb.sock);
+ pthread_mutex_unlock(&close_thread_mutex);
+ return;
+ }
+
+ send_wakeup_signal();
+ result = pthread_join( worker_thread1, NULL );
+ if ( result < 0 )
+ ALOGE( "%s: pthread_join() FAILED: result: %d", __FUNCTION__, result );
+ else
+ ALOGD( "%s: pthread_join() joined: result: %d", __FUNCTION__, result );
+
+ if (linux_cb.sock_power_control > 0)
+ {
+ result = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, sleep_state());
+ ALOGD("%s: Delay %dms before turning off the chip", __FUNCTION__, gPrePowerOffDelay);
+ GKI_delay(gPrePowerOffDelay);
+ result = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+ ALOGD("%s: Delay %dms after turning off the chip", __FUNCTION__, gPostPowerOffDelay);
+ GKI_delay(gPostPowerOffDelay);
+ }
+ result = close(linux_cb.sock);
+ if (result == -1)
+ ALOGE("%s: fail close linux_cb.sock; errno=%d", __FUNCTION__, errno);
+
+ if (linux_cb.sock_power_control > 0 && linux_cb.sock_power_control != linux_cb.sock)
+ result = close(linux_cb.sock_power_control);
+ if (result == -1)
+ ALOGE("%s: fail close linux_cb.sock_power_control; errno=%d", __FUNCTION__, errno);
+
+ linux_cb.sock_power_control = -1;
+ linux_cb.sock = -1;
+
+ close_signal_fds();
+ pthread_mutex_unlock(&close_thread_mutex);
+ ALOGD("%s: exiting", __FUNCTION__);
+}
+
+/*******************************************************************************
+**
+** Function USERIAL_Feature
+**
+** Description Check whether a feature of the serial API is supported.
+**
+** Output Parameter None
+**
+** Returns TRUE if the feature is supported
+** FALSE if the feature is not supported
+**
+*******************************************************************************/
+
+UDRV_API BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE feature)
+{
+ switch (feature)
+ {
+ case USERIAL_FEAT_PORT_1:
+ case USERIAL_FEAT_PORT_2:
+ case USERIAL_FEAT_PORT_3:
+ case USERIAL_FEAT_PORT_4:
+
+ case USERIAL_FEAT_BAUD_600:
+ case USERIAL_FEAT_BAUD_1200:
+ case USERIAL_FEAT_BAUD_9600:
+ case USERIAL_FEAT_BAUD_19200:
+ case USERIAL_FEAT_BAUD_57600:
+ case USERIAL_FEAT_BAUD_115200:
+
+ case USERIAL_FEAT_STOPBITS_1:
+ case USERIAL_FEAT_STOPBITS_2:
+
+ case USERIAL_FEAT_PARITY_NONE:
+ case USERIAL_FEAT_PARITY_EVEN:
+ case USERIAL_FEAT_PARITY_ODD:
+
+ case USERIAL_FEAT_DATABITS_5:
+ case USERIAL_FEAT_DATABITS_6:
+ case USERIAL_FEAT_DATABITS_7:
+ case USERIAL_FEAT_DATABITS_8:
+
+ case USERIAL_FEAT_FC_HW:
+ case USERIAL_FEAT_BUF_BYTE:
+
+ case USERIAL_FEAT_OP_FLUSH_RX:
+ case USERIAL_FEAT_OP_FLUSH_TX:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/*****************************************************************************
+**
+** Function UPIO_Set
+**
+** Description
+** This function sets one or more GPIO devices to the given state.
+** Multiple GPIOs of the same type can be masked together to set more
+** than one GPIO. This function can only be used on types UPIO_LED and
+** UPIO_GENERAL.
+**
+** Input Parameters:
+** type The type of device.
+** pio Indicates the particular GPIOs.
+** state The desired state.
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** None.
+**
+*****************************************************************************/
+UDRV_API void UPIO_Set(tUPIO_TYPE type, tUPIO pio, tUPIO_STATE new_state)
+{
+ int ret;
+ if (type == UPIO_GENERAL)
+ {
+ if (pio == NFC_HAL_LP_NFC_WAKE_GPIO)
+ {
+ if (new_state == UPIO_ON || new_state == UPIO_OFF)
+ {
+ if (linux_cb.sock_power_control > 0)
+ {
+ ALOGD("%s: ioctl, state=%d", __func__, new_state);
+ ret = ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, new_state);
+ if (isWake(new_state) && nfc_wake_delay > 0 && new_state != current_nfc_wake_state)
+ {
+ ALOGD("%s: ioctl, old state=%d, insert delay for %d ms", __func__, current_nfc_wake_state, nfc_wake_delay);
+ setWriteDelay(nfc_wake_delay);
+ }
+ current_nfc_wake_state = new_state;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+**
+** Function setReadPacketSize
+**
+** Description
+** This function sets the packetSize to the driver.
+** this enables faster read operation of NCI/HCI responses
+**
+** Input Parameters:
+** len number of bytes to read per operation.
+**
+** Output Parameter:
+** None.
+**
+** Returns:
+** None.
+**
+*****************************************************************************/
+void setReadPacketSize(int len)
+{
+ int ret;
+ ALOGD("%s: ioctl, len=%d", __func__, len);
+ ret = ioctl(linux_cb.sock, BCMNFC_READ_FULL_PACKET, len);
+}
+
+
+UDRV_API BOOLEAN USERIAL_IsClosed()
+{
+ return (linux_cb.sock == -1) ? TRUE : FALSE;
+}
+
+UDRV_API void USERIAL_PowerupDevice(tUSERIAL_PORT port)
+{
+ int ret = -1;
+ unsigned long num = 0;
+ unsigned int resetSuccess = 0;
+ unsigned int numTries = 0;
+ unsigned char spi_negotiation[64];
+ int delay = gPowerOnDelay;
+ ALOGD("%s: enter", __FUNCTION__);
+
+ if ( GetNumValue ( NAME_READ_MULTI_PACKETS, &num, sizeof ( num ) ) )
+ bcmi2cnfc_read_multi_packets = num;
+
+ if (bcmi2cnfc_read_multi_packets > 0)
+ ioctl(linux_cb.sock, BCMNFC_READ_MULTI_PACKETS, bcmi2cnfc_read_multi_packets);
+
+ while (!resetSuccess && numTries < NUM_RESET_ATTEMPTS) {
+ if (numTries++ > 0) {
+ ALOGW("BCM2079x: retrying reset, attempt %d/%d", numTries, NUM_RESET_ATTEMPTS);
+ }
+ if (linux_cb.sock_power_control > 0)
+ {
+ current_nfc_wake_state = NFC_WAKE_ASSERTED_ON_POR;
+ ioctl(linux_cb.sock_power_control, BCMNFC_WAKE_CTL, NFC_WAKE_ASSERTED_ON_POR);
+ ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 0);
+ GKI_delay(10);
+ ret = ioctl(linux_cb.sock_power_control, BCMNFC_POWER_CTL, 1);
+ }
+
+ ret = GetStrValue ( NAME_SPI_NEGOTIATION, (char*)spi_negotiation, sizeof ( spi_negotiation ) );
+ if (ret > 0 && spi_negotiation[0] > 0 && spi_negotiation[0] < sizeof ( spi_negotiation ) - 1)
+ {
+ int len = spi_negotiation[0];
+ /* Wake control is not available: Start SPI negotiation*/
+ USERIAL_Write(port, &spi_negotiation[1], len);
+ USERIAL_Read(port, spi_nego_res, sizeof ( spi_nego_res ));
+ }
+
+ if ( GetNumValue ( NAME_CLIENT_ADDRESS, &num, sizeof ( num ) ) )
+ bcmi2cnfc_client_addr = num & 0xFF;
+ if (bcmi2cnfc_client_addr != 0 &&
+ 0x07 < bcmi2cnfc_client_addr &&
+ bcmi2cnfc_client_addr < 0x78)
+ {
+ /* Delay needed after turning on chip */
+ GKI_delay(delay);
+ ALOGD( "Change client address to %x\n", bcmi2cnfc_client_addr);
+ ret = change_client_addr(bcmi2cnfc_client_addr);
+ if (!ret) {
+ resetSuccess = 1;
+ linux_cb.client_device_address = bcmi2cnfc_client_addr;
+ /* Delay long enough for address change */
+ /* MACO xxx this needs to be at least 200 ms for BCM2079x B3 */
+ delay = 200;
+ }
+ } else {
+ resetSuccess = 1;
+ }
+ }
+
+ if (!resetSuccess) {
+ ALOGE("BCM2079x: failed to initialize NFC controller");
+ }
+
+ GKI_delay(delay);
+ ALOGD("%s: exit", __FUNCTION__);
+}
+
+#define DEFAULT_CLIENT_ADDRESS 0x77
+#define ALIAS_CLIENT_ADDRESS 0x79
+static int change_client_addr(int addr)
+{
+ int ret;
+ int i;
+ char addr_data[] = {
+ 0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
+ };
+ int size = sizeof(addr_data) - 1;
+
+ addr_data[5] = addr & 0xFF;
+
+ /* set the checksum */
+ ret = 0;
+ for (i = 1; i < size; ++i)
+ ret += addr_data[i];
+ addr_data[size] = (ret & 0xFF);
+ ALOGD( "change_client_addr() change addr from 0x%x to 0x%x\n", DEFAULT_CLIENT_ADDRESS, addr);
+ /* ignore the return code from IOCTL */
+ /* always revert back to the default client address */
+ ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, DEFAULT_CLIENT_ADDRESS);
+ /* Send address change command (skipping first byte) */
+ ret = write(linux_cb.sock, &addr_data[1], size);
+
+ /* If it fails, it is likely a B3 we are talking to */
+ if (ret != size) {
+ ALOGD( "change_client_addr() change addr to 0x%x by setting BSP address to 0x%x\n", addr, ALIAS_CLIENT_ADDRESS);
+ /* legacy kernel */
+ /* MACO xxx commented out code below only works with new kernel driver,
+ * but Mako/Manta ship with old one */
+ ret = ioctl(linux_cb.sock, BCMNFC_CHANGE_ADDR, addr);
+ return ret;
+ /*
+ ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, ALIAS_CLIENT_ADDRESS);
+ size++;
+ ret = write(linux_cb.sock, addr_data, size);
+ */
+ }
+
+ if (ret == size) {
+ ALOGD( "change_client_addr() set client address 0x%x to client driver\n", addr);
+ ret = ioctl(linux_cb.sock, BCMNFC_SET_CLIENT_ADDR, addr);
+ }
+ else {
+ ret = -EIO;
+ }
+ return ret;
+}
diff --git a/halimpl/bcm2079x/gki/common/gki.h b/halimpl/bcm2079x/gki/common/gki.h
new file mode 100644
index 0000000..f2e6f1a
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki.h
@@ -0,0 +1,517 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_H
+#define GKI_H
+
+#ifdef BUILDCFG
+#if (!defined(NFC_HAL_TARGET) || (NFC_HAL_TARGET == FALSE))
+ #include "buildcfg.h"
+#else
+ /* Build config when building HAL */
+ #include "buildcfg_hal.h"
+#endif
+#endif
+
+/* Include platform-specific over-rides */
+#if (defined(NFC_STANDALONE) && (NFC_STANDALONE == TRUE))
+ #include "gki_target.h"
+ #include "bt_types.h"
+#elif (defined(NFC_HAL_TARGET) && (NFC_HAL_TARGET == TRUE))
+ /* If building NFC HAL, then use hal target file */
+ #include "gki_hal_target.h"
+ #include "nfc_types.h"
+#else
+ /* For non-nfc_standalone, include Bluetooth definitions */
+ #include "bt_target.h"
+ #include "bt_types.h"
+#endif
+
+/* Uncomment this line for verbose GKI debugging and buffer tracking */
+/*#define GKI_BUFFER_DEBUG TRUE*/
+
+
+/* Error codes */
+#define GKI_SUCCESS 0x00
+#define GKI_FAILURE 0x01
+#define GKI_INVALID_TASK 0xF0
+#define GKI_INVALID_POOL 0xFF
+
+
+/************************************************************************
+** Mailbox definitions. Each task has 4 mailboxes that are used to
+** send buffers to the task.
+*/
+#define TASK_MBOX_0 0
+#define TASK_MBOX_1 1
+#define TASK_MBOX_2 2
+#define TASK_MBOX_3 3
+
+#define NUM_TASK_MBOX 4
+
+/************************************************************************
+** Event definitions.
+**
+** There are 4 reserved events used to signal messages rcvd in task mailboxes.
+** There are 4 reserved events used to signal timeout events.
+** There are 8 general purpose events available for applications.
+*/
+#define MAX_EVENTS 16
+
+#define TASK_MBOX_0_EVT_MASK 0x0001
+#define TASK_MBOX_1_EVT_MASK 0x0002
+#define TASK_MBOX_2_EVT_MASK 0x0004
+#define TASK_MBOX_3_EVT_MASK 0x0008
+
+
+#define TIMER_0 0
+#define TIMER_1 1
+#define TIMER_2 2
+#define TIMER_3 3
+
+#define TIMER_0_EVT_MASK 0x0010
+#define TIMER_1_EVT_MASK 0x0020
+#define TIMER_2_EVT_MASK 0x0040
+#define TIMER_3_EVT_MASK 0x0080
+
+#define APPL_EVT_0 8
+#define APPL_EVT_1 9
+#define APPL_EVT_2 10
+#define APPL_EVT_3 11
+#define APPL_EVT_4 12
+#define APPL_EVT_5 13
+#define APPL_EVT_6 14
+#define APPL_EVT_7 15
+
+#define EVENT_MASK(evt) ((UINT16)(0x0001 << (evt)))
+
+/************************************************************************
+** Max Time Queue
+**/
+#ifndef GKI_MAX_TIMER_QUEUES
+#define GKI_MAX_TIMER_QUEUES 3
+#endif
+
+
+/************************************************************************
+** Macro to determine the pool buffer size based on the GKI POOL ID at compile time.
+** Pool IDs index from 0 to GKI_NUM_FIXED_BUF_POOLS - 1
+*/
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 1)
+
+#ifndef GKI_POOL_ID_0
+#define GKI_POOL_ID_0 0
+#endif /* ifndef GKI_POOL_ID_0 */
+
+#ifndef GKI_BUF0_SIZE
+#define GKI_BUF0_SIZE 0
+#endif /* ifndef GKI_BUF0_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 1 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 2)
+
+#ifndef GKI_POOL_ID_1
+#define GKI_POOL_ID_1 0
+#endif /* ifndef GKI_POOL_ID_1 */
+
+#ifndef GKI_BUF1_SIZE
+#define GKI_BUF1_SIZE 0
+#endif /* ifndef GKI_BUF1_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 2 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 3)
+
+#ifndef GKI_POOL_ID_2
+#define GKI_POOL_ID_2 0
+#endif /* ifndef GKI_POOL_ID_2 */
+
+#ifndef GKI_BUF2_SIZE
+#define GKI_BUF2_SIZE 0
+#endif /* ifndef GKI_BUF2_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 3 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 4)
+
+#ifndef GKI_POOL_ID_3
+#define GKI_POOL_ID_3 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF3_SIZE
+#define GKI_BUF3_SIZE 0
+#endif /* ifndef GKI_BUF3_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 4 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 5)
+
+#ifndef GKI_POOL_ID_4
+#define GKI_POOL_ID_4 0
+#endif /* ifndef GKI_POOL_ID_4 */
+
+#ifndef GKI_BUF4_SIZE
+#define GKI_BUF4_SIZE 0
+#endif /* ifndef GKI_BUF4_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 5 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 6)
+
+#ifndef GKI_POOL_ID_5
+#define GKI_POOL_ID_5 0
+#endif /* ifndef GKI_POOL_ID_5 */
+
+#ifndef GKI_BUF5_SIZE
+#define GKI_BUF5_SIZE 0
+#endif /* ifndef GKI_BUF5_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 6 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 7)
+
+#ifndef GKI_POOL_ID_6
+#define GKI_POOL_ID_6 0
+#endif /* ifndef GKI_POOL_ID_6 */
+
+#ifndef GKI_BUF6_SIZE
+#define GKI_BUF6_SIZE 0
+#endif /* ifndef GKI_BUF6_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 7 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 8)
+
+#ifndef GKI_POOL_ID_7
+#define GKI_POOL_ID_7 0
+#endif /* ifndef GKI_POOL_ID_7 */
+
+#ifndef GKI_BUF7_SIZE
+#define GKI_BUF7_SIZE 0
+#endif /* ifndef GKI_BUF7_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 8 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 9)
+
+#ifndef GKI_POOL_ID_8
+#define GKI_POOL_ID_8 0
+#endif /* ifndef GKI_POOL_ID_8 */
+
+#ifndef GKI_BUF8_SIZE
+#define GKI_BUF8_SIZE 0
+#endif /* ifndef GKI_BUF8_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 9 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 10)
+
+#ifndef GKI_POOL_ID_9
+#define GKI_POOL_ID_9 0
+#endif /* ifndef GKI_POOL_ID_9 */
+
+#ifndef GKI_BUF9_SIZE
+#define GKI_BUF9_SIZE 0
+#endif /* ifndef GKI_BUF9_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 10 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 11)
+
+#ifndef GKI_POOL_ID_10
+#define GKI_POOL_ID_10 0
+#endif /* ifndef GKI_POOL_ID_10 */
+
+#ifndef GKI_BUF10_SIZE
+#define GKI_BUF10_SIZE 0
+#endif /* ifndef GKI_BUF10_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 11 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 12)
+
+#ifndef GKI_POOL_ID_11
+#define GKI_POOL_ID_11 0
+#endif /* ifndef GKI_POOL_ID_11 */
+
+#ifndef GKI_BUF11_SIZE
+#define GKI_BUF11_SIZE 0
+#endif /* ifndef GKI_BUF11_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 12 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 13)
+
+#ifndef GKI_POOL_ID_12
+#define GKI_POOL_ID_12 0
+#endif /* ifndef GKI_POOL_ID_12 */
+
+#ifndef GKI_BUF12_SIZE
+#define GKI_BUF12_SIZE 0
+#endif /* ifndef GKI_BUF12_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 13 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 14)
+
+#ifndef GKI_POOL_ID_13
+#define GKI_POOL_ID_13 0
+#endif /* ifndef GKI_POOL_ID_13 */
+
+#ifndef GKI_BUF13_SIZE
+#define GKI_BUF13_SIZE 0
+#endif /* ifndef GKI_BUF13_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 14 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 15)
+
+#ifndef GKI_POOL_ID_14
+#define GKI_POOL_ID_14 0
+#endif /* ifndef GKI_POOL_ID_14 */
+
+#ifndef GKI_BUF14_SIZE
+#define GKI_BUF14_SIZE 0
+#endif /* ifndef GKI_BUF14_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 15 */
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS < 16)
+
+#ifndef GKI_POOL_ID_15
+#define GKI_POOL_ID_15 0
+#endif /* ifndef GKI_POOL_ID_15 */
+
+#ifndef GKI_BUF15_SIZE
+#define GKI_BUF15_SIZE 0
+#endif /* ifndef GKI_BUF15_SIZE */
+
+#endif /* GKI_NUM_FIXED_BUF_POOLS < 16 */
+
+
+/* Timer list entry callback type
+*/
+typedef void (TIMER_CBACK)(void *p_tle);
+#ifndef TIMER_PARAM_TYPE
+#ifdef WIN2000
+#define TIMER_PARAM_TYPE void *
+#else
+#define TIMER_PARAM_TYPE UINT32
+#endif
+#endif
+/* Define a timer list entry
+*/
+typedef struct _tle
+{
+ struct _tle *p_next;
+ struct _tle *p_prev;
+ TIMER_CBACK *p_cback;
+ INT32 ticks;
+ TIMER_PARAM_TYPE param;
+ UINT16 event;
+ UINT8 in_use;
+} TIMER_LIST_ENT;
+
+/* Define a timer list queue
+*/
+typedef struct
+{
+ TIMER_LIST_ENT *p_first;
+ TIMER_LIST_ENT *p_last;
+ INT32 last_ticks;
+} TIMER_LIST_Q;
+
+
+/***********************************************************************
+** This queue is a general purpose buffer queue, for application use.
+*/
+typedef struct
+{
+ void *p_first;
+ void *p_last;
+ UINT16 count;
+} BUFFER_Q;
+
+#define GKI_IS_QUEUE_EMPTY(p_q) ((p_q)->count == 0)
+
+/* Task constants
+*/
+#ifndef TASKPTR
+typedef void (*TASKPTR)(UINT32);
+#endif
+
+
+#define GKI_PUBLIC_POOL 0 /* General pool accessible to GKI_getbuf() */
+#define GKI_RESTRICTED_POOL 1 /* Inaccessible pool to GKI_getbuf() */
+
+/***********************************************************************
+** Function prototypes
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Task management
+*/
+GKI_API extern UINT8 GKI_create_task (TASKPTR, UINT8, INT8 *, UINT16 *, UINT16, void*, void*);
+GKI_API extern void GKI_exit_task(UINT8);
+GKI_API extern UINT8 GKI_get_taskid(void);
+GKI_API extern void GKI_init(void);
+GKI_API extern UINT8 *GKI_map_taskname(UINT8);
+GKI_API extern UINT8 GKI_resume_task(UINT8);
+GKI_API extern void GKI_run(void *);
+GKI_API extern void GKI_stop(void);
+GKI_API extern UINT8 GKI_suspend_task(UINT8);
+GKI_API extern UINT8 GKI_is_task_running(UINT8);
+GKI_API extern void GKI_shutdown(void);
+
+/* memory management
+*/
+GKI_API extern void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount);
+GKI_API extern void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len);
+
+/* To send buffers and events between tasks
+*/
+GKI_API extern UINT8 GKI_isend_event (UINT8, UINT16);
+GKI_API extern void GKI_isend_msg (UINT8, UINT8, void *);
+GKI_API extern void *GKI_read_mbox (UINT8);
+GKI_API extern void GKI_send_msg (UINT8, UINT8, void *);
+GKI_API extern UINT8 GKI_send_event (UINT8, UINT16);
+
+
+/* To get and release buffers, change owner and get size
+*/
+GKI_API extern void GKI_change_buf_owner (void *, UINT8);
+GKI_API extern UINT8 GKI_create_pool (UINT16, UINT16, UINT8, void *);
+GKI_API extern void GKI_delete_pool (UINT8);
+GKI_API extern void *GKI_find_buf_start (void *);
+GKI_API extern void GKI_freebuf (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getbuf(size) GKI_getbuf_debug(size, __FUNCTION__, __LINE__)
+GKI_API extern void *GKI_getbuf_debug (UINT16, const char *, int);
+#else
+GKI_API extern void *GKI_getbuf (UINT16);
+#endif
+GKI_API extern UINT16 GKI_get_buf_size (void *);
+#if GKI_BUFFER_DEBUG
+#define GKI_getpoolbuf(id) GKI_getpoolbuf_debug(id, __FUNCTION__, __LINE__)
+GKI_API extern void *GKI_getpoolbuf_debug (UINT8, const char *, int);
+#else
+GKI_API extern void *GKI_getpoolbuf (UINT8);
+#endif
+
+GKI_API extern UINT16 GKI_poolcount (UINT8);
+GKI_API extern UINT16 GKI_poolfreecount (UINT8);
+GKI_API extern UINT16 GKI_poolutilization (UINT8);
+GKI_API extern void GKI_register_mempool (void *p_mem);
+GKI_API extern UINT8 GKI_set_pool_permission(UINT8, UINT8);
+
+
+/* User buffer queue management
+*/
+GKI_API extern void *GKI_dequeue (BUFFER_Q *);
+GKI_API extern void GKI_enqueue (BUFFER_Q *, void *);
+GKI_API extern void GKI_enqueue_head (BUFFER_Q *, void *);
+GKI_API extern void *GKI_getfirst (BUFFER_Q *);
+GKI_API extern void *GKI_getlast (BUFFER_Q *);
+GKI_API extern void *GKI_getnext (void *);
+GKI_API extern void GKI_init_q (BUFFER_Q *);
+GKI_API extern BOOLEAN GKI_queue_is_empty(BUFFER_Q *);
+GKI_API extern void *GKI_remove_from_queue (BUFFER_Q *, void *);
+GKI_API extern UINT16 GKI_get_pool_bufsize (UINT8);
+
+/* Timer management
+*/
+GKI_API extern void GKI_add_to_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern void GKI_delay(UINT32);
+GKI_API extern UINT32 GKI_get_tick_count(void);
+GKI_API extern INT8 *GKI_get_time_stamp(INT8 *);
+GKI_API extern void GKI_init_timer_list (TIMER_LIST_Q *);
+GKI_API extern void GKI_init_timer_list_entry (TIMER_LIST_ENT *);
+GKI_API extern INT32 GKI_ready_to_sleep (void);
+GKI_API extern void GKI_remove_from_timer_list (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern void GKI_start_timer(UINT8, INT32, BOOLEAN);
+GKI_API extern void GKI_stop_timer (UINT8);
+GKI_API extern void GKI_timer_update(INT32);
+GKI_API extern UINT16 GKI_update_timer_list (TIMER_LIST_Q *, INT32);
+GKI_API extern UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *, TIMER_LIST_ENT *);
+GKI_API extern UINT16 GKI_wait(UINT16, UINT32);
+
+/* Start and Stop system time tick callback
+ * true for start system tick if time queue is not empty
+ * false to stop system tick if time queue is empty
+*/
+typedef void (SYSTEM_TICK_CBACK)(BOOLEAN);
+
+/* Time queue management for system ticks
+*/
+GKI_API extern BOOLEAN GKI_timer_queue_empty (void);
+GKI_API extern void GKI_timer_queue_register_callback(SYSTEM_TICK_CBACK *);
+
+/* Disable Interrupts, Enable Interrupts
+*/
+GKI_API extern void GKI_enable(void);
+GKI_API extern void GKI_disable(void);
+GKI_API extern void GKI_sched_lock(void);
+GKI_API extern void GKI_sched_unlock(void);
+
+/* Allocate (Free) memory from an OS
+*/
+GKI_API extern void *GKI_os_malloc (UINT32);
+GKI_API extern void GKI_os_free (void *);
+
+/* os timer operation */
+GKI_API extern UINT32 GKI_get_os_tick_count(void);
+
+/* Exception handling
+*/
+GKI_API extern void GKI_exception (UINT16, char *);
+
+#if GKI_DEBUG == TRUE
+GKI_API extern void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used);
+GKI_API extern void GKI_PrintBuffer(void);
+GKI_API extern void GKI_print_task(void);
+#else
+#undef GKI_PrintBufferUsage
+#define GKI_PrintBuffer() NULL
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/common/gki_buffer.c b/halimpl/bcm2079x/gki/common/gki_buffer.c
new file mode 100644
index 0000000..555bc4b
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_buffer.c
@@ -0,0 +1,1559 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+#include <stdio.h>
+
+#if (GKI_NUM_TOTAL_BUF_POOLS > 16)
+#error Number of pools out of range (16 Max)!
+#endif
+
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+static void gki_add_to_pool_list(UINT8 pool_id);
+static void gki_remove_from_pool_list(UINT8 pool_id);
+#endif /* BTU_STACK_LITE_ENABLED == FALSE */
+
+#if GKI_BUFFER_DEBUG
+#define LOG_TAG "GKI_DEBUG"
+#include <android/log.h>
+#include <cutils/log.h>
+#define LOGD(format, ...) LogMsg (TRACE_CTRL_GENERAL | TRACE_LAYER_GKI | TRACE_ORG_GKI | TRACE_TYPE_GENERIC, format, ## __VA_ARGS__)
+#endif
+/*******************************************************************************
+**
+** Function gki_init_free_queue
+**
+** Description Internal function called at startup to initialize a free
+** queue. It is called once for each free queue.
+**
+** Returns void
+**
+*******************************************************************************/
+static void gki_init_free_queue (UINT8 id, UINT16 size, UINT16 total, void *p_mem)
+{
+ UINT16 i;
+ UINT16 act_size;
+ BUFFER_HDR_T *hdr;
+ BUFFER_HDR_T *hdr1 = NULL;
+ UINT32 *magic;
+ INT32 tempsize = size;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* Ensure an even number of longwords */
+ tempsize = (INT32)ALIGN_POOL(size);
+ act_size = (UINT16)(tempsize + BUFFER_PADDING_SIZE);
+
+ /* Remember pool start and end addresses */
+ if(p_mem)
+ {
+ p_cb->pool_start[id] = (UINT8 *)p_mem;
+ p_cb->pool_end[id] = (UINT8 *)p_mem + (act_size * total);
+ }
+
+ p_cb->pool_size[id] = act_size;
+
+ p_cb->freeq[id].size = (UINT16) tempsize;
+ p_cb->freeq[id].total = total;
+ p_cb->freeq[id].cur_cnt = 0;
+ p_cb->freeq[id].max_cnt = 0;
+
+#if GKI_BUFFER_DEBUG
+ LOGD("gki_init_free_queue() init pool=%d, size=%d (aligned=%d) total=%d start=%p", id, size, tempsize, total, p_mem);
+#endif
+
+ /* Initialize index table */
+ if(p_mem)
+ {
+ hdr = (BUFFER_HDR_T *)p_mem;
+ p_cb->freeq[id].p_first = hdr;
+ for (i = 0; i < total; i++)
+ {
+ hdr->task_id = GKI_INVALID_TASK;
+ hdr->q_id = id;
+ hdr->status = BUF_STATUS_FREE;
+ magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + tempsize);
+ *magic = MAGIC_NO;
+ hdr1 = hdr;
+ hdr = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+ hdr1->p_next = hdr;
+ }
+ hdr1->p_next = NULL;
+ p_cb->freeq[id].p_last = hdr1;
+ }
+ return;
+}
+
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+static BOOLEAN gki_alloc_free_queue(UINT8 id)
+{
+ FREE_QUEUE_T *Q;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+ #if GKI_BUFFER_DEBUG
+ ALOGD("\ngki_alloc_free_queue in, id:%d \n", id);
+ #endif
+
+ Q = &p_cb->freeq[p_cb->pool_list[id]];
+
+ if(Q->p_first == 0)
+ {
+ void* p_mem = GKI_os_malloc((Q->size + BUFFER_PADDING_SIZE) * Q->total);
+ if(p_mem)
+ {
+ //re-initialize the queue with allocated memory
+ #if GKI_BUFFER_DEBUG
+ ALOGD("\ngki_alloc_free_queue calling gki_init_free_queue, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
+ #endif
+ gki_init_free_queue(id, Q->size, Q->total, p_mem);
+ #if GKI_BUFFER_DEBUG
+ ALOGD("\ngki_alloc_free_queue ret OK, id:%d size:%d, totol:%d\n", id, Q->size, Q->total);
+ #endif
+ return TRUE;
+ }
+ GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "gki_alloc_free_queue: Not enough memory");
+ }
+ #if GKI_BUFFER_DEBUG
+ ALOGD("\ngki_alloc_free_queue out failed, id:%d\n", id);
+ #endif
+ return FALSE;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function gki_buffer_init
+**
+** Description Called once internally by GKI at startup to initialize all
+** buffers and free buffer pools.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_buffer_init(void)
+{
+ UINT8 i, tt, mb;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* Initialize mailboxes */
+ for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+ {
+ for (mb = 0; mb < NUM_TASK_MBOX; mb++)
+ {
+ p_cb->OSTaskQFirst[tt][mb] = NULL;
+ p_cb->OSTaskQLast [tt][mb] = NULL;
+ }
+ }
+
+ for (tt = 0; tt < GKI_NUM_TOTAL_BUF_POOLS; tt++)
+ {
+ p_cb->pool_start[tt] = NULL;
+ p_cb->pool_end[tt] = NULL;
+ p_cb->pool_size[tt] = 0;
+
+ p_cb->freeq[tt].p_first = 0;
+ p_cb->freeq[tt].p_last = 0;
+ p_cb->freeq[tt].size = 0;
+ p_cb->freeq[tt].total = 0;
+ p_cb->freeq[tt].cur_cnt = 0;
+ p_cb->freeq[tt].max_cnt = 0;
+ }
+
+ /* Use default from target.h */
+ p_cb->pool_access_mask = GKI_DEF_BUFPOOL_PERM_MASK;
+
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == TRUE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ p_cb->bufpool0 = (UINT8 *)GKI_os_malloc ((GKI_BUF0_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ p_cb->bufpool1 = (UINT8 *)GKI_os_malloc ((GKI_BUF1_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ p_cb->bufpool2 = (UINT8 *)GKI_os_malloc ((GKI_BUF2_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ p_cb->bufpool3 = (UINT8 *)GKI_os_malloc ((GKI_BUF3_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ p_cb->bufpool4 = (UINT8 *)GKI_os_malloc ((GKI_BUF4_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ p_cb->bufpool5 = (UINT8 *)GKI_os_malloc ((GKI_BUF5_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ p_cb->bufpool6 = (UINT8 *)GKI_os_malloc ((GKI_BUF6_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ p_cb->bufpool7 = (UINT8 *)GKI_os_malloc ((GKI_BUF7_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ p_cb->bufpool8 = (UINT8 *)GKI_os_malloc ((GKI_BUF8_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ p_cb->bufpool9 = (UINT8 *)GKI_os_malloc ((GKI_BUF9_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ p_cb->bufpool10 = (UINT8 *)GKI_os_malloc ((GKI_BUF10_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ p_cb->bufpool11 = (UINT8 *)GKI_os_malloc ((GKI_BUF11_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ p_cb->bufpool12 = (UINT8 *)GKI_os_malloc ((GKI_BUF12_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ p_cb->bufpool13 = (UINT8 *)GKI_os_malloc ((GKI_BUF13_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ p_cb->bufpool14 = (UINT8 *)GKI_os_malloc ((GKI_BUF14_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ p_cb->bufpool15 = (UINT8 *)GKI_os_malloc ((GKI_BUF15_SIZE + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX);
+#endif
+
+#endif
+
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ gki_init_free_queue(0, GKI_BUF0_SIZE, GKI_BUF0_MAX, p_cb->bufpool0);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ gki_init_free_queue(1, GKI_BUF1_SIZE, GKI_BUF1_MAX, p_cb->bufpool1);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ gki_init_free_queue(2, GKI_BUF2_SIZE, GKI_BUF2_MAX, p_cb->bufpool2);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ gki_init_free_queue(3, GKI_BUF3_SIZE, GKI_BUF3_MAX, p_cb->bufpool3);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ gki_init_free_queue(4, GKI_BUF4_SIZE, GKI_BUF4_MAX, p_cb->bufpool4);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ gki_init_free_queue(5, GKI_BUF5_SIZE, GKI_BUF5_MAX, p_cb->bufpool5);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ gki_init_free_queue(6, GKI_BUF6_SIZE, GKI_BUF6_MAX, p_cb->bufpool6);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ gki_init_free_queue(7, GKI_BUF7_SIZE, GKI_BUF7_MAX, p_cb->bufpool7);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ gki_init_free_queue(8, GKI_BUF8_SIZE, GKI_BUF8_MAX, p_cb->bufpool8);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ gki_init_free_queue(9, GKI_BUF9_SIZE, GKI_BUF9_MAX, p_cb->bufpool9);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ gki_init_free_queue(10, GKI_BUF10_SIZE, GKI_BUF10_MAX, p_cb->bufpool10);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ gki_init_free_queue(11, GKI_BUF11_SIZE, GKI_BUF11_MAX, p_cb->bufpool11);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ gki_init_free_queue(12, GKI_BUF12_SIZE, GKI_BUF12_MAX, p_cb->bufpool12);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ gki_init_free_queue(13, GKI_BUF13_SIZE, GKI_BUF13_MAX, p_cb->bufpool13);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ gki_init_free_queue(14, GKI_BUF14_SIZE, GKI_BUF14_MAX, p_cb->bufpool14);
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ gki_init_free_queue(15, GKI_BUF15_SIZE, GKI_BUF15_MAX, p_cb->bufpool15);
+#endif
+
+ /* add pools to the pool_list which is arranged in the order of size */
+ for(i=0; i < GKI_NUM_FIXED_BUF_POOLS ; i++)
+ {
+ p_cb->pool_list[i] = i;
+ }
+
+ p_cb->curr_total_no_of_pools = GKI_NUM_FIXED_BUF_POOLS;
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_init_q
+**
+** Description Called by an application to initialize a buffer queue.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_init_q (BUFFER_Q *p_q)
+{
+ p_q->p_first = p_q->p_last = NULL;
+ p_q->count = 0;
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_getbuf
+**
+** Description Called by an application to get a free buffer which
+** is of size greater or equal to the requested size.
+**
+** Note: This routine only takes buffers from public pools.
+** It will not use any buffers from pools
+** marked GKI_RESTRICTED_POOL.
+**
+** Parameters size - (input) number of bytes needed.
+**
+** Returns A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getbuf_debug (UINT16 size, const char * _function_, int _line_)
+#else
+void *GKI_getbuf (UINT16 size)
+#endif
+{
+ UINT8 i;
+ FREE_QUEUE_T *Q;
+ BUFFER_HDR_T *p_hdr;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+#if GKI_BUFFER_DEBUG
+ UINT8 x;
+#endif
+
+ if (size == 0)
+ {
+ GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "getbuf: Size is zero");
+ return (NULL);
+ }
+
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_getbuf() requesting %d func:%s(line=%d)", size, _function_, _line_);
+#endif
+ /* Find the first buffer pool that is public that can hold the desired size */
+ for (i=0; i < p_cb->curr_total_no_of_pools; i++)
+ {
+ if ( size <= p_cb->freeq[p_cb->pool_list[i]].size )
+ break;
+ }
+
+ if(i == p_cb->curr_total_no_of_pools)
+ {
+ GKI_exception (GKI_ERROR_BUF_SIZE_TOOBIG, "getbuf: Size is too big");
+ return (NULL);
+ }
+
+ /* Make sure the buffers aren't disturbed til finished with allocation */
+ GKI_disable();
+
+ /* search the public buffer pools that are big enough to hold the size
+ * until a free buffer is found */
+ for ( ; i < p_cb->curr_total_no_of_pools; i++)
+ {
+ /* Only look at PUBLIC buffer pools (bypass RESTRICTED pools) */
+ if (((UINT16)1 << p_cb->pool_list[i]) & p_cb->pool_access_mask)
+ continue;
+
+ Q = &p_cb->freeq[p_cb->pool_list[i]];
+ if(Q->cur_cnt < Q->total)
+ {
+ #ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+ if(Q->p_first == 0 && gki_alloc_free_queue(i) != TRUE)
+ {
+ GKI_TRACE_ERROR_0("GKI_getbuf() out of buffer");
+ GKI_enable();
+ return NULL;
+ }
+ #endif
+
+ if(Q->p_first == 0)
+ {
+ /* gki_alloc_free_queue() failed to alloc memory */
+ GKI_TRACE_ERROR_0("GKI_getbuf() fail alloc free queue");
+ GKI_enable();
+ return NULL;
+ }
+
+ p_hdr = Q->p_first;
+ Q->p_first = p_hdr->p_next;
+
+ if (!Q->p_first)
+ Q->p_last = NULL;
+
+ if(++Q->cur_cnt > Q->max_cnt)
+ Q->max_cnt = Q->cur_cnt;
+
+ GKI_enable();
+
+ p_hdr->task_id = GKI_get_taskid();
+
+ p_hdr->status = BUF_STATUS_UNLINKED;
+ p_hdr->p_next = NULL;
+ p_hdr->Type = 0;
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_getbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[i].total);
+
+ strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+ p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+ p_hdr->_line = _line_;
+#endif
+ return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+ }
+ }
+
+ GKI_TRACE_ERROR_0("GKI_getbuf() unable to allocate buffer!!!!!");
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_getbuf() unable to allocate buffer!!!!!");
+ LOGD("******************** GKI Memory Pool Dump ********************");
+
+ p_cb = &gki_cb.com;
+
+ LOGD("Dumping total of %d buffer pools", p_cb->curr_total_no_of_pools);
+
+ for (i=0 ; i < p_cb->curr_total_no_of_pools; i++)
+ {
+ p_hdr = (BUFFER_HDR_T *)p_cb->pool_start[i];
+
+ LOGD("pool %d has a total of %d buffers (start=%p)", i, p_cb->freeq[i].total, p_hdr);
+
+ for (x=0; p_hdr && x < p_cb->freeq[i].total; x++)
+ {
+ if (p_hdr->status != BUF_STATUS_FREE)
+ {
+ LOGD("pool:%d, buf[%d]:%x, hdr:%x status=%d func:%s(line=%d)", i, x, (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, p_hdr->status, p_hdr->_function, p_hdr->_line);
+ }
+
+ p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_hdr + p_cb->pool_size[i]);
+ }
+ }
+ LOGD("**************************************************************");
+#endif
+
+ GKI_TRACE_ERROR_0("Failed to allocate GKI buffer");
+
+ GKI_enable();
+
+ return (NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_getpoolbuf
+**
+** Description Called by an application to get a free buffer from
+** a specific buffer pool.
+**
+** Note: If there are no more buffers available from the pool,
+** the public buffers are searched for an available buffer.
+**
+** Parameters pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+#if GKI_BUFFER_DEBUG
+void *GKI_getpoolbuf_debug (UINT8 pool_id, const char * _function_, int _line_)
+#else
+void *GKI_getpoolbuf (UINT8 pool_id)
+#endif
+{
+ FREE_QUEUE_T *Q;
+ BUFFER_HDR_T *p_hdr;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ return (NULL);
+
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_getpoolbuf() requesting from %d func:%s(line=%d)", pool_id, _function_, _line_);
+#endif
+ /* Make sure the buffers aren't disturbed til finished with allocation */
+ GKI_disable();
+
+ Q = &p_cb->freeq[pool_id];
+ if(Q->cur_cnt < Q->total)
+ {
+#ifdef GKI_USE_DEFERED_ALLOC_BUF_POOLS
+ if(Q->p_first == 0 && gki_alloc_free_queue(pool_id) != TRUE)
+ return NULL;
+#endif
+
+ if(Q->p_first == 0)
+ {
+ /* gki_alloc_free_queue() failed to alloc memory */
+ GKI_TRACE_ERROR_0("GKI_getpoolbuf() fail alloc free queue");
+ return NULL;
+ }
+
+ p_hdr = Q->p_first;
+ Q->p_first = p_hdr->p_next;
+
+ if (!Q->p_first)
+ Q->p_last = NULL;
+
+ if(++Q->cur_cnt > Q->max_cnt)
+ Q->max_cnt = Q->cur_cnt;
+
+ GKI_enable();
+
+
+ p_hdr->task_id = GKI_get_taskid();
+
+ p_hdr->status = BUF_STATUS_UNLINKED;
+ p_hdr->p_next = NULL;
+ p_hdr->Type = 0;
+
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_getpoolbuf() allocated, %x, %x (%d of %d used) %d", (UINT8*)p_hdr + BUFFER_HDR_SIZE, p_hdr, Q->cur_cnt, Q->total, p_cb->freeq[pool_id].total);
+
+ strncpy(p_hdr->_function, _function_, _GKI_MAX_FUNCTION_NAME_LEN);
+ p_hdr->_function[_GKI_MAX_FUNCTION_NAME_LEN] = '\0';
+ p_hdr->_line = _line_;
+#endif
+ return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+ }
+
+ /* If here, no buffers in the specified pool */
+ GKI_enable();
+
+#if GKI_BUFFER_DEBUG
+ /* try for free buffers in public pools */
+ return (GKI_getbuf_debug(p_cb->freeq[pool_id].size, _function_, _line_));
+#else
+ /* try for free buffers in public pools */
+ return (GKI_getbuf(p_cb->freeq[pool_id].size));
+#endif
+}
+
+/*******************************************************************************
+**
+** Function GKI_freebuf
+**
+** Description Called by an application to return a buffer to the free pool.
+**
+** Parameters p_buf - (input) address of the beginning of a buffer.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_freebuf (void *p_buf)
+{
+ FREE_QUEUE_T *Q;
+ BUFFER_HDR_T *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+ if (!p_buf || gki_chk_buf_damage(p_buf))
+ {
+ GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Free - Buf Corrupted");
+ return;
+ }
+#endif
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+
+#if GKI_BUFFER_DEBUG
+ LOGD("GKI_freebuf() freeing, %x, %x, func:%s(line=%d)", p_buf, p_hdr, p_hdr->_function, p_hdr->_line);
+#endif
+
+ if (p_hdr->status != BUF_STATUS_UNLINKED)
+ {
+ GKI_exception(GKI_ERROR_FREEBUF_BUF_LINKED, "Freeing Linked Buf");
+ return;
+ }
+
+ if (p_hdr->q_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ {
+ GKI_exception(GKI_ERROR_FREEBUF_BAD_QID, "Bad Buf QId");
+ return;
+ }
+
+ GKI_disable();
+
+ /*
+ ** Release the buffer
+ */
+ Q = &gki_cb.com.freeq[p_hdr->q_id];
+ if (Q->p_last)
+ Q->p_last->p_next = p_hdr;
+ else
+ Q->p_first = p_hdr;
+
+ Q->p_last = p_hdr;
+ p_hdr->p_next = NULL;
+ p_hdr->status = BUF_STATUS_FREE;
+ p_hdr->task_id = GKI_INVALID_TASK;
+ if (Q->cur_cnt > 0)
+ Q->cur_cnt--;
+
+ GKI_enable();
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_buf_size
+**
+** Description Called by an application to get the size of a buffer.
+**
+** Parameters p_buf - (input) address of the beginning of a buffer.
+**
+** Returns the size of the buffer
+**
+*******************************************************************************/
+UINT16 GKI_get_buf_size (void *p_buf)
+{
+ BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (BUFFER_HDR_T *)((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+ if ((UINT32)p_hdr & 1)
+ return (0);
+
+ if (p_hdr->q_id < GKI_NUM_TOTAL_BUF_POOLS)
+ {
+ return (gki_cb.com.freeq[p_hdr->q_id].size);
+ }
+
+ return (0);
+}
+
+/*******************************************************************************
+**
+** Function gki_chk_buf_damage
+**
+** Description Called internally by OSS to check for buffer corruption.
+**
+** Returns TRUE if there is a problem, else FALSE
+**
+*******************************************************************************/
+BOOLEAN gki_chk_buf_damage(void *p_buf)
+{
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+
+ UINT32 *magic;
+ magic = (UINT32 *)((UINT8 *) p_buf + GKI_get_buf_size(p_buf));
+
+ if ((UINT32)magic & 1)
+ return (TRUE);
+
+ if (*magic == MAGIC_NO)
+ return (FALSE);
+
+ return (TRUE);
+
+#else
+
+ return (FALSE);
+
+#endif
+}
+
+/*******************************************************************************
+**
+** Function GKI_send_msg
+**
+** Description Called by applications to send a buffer to a task
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void GKI_send_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+ BUFFER_HDR_T *p_hdr;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* If task non-existant or not started, drop buffer */
+ if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+ {
+ GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+ GKI_freebuf (msg);
+ return;
+ }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+ if (gki_chk_buf_damage(msg))
+ {
+ GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+ return;
+ }
+#endif
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+ if (p_hdr->status != BUF_STATUS_UNLINKED)
+ {
+ GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+ return;
+ }
+
+ GKI_disable();
+
+ if (p_cb->OSTaskQFirst[task_id][mbox])
+ p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+ else
+ p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+ p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+ p_hdr->p_next = NULL;
+ p_hdr->status = BUF_STATUS_QUEUED;
+ p_hdr->task_id = task_id;
+
+
+ GKI_enable();
+
+ GKI_send_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function GKI_read_mbox
+**
+** Description Called by applications to read a buffer from one of
+** the task mailboxes. A task can only read its own mailbox.
+**
+** Parameters: mbox - (input) mailbox ID to read (0, 1, 2, or 3)
+**
+** Returns NULL if the mailbox was empty, else the address of a buffer
+**
+*******************************************************************************/
+void *GKI_read_mbox (UINT8 mbox)
+{
+ UINT8 task_id = GKI_get_taskid();
+ void *p_buf = NULL;
+ BUFFER_HDR_T *p_hdr;
+
+ if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX))
+ return (NULL);
+
+ GKI_disable();
+
+ if (gki_cb.com.OSTaskQFirst[task_id][mbox])
+ {
+ p_hdr = gki_cb.com.OSTaskQFirst[task_id][mbox];
+ gki_cb.com.OSTaskQFirst[task_id][mbox] = p_hdr->p_next;
+
+ p_hdr->p_next = NULL;
+ p_hdr->status = BUF_STATUS_UNLINKED;
+
+ p_buf = (UINT8 *)p_hdr + BUFFER_HDR_SIZE;
+ }
+
+ GKI_enable();
+
+ return (p_buf);
+}
+
+
+
+/*******************************************************************************
+**
+** Function GKI_enqueue
+**
+** Description Enqueue a buffer at the tail of the queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+** p_buf - (input) address of the buffer to enqueue
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_enqueue (BUFFER_Q *p_q, void *p_buf)
+{
+ BUFFER_HDR_T *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+ if (gki_chk_buf_damage(p_buf))
+ {
+ GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+ return;
+ }
+#endif
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+ if (p_hdr->status != BUF_STATUS_UNLINKED)
+ {
+ GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue - buf already linked");
+ return;
+ }
+
+ GKI_disable();
+
+ /* Since the queue is exposed (C vs C++), keep the pointers in exposed format */
+ if (p_q->p_first)
+ {
+ BUFFER_HDR_T *p_last_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_last - 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;
+ p_hdr->status = BUF_STATUS_QUEUED;
+
+ GKI_enable();
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_enqueue_head
+**
+** Description Enqueue a buffer at the head of the queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+** p_buf - (input) address of the buffer to enqueue
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_enqueue_head (BUFFER_Q *p_q, void *p_buf)
+{
+ BUFFER_HDR_T *p_hdr;
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+ if (gki_chk_buf_damage(p_buf))
+ {
+ GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Enqueue - Buffer corrupted");
+ return;
+ }
+#endif
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+ if (p_hdr->status != BUF_STATUS_UNLINKED)
+ {
+ GKI_exception(GKI_ERROR_ENQUEUE_BUF_LINKED, "Eneueue head - buf already linked");
+ return;
+ }
+
+ GKI_disable();
+
+ if (p_q->p_first)
+ {
+ p_hdr->p_next = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+ p_q->p_first = p_buf;
+ }
+ else
+ {
+ p_q->p_first = p_buf;
+ p_q->p_last = p_buf;
+ p_hdr->p_next = NULL;
+ }
+ p_q->count++;
+
+ p_hdr->status = BUF_STATUS_QUEUED;
+
+ GKI_enable();
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_dequeue
+**
+** Description Dequeues a buffer from the head of a queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+**
+** Returns NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_dequeue (BUFFER_Q *p_q)
+{
+ BUFFER_HDR_T *p_hdr;
+
+ GKI_disable();
+
+ if (!p_q || !p_q->count)
+ {
+ GKI_enable();
+ return (NULL);
+ }
+
+ p_hdr = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - BUFFER_HDR_SIZE);
+
+ /* Keep buffers such that GKI header is invisible
+ */
+ if (p_hdr->p_next)
+ p_q->p_first = ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+ else
+ {
+ p_q->p_first = NULL;
+ p_q->p_last = NULL;
+ }
+
+ p_q->count--;
+
+ p_hdr->p_next = NULL;
+ p_hdr->status = BUF_STATUS_UNLINKED;
+
+ GKI_enable();
+
+ return ((UINT8 *)p_hdr + BUFFER_HDR_SIZE);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_remove_from_queue
+**
+** Description Dequeue a buffer from the middle of the queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+** p_buf - (input) address of the buffer to enqueue
+**
+** Returns NULL if queue is empty, else buffer
+**
+*******************************************************************************/
+void *GKI_remove_from_queue (BUFFER_Q *p_q, void *p_buf)
+{
+ BUFFER_HDR_T *p_prev;
+ BUFFER_HDR_T *p_buf_hdr;
+
+ GKI_disable();
+
+ if (p_buf == p_q->p_first)
+ {
+ GKI_enable();
+ return (GKI_dequeue (p_q));
+ }
+
+ p_buf_hdr = (BUFFER_HDR_T *)((UINT8 *)p_buf - BUFFER_HDR_SIZE);
+ p_prev = (BUFFER_HDR_T *)((UINT8 *)p_q->p_first - 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;
+ p_buf_hdr->status = BUF_STATUS_UNLINKED;
+
+ GKI_enable();
+ return (p_buf);
+ }
+ }
+
+ GKI_enable();
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function GKI_getfirst
+**
+** Description Return a pointer to the first buffer in a queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+**
+** Returns NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getfirst (BUFFER_Q *p_q)
+{
+ return (p_q->p_first);
+}
+
+/*******************************************************************************
+**
+** Function GKI_getlast
+**
+** Description Return a pointer to the last buffer in a queue
+**
+** Parameters: p_q - (input) pointer to a queue.
+**
+** Returns NULL if queue is empty, else buffer address
+**
+*******************************************************************************/
+void *GKI_getlast (BUFFER_Q *p_q)
+{
+ return (p_q->p_last);
+}
+
+/*******************************************************************************
+**
+** Function GKI_getnext
+**
+** Description Return a pointer to the next buffer in a queue
+**
+** Parameters: p_buf - (input) pointer to the buffer to find the next one from.
+**
+** Returns NULL if no more buffers in the queue, else next buffer address
+**
+*******************************************************************************/
+void *GKI_getnext (void *p_buf)
+{
+ BUFFER_HDR_T *p_hdr;
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+ if (p_hdr->p_next)
+ return ((UINT8 *)p_hdr->p_next + BUFFER_HDR_SIZE);
+ else
+ return (NULL);
+}
+
+
+
+/*******************************************************************************
+**
+** Function GKI_queue_is_empty
+**
+** Description Check the status of a queue.
+**
+** Parameters: p_q - (input) pointer to a queue.
+**
+** Returns TRUE if queue is empty, else FALSE
+**
+*******************************************************************************/
+BOOLEAN GKI_queue_is_empty(BUFFER_Q *p_q)
+{
+ return ((BOOLEAN) (p_q->count == 0));
+}
+
+/*******************************************************************************
+**
+** Function GKI_find_buf_start
+**
+** Description This function is called with an address inside a buffer,
+** and returns the start address ofthe buffer.
+**
+** The buffer should be one allocated from one of GKI's pools.
+**
+** Parameters: p_user_area - (input) address of anywhere in a GKI buffer.
+**
+** Returns void * - Address of the beginning of the specified buffer if successful,
+** otherwise NULL if unsuccessful
+**
+*******************************************************************************/
+void *GKI_find_buf_start (void *p_user_area)
+{
+ UINT16 xx, size;
+ UINT32 yy;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+ UINT8 *p_ua = (UINT8 *)p_user_area;
+
+ for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+ {
+ if ((p_ua > p_cb->pool_start[xx]) && (p_ua < p_cb->pool_end[xx]))
+ {
+ yy = (UINT32)(p_ua - p_cb->pool_start[xx]);
+
+ size = p_cb->pool_size[xx];
+
+ yy = (yy / size) * size;
+
+ return ((void *) (p_cb->pool_start[xx] + yy + sizeof(BUFFER_HDR_T)) );
+ }
+ }
+
+ /* If here, invalid address - not in one of our buffers */
+ GKI_exception (GKI_ERROR_BUF_SIZE_ZERO, "GKI_get_buf_start:: bad addr");
+
+ return (NULL);
+}
+
+
+/********************************************************
+* The following functions are not needed for light stack
+*********************************************************/
+#if (!defined(BTU_STACK_LITE_ENABLED) || BTU_STACK_LITE_ENABLED == FALSE)
+
+/*******************************************************************************
+**
+** Function GKI_set_pool_permission
+**
+** Description This function is called to set or change the permissions for
+** the specified pool ID.
+**
+** Parameters pool_id - (input) pool ID to be set or changed
+** permission - (input) GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL
+**
+** Returns GKI_SUCCESS if successful
+** GKI_INVALID_POOL if unsuccessful
+**
+*******************************************************************************/
+UINT8 GKI_set_pool_permission(UINT8 pool_id, UINT8 permission)
+{
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+ {
+ if (permission == GKI_RESTRICTED_POOL)
+ p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask | (1 << pool_id));
+
+ else /* mark the pool as public */
+ p_cb->pool_access_mask = (UINT16)(p_cb->pool_access_mask & ~(1 << pool_id));
+
+ return (GKI_SUCCESS);
+ }
+ else
+ return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function gki_add_to_pool_list
+**
+** Description Adds pool to the pool list which is arranged in the
+** order of size
+**
+** Returns void
+**
+*******************************************************************************/
+static void gki_add_to_pool_list(UINT8 pool_id)
+{
+
+ INT32 i, j;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* Find the position where the specified pool should be inserted into the list */
+ for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+ {
+
+ if(p_cb->freeq[pool_id].size <= p_cb->freeq[ p_cb->pool_list[i] ].size)
+ break;
+ }
+
+ /* Insert the new buffer pool ID into the list of pools */
+ for(j = p_cb->curr_total_no_of_pools; j > i; j--)
+ {
+ p_cb->pool_list[j] = p_cb->pool_list[j-1];
+ }
+
+ p_cb->pool_list[i] = pool_id;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function gki_remove_from_pool_list
+**
+** Description Removes pool from the pool list. Called when a pool is deleted
+**
+** Returns void
+**
+*******************************************************************************/
+static void gki_remove_from_pool_list(UINT8 pool_id)
+{
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+ UINT8 i;
+
+ for(i=0; i < p_cb->curr_total_no_of_pools; i++)
+ {
+ if(pool_id == p_cb->pool_list[i])
+ break;
+ }
+
+ while (i < (p_cb->curr_total_no_of_pools - 1))
+ {
+ p_cb->pool_list[i] = p_cb->pool_list[i+1];
+ i++;
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function GKI_igetpoolbuf
+**
+** Description Called by an interrupt service routine to get a free buffer from
+** a specific buffer pool.
+**
+** Parameters pool_id - (input) pool ID to get a buffer out of.
+**
+** Returns A pointer to the buffer, or NULL if none available
+**
+*******************************************************************************/
+void *GKI_igetpoolbuf (UINT8 pool_id)
+{
+ FREE_QUEUE_T *Q;
+ BUFFER_HDR_T *p_hdr;
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ return (NULL);
+
+
+ Q = &gki_cb.com.freeq[pool_id];
+ if(Q->cur_cnt < Q->total)
+ {
+ p_hdr = Q->p_first;
+ Q->p_first = p_hdr->p_next;
+
+ if (!Q->p_first)
+ Q->p_last = NULL;
+
+ if(++Q->cur_cnt > Q->max_cnt)
+ Q->max_cnt = Q->cur_cnt;
+
+ p_hdr->task_id = GKI_get_taskid();
+
+ p_hdr->status = BUF_STATUS_UNLINKED;
+ p_hdr->p_next = NULL;
+ p_hdr->Type = 0;
+
+ return ((void *) ((UINT8 *)p_hdr + BUFFER_HDR_SIZE));
+ }
+
+ return (NULL);
+}
+
+/*******************************************************************************
+**
+** Function GKI_poolcount
+**
+** Description Called by an application to get the total number of buffers
+** in the specified buffer pool.
+**
+** Parameters pool_id - (input) pool ID to get the free count of.
+**
+** Returns the total number of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolcount (UINT8 pool_id)
+{
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ return (0);
+
+ return (gki_cb.com.freeq[pool_id].total);
+}
+
+/*******************************************************************************
+**
+** Function GKI_poolfreecount
+**
+** Description Called by an application to get the number of free buffers
+** in the specified buffer pool.
+**
+** Parameters pool_id - (input) pool ID to get the free count of.
+**
+** Returns the number of free buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_poolfreecount (UINT8 pool_id)
+{
+ FREE_QUEUE_T *Q;
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ return (0);
+
+ Q = &gki_cb.com.freeq[pool_id];
+
+ return ((UINT16)(Q->total - Q->cur_cnt));
+}
+
+/*******************************************************************************
+**
+** Function GKI_change_buf_owner
+**
+** Description Called to change the task ownership of a buffer.
+**
+** Parameters: p_buf - (input) pointer to the buffer
+** task_id - (input) task id to change ownership to
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_change_buf_owner (void *p_buf, UINT8 task_id)
+{
+ BUFFER_HDR_T *p_hdr = (BUFFER_HDR_T *) ((UINT8 *) p_buf - BUFFER_HDR_SIZE);
+
+ p_hdr->task_id = task_id;
+
+ return;
+}
+
+#if (defined(GKI_SEND_MSG_FROM_ISR) && GKI_SEND_MSG_FROM_ISR == TRUE)
+/*******************************************************************************
+**
+** Function GKI_isend_msg
+**
+** Description Called from interrupt context to send a buffer to a task
+**
+** Returns Nothing
+**
+*******************************************************************************/
+void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg)
+{
+ BUFFER_HDR_T *p_hdr;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* If task non-existant or not started, drop buffer */
+ if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD))
+ {
+ GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest");
+ GKI_freebuf (msg);
+ return;
+ }
+
+#if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE)
+ if (gki_chk_buf_damage(msg))
+ {
+ GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted");
+ return;
+ }
+#endif
+
+#if (GKI_ENABLE_OWNER_CHECK == TRUE)
+ if (gki_chk_buf_owner(msg))
+ {
+ GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner");
+ return;
+ }
+#endif
+
+ p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE);
+
+ if (p_hdr->status != BUF_STATUS_UNLINKED)
+ {
+ GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked");
+ return;
+ }
+
+ if (p_cb->OSTaskQFirst[task_id][mbox])
+ p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr;
+ else
+ p_cb->OSTaskQFirst[task_id][mbox] = p_hdr;
+
+ p_cb->OSTaskQLast[task_id][mbox] = p_hdr;
+
+ p_hdr->p_next = NULL;
+ p_hdr->status = BUF_STATUS_QUEUED;
+ p_hdr->task_id = task_id;
+
+ GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox));
+
+ return;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function GKI_create_pool
+**
+** Description Called by applications to create a buffer pool.
+**
+** Parameters: size - (input) length (in bytes) of each buffer in the pool
+** count - (input) number of buffers to allocate for the pool
+** permission - (input) restricted or public access?
+** (GKI_PUBLIC_POOL or GKI_RESTRICTED_POOL)
+** p_mem_pool - (input) pointer to an OS memory pool, NULL if not provided
+**
+** Returns the buffer pool ID, which should be used in calls to
+** GKI_getpoolbuf(). If a pool could not be created, this
+** function returns 0xff.
+**
+*******************************************************************************/
+UINT8 GKI_create_pool (UINT16 size, UINT16 count, UINT8 permission, void *p_mem_pool)
+{
+ UINT8 xx;
+ UINT32 mem_needed;
+ INT32 tempsize = size;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ /* First make sure the size of each pool has a valid size with room for the header info */
+ if (size > MAX_USER_BUF_SIZE)
+ return (GKI_INVALID_POOL);
+
+ /* First, look for an unused pool */
+ for (xx = 0; xx < GKI_NUM_TOTAL_BUF_POOLS; xx++)
+ {
+ if (!p_cb->pool_start[xx])
+ break;
+ }
+
+ if (xx == GKI_NUM_TOTAL_BUF_POOLS)
+ return (GKI_INVALID_POOL);
+
+ /* Ensure an even number of longwords */
+ tempsize = (INT32)ALIGN_POOL(size);
+
+ mem_needed = (tempsize + BUFFER_PADDING_SIZE) * count;
+
+ if (!p_mem_pool)
+ p_mem_pool = GKI_os_malloc(mem_needed);
+
+ if (p_mem_pool)
+ {
+ /* Initialize the new pool */
+ gki_init_free_queue (xx, size, count, p_mem_pool);
+ gki_add_to_pool_list(xx);
+ (void) GKI_set_pool_permission (xx, permission);
+ p_cb->curr_total_no_of_pools++;
+
+ return (xx);
+ }
+ else
+ return (GKI_INVALID_POOL);
+}
+
+/*******************************************************************************
+**
+** Function GKI_delete_pool
+**
+** Description Called by applications to delete a buffer pool. The function
+** calls the operating specific function to free the actual memory.
+** An exception is generated if an error is detected.
+**
+** Parameters: pool_id - (input) Id of the poll being deleted.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_delete_pool (UINT8 pool_id)
+{
+ FREE_QUEUE_T *Q;
+ tGKI_COM_CB *p_cb = &gki_cb.com;
+
+ if ((pool_id >= GKI_NUM_TOTAL_BUF_POOLS) || (!p_cb->pool_start[pool_id]))
+ return;
+
+ GKI_disable();
+ Q = &p_cb->freeq[pool_id];
+
+ if (!Q->cur_cnt)
+ {
+ Q->size = 0;
+ Q->total = 0;
+ Q->cur_cnt = 0;
+ Q->max_cnt = 0;
+ Q->p_first = NULL;
+ Q->p_last = NULL;
+
+ GKI_os_free (p_cb->pool_start[pool_id]);
+
+ p_cb->pool_start[pool_id] = NULL;
+ p_cb->pool_end[pool_id] = NULL;
+ p_cb->pool_size[pool_id] = 0;
+
+ gki_remove_from_pool_list(pool_id);
+ p_cb->curr_total_no_of_pools--;
+ }
+ else
+ GKI_exception(GKI_ERROR_DELETE_POOL_BAD_QID, "Deleting bad pool");
+
+ GKI_enable();
+
+ return;
+}
+
+#endif /* BTU_STACK_LITE_ENABLED == FALSE */
+
+/*******************************************************************************
+**
+** Function GKI_get_pool_bufsize
+**
+** Description Called by an application to get the size of buffers in a pool
+**
+** Parameters Pool ID.
+**
+** Returns the size of buffers in the pool
+**
+*******************************************************************************/
+UINT16 GKI_get_pool_bufsize (UINT8 pool_id)
+{
+ if (pool_id < GKI_NUM_TOTAL_BUF_POOLS)
+ return (gki_cb.com.freeq[pool_id].size);
+
+ return (0);
+}
+
+/*******************************************************************************
+**
+** Function GKI_poolutilization
+**
+** Description Called by an application to get the buffer utilization
+** in the specified buffer pool.
+**
+** Parameters pool_id - (input) pool ID to get the free count of.
+**
+** Returns % of buffers used from 0 to 100
+**
+*******************************************************************************/
+UINT16 GKI_poolutilization (UINT8 pool_id)
+{
+ FREE_QUEUE_T *Q;
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS)
+ return (100);
+
+ Q = &gki_cb.com.freeq[pool_id];
+
+ if (Q->total == 0)
+ return (100);
+
+ return ((Q->cur_cnt * 100) / Q->total);
+}
+
diff --git a/halimpl/bcm2079x/gki/common/gki_common.h b/halimpl/bcm2079x/gki/common/gki_common.h
new file mode 100644
index 0000000..2bd9f8f
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_common.h
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_COMMON_H
+#define GKI_COMMON_H
+
+#include "gki.h"
+#include "dyn_mem.h"
+
+#ifndef GKI_DEBUG
+#define GKI_DEBUG FALSE
+#endif
+
+/* Task States: (For OSRdyTbl) */
+#define TASK_DEAD 0 /* b0000 */
+#define TASK_READY 1 /* b0001 */
+#define TASK_WAIT 2 /* b0010 */
+#define TASK_DELAY 4 /* b0100 */
+#define TASK_SUSPEND 8 /* b1000 */
+
+
+/********************************************************************
+** Internal Error codes
+*********************************************************************/
+#define GKI_ERROR_BUF_CORRUPTED 0xFFFF
+#define GKI_ERROR_NOT_BUF_OWNER 0xFFFE
+#define GKI_ERROR_FREEBUF_BAD_QID 0xFFFD
+#define GKI_ERROR_FREEBUF_BUF_LINKED 0xFFFC
+#define GKI_ERROR_SEND_MSG_BAD_DEST 0xFFFB
+#define GKI_ERROR_SEND_MSG_BUF_LINKED 0xFFFA
+#define GKI_ERROR_ENQUEUE_BUF_LINKED 0xFFF9
+#define GKI_ERROR_DELETE_POOL_BAD_QID 0xFFF8
+#define GKI_ERROR_BUF_SIZE_TOOBIG 0xFFF7
+#define GKI_ERROR_BUF_SIZE_ZERO 0xFFF6
+#define GKI_ERROR_ADDR_NOT_IN_BUF 0xFFF5
+
+
+/********************************************************************
+** Misc constants
+*********************************************************************/
+
+#define GKI_MAX_INT32 (0x7fffffffL)
+#define GKI_MAX_TIMESTAMP (0xffffffffL)
+
+/********************************************************************
+** Buffer Management Data Structures
+*********************************************************************/
+
+typedef struct _buffer_hdr
+{
+ struct _buffer_hdr *p_next; /* next buffer in the queue */
+ UINT8 q_id; /* id of the queue */
+ UINT8 task_id; /* task which allocated the buffer*/
+ UINT8 status; /* FREE, UNLINKED or QUEUED */
+ UINT8 Type;
+
+#if GKI_BUFFER_DEBUG
+ /* for tracking who allocated the buffer */
+ #define _GKI_MAX_FUNCTION_NAME_LEN (50)
+ char _function[_GKI_MAX_FUNCTION_NAME_LEN+1];
+ int _line;
+#endif
+
+} BUFFER_HDR_T;
+
+typedef struct _free_queue
+{
+ BUFFER_HDR_T *p_first; /* first buffer in the queue */
+ BUFFER_HDR_T *p_last; /* last buffer in the queue */
+ UINT16 size; /* size of the buffers in the pool */
+ UINT16 total; /* toatal number of buffers */
+ UINT16 cur_cnt; /* number of buffers currently allocated */
+ UINT16 max_cnt; /* maximum number of buffers allocated at any time */
+} FREE_QUEUE_T;
+
+
+/* Buffer related defines
+*/
+#define ALIGN_POOL(pl_size) ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
+#define BUFFER_HDR_SIZE (sizeof(BUFFER_HDR_T)) /* Offset past header */
+#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
+#define MAX_USER_BUF_SIZE ((UINT16)0xffff - BUFFER_PADDING_SIZE) /* pool size must allow for header */
+#define MAGIC_NO 0xDDBADDBA
+
+#define BUF_STATUS_FREE 0
+#define BUF_STATUS_UNLINKED 1
+#define BUF_STATUS_QUEUED 2
+
+#define GKI_USE_DEFERED_ALLOC_BUF_POOLS
+
+/* Exception related structures (Used in debug mode only)
+*/
+#if (GKI_DEBUG == TRUE)
+typedef struct
+{
+ UINT16 type;
+ UINT8 taskid;
+ UINT8 msg[GKI_MAX_EXCEPTION_MSGLEN];
+} EXCEPTION_T;
+#endif
+
+
+/* Put all GKI variables into one control block
+*/
+typedef struct
+{
+ /* Task management variables
+ */
+ /* The stack and stack size are not used on Windows
+ */
+#if (!defined GKI_USE_DEFERED_ALLOC_BUF_POOLS && (GKI_USE_DYNAMIC_BUFFERS == FALSE))
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ UINT8 bufpool0[(ALIGN_POOL(GKI_BUF0_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF0_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ UINT8 bufpool1[(ALIGN_POOL(GKI_BUF1_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF1_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ UINT8 bufpool2[(ALIGN_POOL(GKI_BUF2_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF2_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ UINT8 bufpool3[(ALIGN_POOL(GKI_BUF3_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF3_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ UINT8 bufpool4[(ALIGN_POOL(GKI_BUF4_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF4_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ UINT8 bufpool5[(ALIGN_POOL(GKI_BUF5_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF5_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ UINT8 bufpool6[(ALIGN_POOL(GKI_BUF6_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF6_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ UINT8 bufpool7[(ALIGN_POOL(GKI_BUF7_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF7_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ UINT8 bufpool8[(ALIGN_POOL(GKI_BUF8_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF8_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ UINT8 bufpool9[(ALIGN_POOL(GKI_BUF9_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF9_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ UINT8 bufpool10[(ALIGN_POOL(GKI_BUF10_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF10_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ UINT8 bufpool11[(ALIGN_POOL(GKI_BUF11_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF11_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ UINT8 bufpool12[(ALIGN_POOL(GKI_BUF12_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF12_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ UINT8 bufpool13[(ALIGN_POOL(GKI_BUF13_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF13_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ UINT8 bufpool14[(ALIGN_POOL(GKI_BUF14_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF14_MAX];
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ UINT8 bufpool15[(ALIGN_POOL(GKI_BUF15_SIZE) + BUFFER_PADDING_SIZE) * GKI_BUF15_MAX];
+#endif
+
+#else
+/* Definitions for dynamic buffer use */
+#if (GKI_NUM_FIXED_BUF_POOLS > 0)
+ UINT8 *bufpool0;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 1)
+ UINT8 *bufpool1;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 2)
+ UINT8 *bufpool2;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 3)
+ UINT8 *bufpool3;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 4)
+ UINT8 *bufpool4;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 5)
+ UINT8 *bufpool5;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 6)
+ UINT8 *bufpool6;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 7)
+ UINT8 *bufpool7;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 8)
+ UINT8 *bufpool8;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 9)
+ UINT8 *bufpool9;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 10)
+ UINT8 *bufpool10;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 11)
+ UINT8 *bufpool11;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 12)
+ UINT8 *bufpool12;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 13)
+ UINT8 *bufpool13;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 14)
+ UINT8 *bufpool14;
+#endif
+
+#if (GKI_NUM_FIXED_BUF_POOLS > 15)
+ UINT8 *bufpool15;
+#endif
+
+#endif
+
+ UINT8 *OSStack[GKI_MAX_TASKS]; /* pointer to beginning of stack */
+ UINT16 OSStackSize[GKI_MAX_TASKS]; /* stack size available to each task */
+
+
+ INT8 *OSTName[GKI_MAX_TASKS]; /* name of the task */
+
+ UINT8 OSRdyTbl[GKI_MAX_TASKS]; /* current state of the task */
+ UINT16 OSWaitEvt[GKI_MAX_TASKS]; /* events that have to be processed by the task */
+ UINT16 OSWaitForEvt[GKI_MAX_TASKS]; /* events the task is waiting for*/
+
+ UINT32 OSTicks; /* system ticks from start */
+ UINT32 OSIdleCnt; /* idle counter */
+ INT16 OSDisableNesting; /* counter to keep track of interrupt disable nesting */
+ INT16 OSLockNesting; /* counter to keep track of sched lock nesting */
+ INT16 OSIntNesting; /* counter to keep track of interrupt nesting */
+
+ /* Timer related variables
+ */
+ INT32 OSTicksTilExp; /* Number of ticks till next timer expires */
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ UINT32 OSTicksTilStop; /* inactivity delay timer; OS Ticks till stopping system tick */
+#endif
+ INT32 OSNumOrigTicks; /* Number of ticks between last timer expiration to the next one */
+
+ INT32 OSWaitTmr [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */
+
+ /* Only take up space timers used in the system (GKI_NUM_TIMERS defined in target.h) */
+#if (GKI_NUM_TIMERS > 0)
+ INT32 OSTaskTmr0 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr0R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ INT32 OSTaskTmr1 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr1R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ INT32 OSTaskTmr2 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr2R [GKI_MAX_TASKS];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ INT32 OSTaskTmr3 [GKI_MAX_TASKS];
+ INT32 OSTaskTmr3R [GKI_MAX_TASKS];
+#endif
+
+
+
+ /* Buffer related variables
+ */
+ BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
+ BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
+
+ /* Define the buffer pool management variables
+ */
+ FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];
+
+ UINT16 pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
+ UINT16 pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
+ UINT16 pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
+
+ /* Define the buffer pool start addresses
+ */
+ UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the start of each buffer pool */
+ UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the end of each buffer pool */
+ UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS]; /* actual size of the buffers in a pool */
+
+ /* Define the buffer pool access control variables */
+ void *p_user_mempool; /* User O/S memory pool */
+ UINT16 pool_access_mask; /* Bits are set if the corresponding buffer pool is a restricted pool */
+ UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
+ UINT8 curr_total_no_of_pools; /* number of fixed buf pools + current number of dynamic pools */
+
+ BOOLEAN timer_nesting; /* flag to prevent timer interrupt nesting */
+
+ /* Time queue arrays */
+ TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
+ /* System tick callback */
+ SYSTEM_TICK_CBACK *p_tick_cb;
+ BOOLEAN system_tick_running; /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
+
+#if (GKI_DEBUG == TRUE)
+ UINT16 ExceptionCnt; /* number of GKI exceptions that have happened */
+ EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
+#endif
+
+} tGKI_COM_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Internal GKI function prototypes
+*/
+GKI_API extern BOOLEAN gki_chk_buf_damage(void *);
+extern BOOLEAN gki_chk_buf_owner(void *);
+extern void gki_buffer_init (void);
+extern void gki_timers_init(void);
+extern void gki_adjust_timer_count (INT32);
+
+extern void OSStartRdy(void);
+extern void OSCtxSw(void);
+extern void OSIntCtxSw(void);
+extern void OSSched(void);
+extern void OSIntEnter(void);
+extern void OSIntExit(void);
+
+
+/* Debug aids
+*/
+typedef void (*FP_PRINT)(char *, ...);
+
+#if (GKI_DEBUG == TRUE)
+
+typedef void (*PKT_PRINT)(UINT8 *, UINT16);
+
+extern void gki_print_task(FP_PRINT);
+extern void gki_print_exception(FP_PRINT);
+extern void gki_print_timer(FP_PRINT);
+extern void gki_print_stack(FP_PRINT);
+extern void gki_print_buffer(FP_PRINT);
+extern void gki_print_buffer_statistics(FP_PRINT, INT16);
+GKI_API extern void gki_print_used_bufs (FP_PRINT, UINT8);
+extern void gki_dump(UINT8 *, UINT16, FP_PRINT);
+extern void gki_dump2(UINT16 *, UINT16, FP_PRINT);
+extern void gki_dump4(UINT32 *, UINT16, FP_PRINT);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_debug.c b/halimpl/bcm2079x/gki/common/gki_debug.c
new file mode 100644
index 0000000..481ba16
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_debug.c
@@ -0,0 +1,353 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#if (GKI_DEBUG == TRUE)
+
+const INT8 * const OSTaskStates[] =
+{
+ (INT8 *)"DEAD", /* 0 */
+ (INT8 *)"REDY", /* 1 */
+ (INT8 *)"WAIT", /* 2 */
+ (INT8 *)"",
+ (INT8 *)"DELY", /* 4 */
+ (INT8 *)"",
+ (INT8 *)"",
+ (INT8 *)"",
+ (INT8 *)"SUSP", /* 8 */
+};
+
+
+/*******************************************************************************
+**
+** Function GKI_PrintBufferUsage
+**
+** Description Displays Current Buffer Pool summary
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_PrintBufferUsage(UINT8 *p_num_pools, UINT16 *p_cur_used)
+{
+ int i;
+ FREE_QUEUE_T *p;
+ UINT8 num = gki_cb.com.curr_total_no_of_pools;
+ UINT16 cur[GKI_NUM_TOTAL_BUF_POOLS];
+
+ GKI_TRACE_0("");
+ GKI_TRACE_0("--- GKI Buffer Pool Summary (R - restricted, P - public) ---");
+
+ GKI_TRACE_0("POOL SIZE USED MAXU TOTAL");
+ GKI_TRACE_0("------------------------------");
+ for (i = 0; i < gki_cb.com.curr_total_no_of_pools; i++)
+ {
+ p = &gki_cb.com.freeq[i];
+ if ((1 << i) & gki_cb.com.pool_access_mask)
+ {
+ GKI_TRACE_5("%02d: (R), %4d, %3d, %3d, %3d",
+ i, p->size, p->cur_cnt, p->max_cnt, p->total);
+ }
+ else
+ {
+ GKI_TRACE_5("%02d: (P), %4d, %3d, %3d, %3d",
+ i, p->size, p->cur_cnt, p->max_cnt, p->total);
+ }
+ cur[i] = p->cur_cnt;
+ }
+ if (p_num_pools)
+ *p_num_pools = num;
+ if (p_cur_used)
+ memcpy(p_cur_used, cur, num*2);
+}
+
+/*******************************************************************************
+**
+** Function GKI_PrintBuffer
+**
+** Description Called internally by OSS to print the buffer pools
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_PrintBuffer(void)
+{
+ UINT16 i;
+ for(i=0; i<GKI_NUM_TOTAL_BUF_POOLS; i++)
+ {
+ GKI_TRACE_5("pool:%4u free %4u cur %3u max %3u total%3u", i, gki_cb.com.freeq[i].size,
+ gki_cb.com.freeq[i].cur_cnt, gki_cb.com.freeq[i].max_cnt, gki_cb.com.freeq[i].total);
+ }
+}
+
+/*******************************************************************************
+**
+** Function gki_calc_stack
+**
+** Description This function tries to calculate the amount of
+** stack used by looking non magic num. Magic num is consider
+** the first byte in the stack.
+**
+** Returns the number of unused byte on the stack. 4 in case of stack overrun
+**
+*******************************************************************************/
+UINT16 gki_calc_stack (UINT8 task)
+{
+ int j, stacksize;
+ UINT32 MagicNum;
+ UINT32 *p;
+
+ stacksize = (int) gki_cb.com.OSStackSize[task];
+ p = (UINT32 *)gki_cb.com.OSStack[task]; /* assume stack is aligned, */
+ MagicNum = *p;
+
+ for(j = 0; j < stacksize; j++)
+ {
+ if(*p++ != MagicNum) break;
+ }
+
+ return (j * sizeof(UINT32));
+}
+
+/*******************************************************************************
+**
+** Function GKI_print_task
+**
+** Description Print task stack usage.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_print_task(void)
+{
+#ifdef _BT_WIN32
+ GKI_TRACE_0("Service not available under insight");
+#else
+ UINT8 TaskId;
+
+ GKI_TRACE_0("TID TASKNAME STATE FREE_STACK STACK");
+ for(TaskId=0; TaskId < GKI_MAX_TASKS; TaskId++)
+ {
+ if (gki_cb.com.OSRdyTbl[TaskId] != TASK_DEAD)
+ {
+ GKI_TRACE_5("%2u %-8s %-5s 0x%04X 0x%04X Bytes",
+ (UINT16)TaskId, gki_cb.com.OSTName[TaskId],
+ OSTaskStates[gki_cb.com.OSRdyTbl[TaskId]],
+ gki_calc_stack(TaskId), gki_cb.com.OSStackSize[TaskId]);
+
+ }
+ }
+#endif
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_buffer_statistics
+**
+** Description Called internally by OSS to print the buffer pools statistics
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_buffer_statistics(FP_PRINT print, INT16 pool)
+{
+ UINT16 i;
+ BUFFER_HDR_T *hdr;
+ UINT16 size,act_size,maxbuffs;
+ UINT32 *magic;
+
+ if (pool > GKI_NUM_TOTAL_BUF_POOLS || pool < 0)
+ {
+ print("Not a valid Buffer pool\n");
+ return;
+ }
+
+ size = gki_cb.com.freeq[pool].size;
+ maxbuffs = gki_cb.com.freeq[pool].total;
+ act_size = size + BUFFER_PADDING_SIZE;
+ print("Buffer Pool[%u] size=%u cur_cnt=%u max_cnt=%u total=%u\n",
+ pool, gki_cb.com.freeq[pool].size,
+ gki_cb.com.freeq[pool].cur_cnt, gki_cb.com.freeq[pool].max_cnt, gki_cb.com.freeq[pool].total);
+
+ print(" Owner State Sanity\n");
+ print("----------------------------\n");
+ hdr = (BUFFER_HDR_T *)(gki_cb.com.pool_start[pool]);
+ for(i=0; i<maxbuffs; i++)
+ {
+ magic = (UINT32 *)((UINT8 *)hdr + BUFFER_HDR_SIZE + size);
+ print("%3d: 0x%02x %4d %10s\n", i, hdr->task_id, hdr->status, (*magic == MAGIC_NO)?"OK":"CORRUPTED");
+ hdr = (BUFFER_HDR_T *)((UINT8 *)hdr + act_size);
+ }
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_used_bufs
+**
+** Description Dumps used buffers in the particular pool
+**
+*******************************************************************************/
+GKI_API void gki_print_used_bufs (FP_PRINT print, UINT8 pool_id)
+{
+ UINT8 *p_start;
+ UINT16 buf_size;
+ UINT16 num_bufs;
+ BUFFER_HDR_T *p_hdr;
+ UINT16 i;
+ UINT32 *magic;
+ UINT16 *p;
+
+
+ if (pool_id >= GKI_NUM_TOTAL_BUF_POOLS && gki_cb.com.pool_start[pool_id] != 0)
+ {
+ print("Not a valid Buffer pool\n");
+ return;
+ }
+
+ p_start = gki_cb.com.pool_start[pool_id];
+ buf_size = gki_cb.com.freeq[pool_id].size + BUFFER_PADDING_SIZE;
+ num_bufs = gki_cb.com.freeq[pool_id].total;
+
+ for (i = 0; i < num_bufs; i++, p_start += buf_size)
+ {
+ p_hdr = (BUFFER_HDR_T *)p_start;
+ magic = (UINT32 *)((UINT8 *)p_hdr + buf_size - sizeof(UINT32));
+ p = (UINT16 *) p_hdr;
+
+ if (p_hdr->status != BUF_STATUS_FREE)
+ {
+ print ("%d:0x%x (Q:%d,Task:%s,Stat:%d,%s) %04x %04x %04x %04x %04x %04x %04x %04x\n",
+ i, p_hdr,
+ p_hdr->q_id,
+ GKI_map_taskname(p_hdr->task_id),
+ p_hdr->status,
+ (*magic == MAGIC_NO)? "OK" : "CORRUPTED",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_task
+**
+** Description This function prints the task states.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_task (FP_PRINT print)
+{
+ UINT8 i;
+
+ print("TID VID TASKNAME STATE WAIT WAITFOR TIMEOUT STACK\n");
+ print("-------------------------------------------------\n");
+ for(i=0; i<GKI_MAX_TASKS; i++)
+ {
+ if (gki_cb.com.OSRdyTbl[i] != TASK_DEAD)
+ {
+ print("%2u %-8s %-5s %04X %04X %7u %u/%u Bytes\n",
+ (UINT16)i, gki_cb.com.OSTName[i],
+ OSTaskStates[gki_cb.com.OSRdyTbl[i]],
+ gki_cb.com.OSWaitEvt[i], gki_cb.com.OSWaitForEvt[i],
+ gki_cb.com.OSWaitTmr[i], gki_calc_stack(i), gki_cb.com.OSStackSize[i]);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function gki_print_exception
+**
+** Description This function prints the exception information.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_print_exception(FP_PRINT print)
+{
+ UINT16 i;
+ EXCEPTION_T *pExp;
+
+ print ("GKI Exceptions:\n");
+ for (i = 0; i < gki_cb.com.ExceptionCnt; i++)
+ {
+ pExp = &gki_cb.com.Exception[i];
+ print("%d: Type=%d, Task=%d: %s\n", i,
+ (INT32)pExp->type, (INT32)pExp->taskid, (INT8 *)pExp->msg);
+ }
+}
+
+
+/*****************************************************************************/
+void gki_dump (UINT8 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %02X, ", &s[i], s[i]);
+ else if(j == 7)
+ print("%02X, ", s[i]);
+ else
+ print("%02X, ", s[i]);
+ if(++j == 16)
+ j=0;
+ }
+ print("\n");
+}
+
+void gki_dump2 (UINT16 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %04X, ", &s[i], s[i]);
+ else
+ print("%04X, ", s[i]);
+ if(++j == 8)
+ j=0;
+ }
+ print("\n");
+}
+
+void gki_dump4 (UINT32 *s, UINT16 len, FP_PRINT print)
+{
+ UINT16 i, j;
+
+ for(i=0, j=0; i<len; i++)
+ {
+ if(j == 0)
+ print("\n%lX: %08lX, ", &s[i], s[i]);
+ else
+ print("%08lX, ", s[i]);
+ if(++j == 4)
+ j=0;
+ }
+ print("\n");
+}
+
+
+#endif
diff --git a/halimpl/bcm2079x/gki/common/gki_inet.h b/halimpl/bcm2079x/gki/common/gki_inet.h
new file mode 100644
index 0000000..569c4fd
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_inet.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INET_H
+#define GKI_INET_H
+
+#include "data_types.h"
+
+#define htons ntohs
+#define htonl ntohl
+
+#define htonets nettohs
+#define htonetl nettohl
+
+#if BIG_ENDIAN == TRUE
+#define ntohs(n) (n)
+#define ntohl(n) (n)
+#define ntoh6(n) (n)
+
+#define nettohs(n) (n)
+#define nettohl(n) (n)
+#else
+extern UINT16 ntohs(UINT16 n);
+extern UINT32 ntohl(UINT32 n);
+extern UINT8 *ntoh6(UINT8 *p);
+
+#define nettohs(n) ((UINT16)((((n) << 8) & 0xff00) | (((n) >> 8) & 0x00ff)))
+#define nettohl(n) ((((n) & 0x000000ff) << 24) | (((n) << 8) & 0x00ff0000) | \
+ (((n) >> 8) & 0x0000ff00) | (((n) >> 24) & 0x000000ff))
+#endif
+
+#endif /* GKI_INET_H */
+
diff --git a/halimpl/bcm2079x/gki/common/gki_time.c b/halimpl/bcm2079x/gki/common/gki_time.c
new file mode 100644
index 0000000..e840a36
--- /dev/null
+++ b/halimpl/bcm2079x/gki/common/gki_time.c
@@ -0,0 +1,1017 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include "gki_int.h"
+
+#ifndef BT_ERROR_TRACE_0
+#define BT_ERROR_TRACE_0(l,m)
+#endif
+
+/* Make sure that this has been defined in target.h */
+#ifndef GKI_NUM_TIMERS
+#error NO TIMERS: Must define at least 1 timer in the system!
+#endif
+
+
+#define GKI_NO_NEW_TMRS_STARTED (0x7fffffffL) /* Largest signed positive timer count */
+#define GKI_UNUSED_LIST_ENTRY (0x80000000L) /* Marks an unused timer list entry (initial value) */
+#define GKI_MAX_INT32 (0x7fffffffL)
+
+/*******************************************************************************
+**
+** Function gki_timers_init
+**
+** Description This internal function is called once at startup to initialize
+** all the timer structures.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_timers_init(void)
+{
+ UINT8 tt;
+
+ gki_cb.com.OSTicksTilExp = 0; /* Remaining time (of OSTimeCurTimeout) before next timer expires */
+ gki_cb.com.OSNumOrigTicks = 0;
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
+#endif
+
+ for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+ {
+ gki_cb.com.OSWaitTmr [tt] = 0;
+
+#if (GKI_NUM_TIMERS > 0)
+ gki_cb.com.OSTaskTmr0 [tt] = 0;
+ gki_cb.com.OSTaskTmr0R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ gki_cb.com.OSTaskTmr1 [tt] = 0;
+ gki_cb.com.OSTaskTmr1R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ gki_cb.com.OSTaskTmr2 [tt] = 0;
+ gki_cb.com.OSTaskTmr2R [tt] = 0;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ gki_cb.com.OSTaskTmr3 [tt] = 0;
+ gki_cb.com.OSTaskTmr3R [tt] = 0;
+#endif
+ }
+
+ for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+ {
+ gki_cb.com.timer_queues[tt] = NULL;
+ }
+
+ gki_cb.com.p_tick_cb = NULL;
+ gki_cb.com.system_tick_running = FALSE;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function gki_timers_is_timer_running
+**
+** Description This internal function is called to test if any gki timer are running
+**
+**
+** Returns TRUE if at least one time is running in the system, FALSE else.
+**
+*******************************************************************************/
+BOOLEAN gki_timers_is_timer_running(void)
+{
+ UINT8 tt;
+ for (tt = 0; tt < GKI_MAX_TASKS; tt++)
+ {
+
+#if (GKI_NUM_TIMERS > 0)
+ if(gki_cb.com.OSTaskTmr0 [tt])
+ {
+ return TRUE;
+ }
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ if(gki_cb.com.OSTaskTmr1 [tt] )
+ {
+ return TRUE;
+ }
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ if(gki_cb.com.OSTaskTmr2 [tt] )
+ {
+ return TRUE;
+ }
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ if(gki_cb.com.OSTaskTmr3 [tt] )
+ {
+ return TRUE;
+ }
+#endif
+ }
+
+ return FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function GKI_get_tick_count
+**
+** Description This function returns the current system ticks
+**
+** Returns The current number of system ticks
+**
+*******************************************************************************/
+UINT32 GKI_get_tick_count(void)
+{
+ return gki_cb.com.OSTicks;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_ready_to_sleep
+**
+** Description This function returns the number of system ticks until the
+** next timer will expire. It is typically called by a power
+** savings manager to find out how long it can have the system
+** sleep before it needs to service the next entry.
+**
+** Parameters: None
+**
+** Returns Number of ticks til the next timer expires
+** Note: the value is a signed value. This value should be
+** compared to x > 0, to avoid misinterpreting negative tick
+** values.
+**
+*******************************************************************************/
+INT32 GKI_ready_to_sleep (void)
+{
+ return (gki_cb.com.OSTicksTilExp);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_start_timer
+**
+** Description An application can call this function to start one of
+** it's four general purpose timers. Any of the four timers
+** can be 1-shot or continuous. If a timer is already running,
+** it will be reset to the new parameters.
+**
+** Parameters tnum - (input) timer number to be started (TIMER_0,
+** TIMER_1, TIMER_2, or TIMER_3)
+** ticks - (input) the number of system ticks til the
+** timer expires.
+** is_continuous - (input) TRUE if timer restarts automatically,
+** else FALSE if it is a 'one-shot'.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_start_timer (UINT8 tnum, INT32 ticks, BOOLEAN is_continuous)
+{
+ INT32 reload;
+ INT32 orig_ticks;
+ UINT8 task_id = GKI_get_taskid();
+ BOOLEAN bad_timer = FALSE;
+
+ if (ticks <= 0)
+ ticks = 1;
+
+ orig_ticks = ticks; /* save the ticks in case adjustment is necessary */
+
+
+ /* If continuous timer, set reload, else set it to 0 */
+ if (is_continuous)
+ reload = ticks;
+ else
+ reload = 0;
+
+ GKI_disable();
+
+ if(gki_timers_is_timer_running() == FALSE)
+ {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ /* if inactivity delay timer is not running, start system tick */
+ if(gki_cb.com.OSTicksTilStop == 0)
+ {
+#endif
+ if(gki_cb.com.p_tick_cb)
+ {
+ /* start system tick */
+ gki_cb.com.system_tick_running = TRUE;
+ (gki_cb.com.p_tick_cb) (TRUE);
+ }
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ }
+ else
+ {
+ /* clear inactivity delay timer */
+ gki_cb.com.OSTicksTilStop = 0;
+ }
+#endif
+ }
+ /* Add the time since the last task timer update.
+ ** Note that this works when no timers are active since
+ ** both OSNumOrigTicks and OSTicksTilExp are 0.
+ */
+ if (GKI_MAX_INT32 - (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) > ticks)
+ {
+ ticks += gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp;
+ }
+ else
+ ticks = GKI_MAX_INT32;
+
+ switch (tnum)
+ {
+#if (GKI_NUM_TIMERS > 0)
+ case TIMER_0:
+ gki_cb.com.OSTaskTmr0R[task_id] = reload;
+ gki_cb.com.OSTaskTmr0 [task_id] = ticks;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ case TIMER_1:
+ gki_cb.com.OSTaskTmr1R[task_id] = reload;
+ gki_cb.com.OSTaskTmr1 [task_id] = ticks;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ case TIMER_2:
+ gki_cb.com.OSTaskTmr2R[task_id] = reload;
+ gki_cb.com.OSTaskTmr2 [task_id] = ticks;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ case TIMER_3:
+ gki_cb.com.OSTaskTmr3R[task_id] = reload;
+ gki_cb.com.OSTaskTmr3 [task_id] = ticks;
+ break;
+#endif
+ default:
+ bad_timer = TRUE; /* Timer number is bad, so do not use */
+ }
+
+ /* Update the expiration timeout if a legitimate timer */
+ if (!bad_timer)
+ {
+ /* Only update the timeout value if it is less than any other newly started timers */
+ gki_adjust_timer_count (orig_ticks);
+ }
+
+ GKI_enable();
+
+}
+
+/*******************************************************************************
+**
+** Function GKI_stop_timer
+**
+** Description An application can call this function to stop one of
+** it's four general purpose timers. There is no harm in
+** stopping a timer that is already stopped.
+**
+** Parameters tnum - (input) timer number to be started (TIMER_0,
+** TIMER_1, TIMER_2, or TIMER_3)
+** Returns void
+**
+*******************************************************************************/
+void GKI_stop_timer (UINT8 tnum)
+{
+ UINT8 task_id = GKI_get_taskid();
+
+ GKI_disable();
+
+ switch (tnum)
+ {
+#if (GKI_NUM_TIMERS > 0)
+ case TIMER_0:
+ gki_cb.com.OSTaskTmr0R[task_id] = 0;
+ gki_cb.com.OSTaskTmr0 [task_id] = 0;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ case TIMER_1:
+ gki_cb.com.OSTaskTmr1R[task_id] = 0;
+ gki_cb.com.OSTaskTmr1 [task_id] = 0;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ case TIMER_2:
+ gki_cb.com.OSTaskTmr2R[task_id] = 0;
+ gki_cb.com.OSTaskTmr2 [task_id] = 0;
+ break;
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ case TIMER_3:
+ gki_cb.com.OSTaskTmr3R[task_id] = 0;
+ gki_cb.com.OSTaskTmr3 [task_id] = 0;
+ break;
+#endif
+ }
+
+ if (gki_timers_is_timer_running() == FALSE)
+ {
+ if (gki_cb.com.p_tick_cb)
+ {
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ /* if inactivity delay timer is not running */
+ if ((gki_cb.com.system_tick_running)&&(gki_cb.com.OSTicksTilStop == 0))
+ {
+ /* set inactivity delay timer */
+ /* when timer expires, system tick will be stopped */
+ gki_cb.com.OSTicksTilStop = GKI_DELAY_STOP_SYS_TICK;
+ }
+#else
+ gki_cb.com.system_tick_running = FALSE;
+ gki_cb.com.p_tick_cb(FALSE); /* stop system tick */
+#endif
+ }
+ }
+
+ GKI_enable();
+
+
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_timer_update
+**
+** Description This function is called by an OS to drive the GKI's timers.
+** It is typically called at every system tick to
+** update the timers for all tasks, and check for timeouts.
+**
+** Note: It has been designed to also allow for variable tick updates
+** so that systems with strict power savings requirements can
+** have the update occur at variable intervals.
+**
+** Parameters: ticks_since_last_update - (input) This is the number of TICKS that have
+** occurred since the last time GKI_timer_update was called.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_timer_update (INT32 ticks_since_last_update)
+{
+ UINT8 task_id;
+ long next_expiration; /* Holds the next soonest expiration time after this update */
+
+ /* Increment the number of ticks used for time stamps */
+ gki_cb.com.OSTicks += ticks_since_last_update;
+
+ /* If any timers are running in any tasks, decrement the remaining time til
+ * the timer updates need to take place (next expiration occurs)
+ */
+ gki_cb.com.OSTicksTilExp -= ticks_since_last_update;
+
+ /* Don't allow timer interrupt nesting */
+ if (gki_cb.com.timer_nesting)
+ return;
+
+ gki_cb.com.timer_nesting = 1;
+
+#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
+ /* if inactivity delay timer is set and expired */
+ if (gki_cb.com.OSTicksTilStop)
+ {
+ if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update )
+ {
+ if(gki_cb.com.p_tick_cb)
+ {
+ gki_cb.com.system_tick_running = FALSE;
+ (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */
+ }
+ gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */
+ gki_cb.com.timer_nesting = 0;
+ return;
+ }
+ else
+ gki_cb.com.OSTicksTilStop -= ticks_since_last_update;
+ }
+#endif
+
+ /* No need to update the ticks if no timeout has occurred */
+ if (gki_cb.com.OSTicksTilExp > 0)
+ {
+ gki_cb.com.timer_nesting = 0;
+ return;
+ }
+
+ GKI_disable();
+
+ next_expiration = GKI_NO_NEW_TMRS_STARTED;
+
+ /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks
+ to account for the difference so timer updates below are decremented by the full number
+ of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this
+ value only affects the timer updates below
+ */
+ gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp;
+
+ /* Check for OS Task Timers */
+ for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+ {
+ if (gki_cb.com.OSRdyTbl[task_id] == TASK_DEAD)
+ {
+ // task is shutdown do not try to service timers
+ continue;
+ }
+
+ if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */
+ {
+ gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks;
+ if (gki_cb.com.OSWaitTmr[task_id] <= 0)
+ {
+ /* Timer Expired */
+ gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+ }
+ }
+
+#if (GKI_NUM_TIMERS > 0)
+ /* If any timer is running, decrement */
+ if (gki_cb.com.OSTaskTmr0[task_id] > 0)
+ {
+ gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+ if (gki_cb.com.OSTaskTmr0[task_id] <= 0)
+ {
+ /* Set Timer 0 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+ GKI_isend_event (task_id, TIMER_0_EVT_MASK);
+#else
+ GKI_send_event (task_id, TIMER_0_EVT_MASK);
+#endif
+ gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id];
+ }
+ }
+
+ /* Check to see if this timer is the next one to expire */
+ if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration)
+ next_expiration = gki_cb.com.OSTaskTmr0[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 1)
+ /* If any timer is running, decrement */
+ if (gki_cb.com.OSTaskTmr1[task_id] > 0)
+ {
+ gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+ if (gki_cb.com.OSTaskTmr1[task_id] <= 0)
+ {
+ /* Set Timer 1 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+ GKI_isend_event (task_id, TIMER_1_EVT_MASK);
+#else
+ GKI_send_event (task_id, TIMER_1_EVT_MASK);
+#endif
+ gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id];
+ }
+ }
+
+ /* Check to see if this timer is the next one to expire */
+ if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration)
+ next_expiration = gki_cb.com.OSTaskTmr1[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 2)
+ /* If any timer is running, decrement */
+ if (gki_cb.com.OSTaskTmr2[task_id] > 0)
+ {
+ gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+ if (gki_cb.com.OSTaskTmr2[task_id] <= 0)
+ {
+ /* Set Timer 2 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+ GKI_isend_event (task_id, TIMER_2_EVT_MASK);
+#else
+ GKI_send_event (task_id, TIMER_2_EVT_MASK);
+#endif
+ gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id];
+ }
+ }
+
+ /* Check to see if this timer is the next one to expire */
+ if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration)
+ next_expiration = gki_cb.com.OSTaskTmr2[task_id];
+#endif
+
+#if (GKI_NUM_TIMERS > 3)
+ /* If any timer is running, decrement */
+ if (gki_cb.com.OSTaskTmr3[task_id] > 0)
+ {
+ gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks;
+
+ if (gki_cb.com.OSTaskTmr3[task_id] <= 0)
+ {
+ /* Set Timer 3 Expired event mask and reload timer */
+#if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE)
+ GKI_isend_event (task_id, TIMER_3_EVT_MASK);
+#else
+ GKI_send_event (task_id, TIMER_3_EVT_MASK);
+#endif
+ gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id];
+ }
+ }
+
+ /* Check to see if this timer is the next one to expire */
+ if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration)
+ next_expiration = gki_cb.com.OSTaskTmr3[task_id];
+#endif
+
+ }
+
+ /* Set the next timer experation value if there is one to start */
+ if (next_expiration < GKI_NO_NEW_TMRS_STARTED)
+ {
+ gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration;
+ }
+ else
+ {
+ gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0;
+ }
+
+ gki_cb.com.timer_nesting = 0;
+
+ GKI_enable();
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_timer_queue_empty
+**
+** Description This function is called by applications to see whether the timer
+** queue is empty
+**
+** Parameters
+**
+** Returns BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN GKI_timer_queue_empty (void)
+{
+ UINT8 tt;
+
+ for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+ {
+ if (gki_cb.com.timer_queues[tt])
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function GKI_timer_queue_register_callback
+**
+** Description This function is called by applications to register system tick
+** start/stop callback for time queues
+**
+**
+** Parameters p_callback - (input) pointer to the system tick callback
+**
+** Returns BOOLEAN
+**
+*******************************************************************************/
+void GKI_timer_queue_register_callback (SYSTEM_TICK_CBACK *p_callback)
+{
+ gki_cb.com.p_tick_cb = p_callback;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function GKI_init_timer_list
+**
+** Description This function is called by applications when they
+** want to initialize a timer list.
+**
+** Parameters p_timer_listq - (input) pointer to the timer list queue object
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_init_timer_list (TIMER_LIST_Q *p_timer_listq)
+{
+ p_timer_listq->p_first = NULL;
+ p_timer_listq->p_last = NULL;
+ p_timer_listq->last_ticks = 0;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function GKI_init_timer_list_entry
+**
+** Description This function is called by the applications when they
+** want to initialize a timer list entry. This must be
+** done prior to first use of the entry.
+**
+** Parameters p_tle - (input) pointer to a timer list queue entry
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_init_timer_list_entry (TIMER_LIST_ENT *p_tle)
+{
+ p_tle->p_next = NULL;
+ p_tle->p_prev = NULL;
+ p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+ p_tle->in_use = FALSE;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_update_timer_list
+**
+** Description This function is called by the applications when they
+** want to update a timer list. This should be at every
+** timer list unit tick, e.g. once per sec, once per minute etc.
+**
+** Parameters p_timer_listq - (input) pointer to the timer list queue object
+** num_units_since_last_update - (input) number of units since the last update
+** (allows for variable unit update)
+**
+** NOTE: The following timer list update routines should not be used for exact time
+** critical purposes. The timer tasks should be used when exact timing is needed.
+**
+** Returns the number of timers that have expired
+**
+*******************************************************************************/
+UINT16 GKI_update_timer_list (TIMER_LIST_Q *p_timer_listq, INT32 num_units_since_last_update)
+{
+ TIMER_LIST_ENT *p_tle;
+ UINT16 num_time_out = 0;
+ INT32 rem_ticks;
+ INT32 temp_ticks;
+
+ p_tle = p_timer_listq->p_first;
+
+ /* First, get the guys who have previously timed out */
+ /* Note that the tick value of the timers should always be '0' */
+ while ((p_tle) && (p_tle->ticks <= 0))
+ {
+ num_time_out++;
+ p_tle = p_tle->p_next;
+ }
+
+ /* Timer entriy tick values are relative to the preceeding entry */
+ rem_ticks = num_units_since_last_update;
+
+ /* Now, adjust remaining timer entries */
+ while ((p_tle != NULL) && (rem_ticks > 0))
+ {
+ temp_ticks = p_tle->ticks;
+ p_tle->ticks -= rem_ticks;
+
+ /* See if this timer has just timed out */
+ if (p_tle->ticks <= 0)
+ {
+ /* We set the number of ticks to '0' so that the legacy code
+ * that assumes a '0' or nonzero value will still work as coded. */
+ p_tle->ticks = 0;
+
+ num_time_out++;
+ }
+
+ rem_ticks -= temp_ticks; /* Decrement the remaining ticks to process */
+ p_tle = p_tle->p_next;
+ }
+
+ if (p_timer_listq->last_ticks > 0)
+ {
+ p_timer_listq->last_ticks -= num_units_since_last_update;
+
+ /* If the last timer has expired set last_ticks to 0 so that other list update
+ * functions will calculate correctly
+ */
+ if (p_timer_listq->last_ticks < 0)
+ p_timer_listq->last_ticks = 0;
+ }
+
+ return (num_time_out);
+}
+
+/*******************************************************************************
+**
+** Function GKI_get_remaining_ticks
+**
+** Description This function is called by an application to get remaining
+** ticks to expire
+**
+** Parameters p_timer_listq - (input) pointer to the timer list queue object
+** p_target_tle - (input) pointer to a timer list queue entry
+**
+** Returns 0 if timer is not used or timer is not in the list
+** remaining ticks if success
+**
+*******************************************************************************/
+UINT32 GKI_get_remaining_ticks (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_target_tle)
+{
+ TIMER_LIST_ENT *p_tle;
+ UINT32 rem_ticks = 0;
+
+ if (p_target_tle->in_use)
+ {
+ p_tle = p_timer_listq->p_first;
+
+ /* adding up all of ticks in previous entries */
+ while ((p_tle)&&(p_tle != p_target_tle))
+ {
+ rem_ticks += p_tle->ticks;
+ p_tle = p_tle->p_next;
+ }
+
+ /* if found target entry */
+ if (p_tle == p_target_tle)
+ {
+ rem_ticks += p_tle->ticks;
+ }
+ else
+ {
+ BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: No timer entry in the list");
+ return(0);
+ }
+ }
+ else
+ {
+ BT_ERROR_TRACE_0(TRACE_LAYER_GKI, "GKI_get_remaining_ticks: timer entry is not active");
+ }
+
+ return (rem_ticks);
+}
+
+/*******************************************************************************
+**
+** Function GKI_add_to_timer_list
+**
+** Description This function is called by an application to add a timer
+** entry to a timer list.
+**
+** Note: A timer value of '0' will effectively insert an already
+** expired event. Negative tick values will be ignored.
+**
+** Parameters p_timer_listq - (input) pointer to the timer list queue object
+** p_tle - (input) pointer to a timer list queue entry
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_add_to_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_tle)
+{
+ UINT32 nr_ticks_total;
+ UINT8 tt;
+ TIMER_LIST_ENT *p_temp;
+ if (p_tle == NULL || p_timer_listq == NULL) {
+ GKI_TRACE_3("%s: invalid argument %x, %x****************************<<", __func__, p_timer_listq, p_tle);
+ return;
+ }
+
+
+ /* Only process valid tick values */
+ if (p_tle->ticks >= 0)
+ {
+ /* If this entry is the last in the list */
+ if (p_tle->ticks >= p_timer_listq->last_ticks)
+ {
+ /* If this entry is the only entry in the list */
+ if (p_timer_listq->p_first == NULL)
+ p_timer_listq->p_first = p_tle;
+ else
+ {
+ /* Insert the entry onto the end of the list */
+ if (p_timer_listq->p_last != NULL)
+ p_timer_listq->p_last->p_next = p_tle;
+
+ p_tle->p_prev = p_timer_listq->p_last;
+ }
+
+ p_tle->p_next = NULL;
+ p_timer_listq->p_last = p_tle;
+ nr_ticks_total = p_tle->ticks;
+ p_tle->ticks -= p_timer_listq->last_ticks;
+
+ p_timer_listq->last_ticks = nr_ticks_total;
+ }
+ else /* This entry needs to be inserted before the last entry */
+ {
+ /* Find the entry that the new one needs to be inserted in front of */
+ p_temp = p_timer_listq->p_first;
+ while (p_tle->ticks > p_temp->ticks)
+ {
+ /* Update the tick value if looking at an unexpired entry */
+ if (p_temp->ticks > 0)
+ p_tle->ticks -= p_temp->ticks;
+
+ p_temp = p_temp->p_next;
+ }
+
+ /* The new entry is the first in the list */
+ if (p_temp == p_timer_listq->p_first)
+ {
+ p_tle->p_next = p_timer_listq->p_first;
+ p_timer_listq->p_first->p_prev = p_tle;
+ p_timer_listq->p_first = p_tle;
+ }
+ else
+ {
+ p_temp->p_prev->p_next = p_tle;
+ p_tle->p_prev = p_temp->p_prev;
+ p_temp->p_prev = p_tle;
+ p_tle->p_next = p_temp;
+ }
+ p_temp->ticks -= p_tle->ticks;
+ }
+
+ p_tle->in_use = TRUE;
+
+ /* if we already add this timer queue to the array */
+ for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+ {
+ if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+ return;
+ }
+ /* add this timer queue to the array */
+ for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+ {
+ if (gki_cb.com.timer_queues[tt] == NULL)
+ break;
+ }
+ if (tt < GKI_MAX_TIMER_QUEUES)
+ {
+ gki_cb.com.timer_queues[tt] = p_timer_listq;
+ }
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_remove_from_timer_list
+**
+** Description This function is called by an application to remove a timer
+** entry from a timer list.
+**
+** Parameters p_timer_listq - (input) pointer to the timer list queue object
+** p_tle - (input) pointer to a timer list queue entry
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_remove_from_timer_list (TIMER_LIST_Q *p_timer_listq, TIMER_LIST_ENT *p_tle)
+{
+ UINT8 tt;
+
+ /* Verify that the entry is valid */
+ if (p_tle == NULL || p_tle->in_use == FALSE || p_timer_listq->p_first == NULL)
+ {
+ return;
+ }
+
+ /* Add the ticks remaining in this timer (if any) to the next guy in the list.
+ ** Note: Expired timers have a tick value of '0'.
+ */
+ if (p_tle->p_next != NULL)
+ {
+ p_tle->p_next->ticks += p_tle->ticks;
+ }
+ else
+ {
+ p_timer_listq->last_ticks -= p_tle->ticks;
+ }
+
+ /* Unlink timer from the list.
+ */
+ if (p_timer_listq->p_first == p_tle)
+ {
+ p_timer_listq->p_first = p_tle->p_next;
+
+ if (p_timer_listq->p_first != NULL)
+ p_timer_listq->p_first->p_prev = NULL;
+
+ if (p_timer_listq->p_last == p_tle)
+ p_timer_listq->p_last = NULL;
+ }
+ else
+ {
+ if (p_timer_listq->p_last == p_tle)
+ {
+ p_timer_listq->p_last = p_tle->p_prev;
+
+ if (p_timer_listq->p_last != NULL)
+ p_timer_listq->p_last->p_next = NULL;
+ }
+ else
+ {
+ if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
+ p_tle->p_next->p_prev = p_tle->p_prev;
+ else
+ {
+ /* Error case - chain messed up ?? */
+ return;
+ }
+
+ if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
+ p_tle->p_prev->p_next = p_tle->p_next;
+ else
+ {
+ /* Error case - chain messed up ?? */
+ return;
+ }
+ }
+ }
+
+ p_tle->p_next = p_tle->p_prev = NULL;
+ p_tle->ticks = GKI_UNUSED_LIST_ENTRY;
+ p_tle->in_use = FALSE;
+
+ /* if timer queue is empty */
+ if (p_timer_listq->p_first == NULL && p_timer_listq->p_last == NULL)
+ {
+ for (tt = 0; tt < GKI_MAX_TIMER_QUEUES; tt++)
+ {
+ if (gki_cb.com.timer_queues[tt] == p_timer_listq)
+ {
+ gki_cb.com.timer_queues[tt] = NULL;
+ break;
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function gki_adjust_timer_count
+**
+** Description This function is called whenever a new timer or GKI_wait occurs
+** to adjust (if necessary) the current time til the first expiration.
+** This only needs to make an adjustment if the new timer (in ticks) is
+** less than the number of ticks remaining on the current timer.
+**
+** Parameters: ticks - (input) number of system ticks of the new timer entry
+**
+** NOTE: This routine MUST be called while interrupts are disabled to
+** avoid updates while adjusting the timer variables.
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_adjust_timer_count (INT32 ticks)
+{
+ if (ticks > 0)
+ {
+ /* See if the new timer expires before the current first expiration */
+ if (gki_cb.com.OSNumOrigTicks == 0 || (ticks < gki_cb.com.OSTicksTilExp && gki_cb.com.OSTicksTilExp > 0))
+ {
+ gki_cb.com.OSNumOrigTicks = (gki_cb.com.OSNumOrigTicks - gki_cb.com.OSTicksTilExp) + ticks;
+ gki_cb.com.OSTicksTilExp = ticks;
+ }
+ }
+
+ return;
+}
diff --git a/halimpl/bcm2079x/gki/ulinux/data_types.h b/halimpl/bcm2079x/gki/ulinux/data_types.h
new file mode 100644
index 0000000..27ae561
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/data_types.h
@@ -0,0 +1,71 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef DATA_TYPES_H
+#define DATA_TYPES_H
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned long UINT32;
+typedef unsigned long long int UINT64;
+typedef signed long INT32;
+typedef signed char INT8;
+typedef signed short INT16;
+typedef unsigned char BOOLEAN;
+typedef UINT32 UINTPTR;
+typedef UINT32 TIME_STAMP;
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+typedef unsigned char UBYTE;
+
+#ifdef __arm
+#define PACKED __packed
+#define INLINE __inline
+#else
+#define PACKED
+#define INLINE
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN FALSE
+#endif
+
+#define UINT16_LOW_BYTE(x) ((x) & 0xff)
+#define UINT16_HI_BYTE(x) ((x) >> 8)
+
+/* MACRO definitions for safe string functions */
+/* Replace standard string functions with safe functions if available */
+#define BCM_STRCAT_S(x1,x2,x3) strcat((x1),(x3))
+#define BCM_STRNCAT_S(x1,x2,x3,x4) strncat((x1),(x3),(x4))
+#define BCM_STRCPY_S(x1,x2,x3) strcpy((x1),(x3))
+#define BCM_STRNCPY_S(x1,x2,x3,x4) strncpy((x1),(x3),(x4))
+#define BCM_SPRINTF_S(x1,x2,x3,x4) sprintf((x1),(x3),(x4))
+#define BCM_VSPRINTF_S(x1,x2,x3,x4) vsprintf((x1),(x3),(x4))
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_int.h b/halimpl/bcm2079x/gki/ulinux/gki_int.h
new file mode 100644
index 0000000..c59ac32
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_int.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef GKI_INT_H
+#define GKI_INT_H
+
+#include "gki_common.h"
+#include <pthread.h>
+
+/**********************************************************************
+** OS specific definitions
+*/
+#ifdef ANDROID
+#include <sys/times.h>
+#endif
+
+typedef struct
+{
+ pthread_mutex_t GKI_mutex;
+ pthread_t thread_id[GKI_MAX_TASKS];
+ pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];
+ pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];
+ pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];
+ pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];
+ int no_timer_suspend; /* 1: no suspend, 0 stop calling GKI_timer_update() */
+ pthread_mutex_t gki_timer_mutex;
+ pthread_cond_t gki_timer_cond;
+ int gki_timer_wake_lock_on;
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_t GKI_trace_mutex;
+#endif
+} tGKI_OS;
+
+/* condition to exit or continue GKI_run() timer loop */
+#define GKI_TIMER_TICK_RUN_COND 1
+#define GKI_TIMER_TICK_STOP_COND 0
+#define GKI_TIMER_TICK_EXIT_COND 2
+
+extern void gki_system_tick_start_stop_cback(BOOLEAN start);
+
+/* Contains common control block as well as OS specific variables */
+typedef struct
+{
+ tGKI_OS os;
+ tGKI_COM_CB com;
+} tGKI_CB;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if GKI_DYNAMIC_MEMORY == FALSE
+GKI_API extern tGKI_CB gki_cb;
+#else
+GKI_API extern tGKI_CB *gki_cb_ptr;
+#define gki_cb (*gki_cb_ptr)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
new file mode 100644
index 0000000..df58e27
--- /dev/null
+++ b/halimpl/bcm2079x/gki/ulinux/gki_ulinux.c
@@ -0,0 +1,1317 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#include <malloc.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define GKI_DEBUG FALSE
+
+#include <pthread.h> /* must be 1st header defined */
+#include <time.h>
+#include <hardware_legacy/power.h> /* Android header */
+#include "gki_int.h"
+#include "gki_target.h"
+
+/* Temp android logging...move to android tgt config file */
+
+#ifndef LINUX_NATIVE
+#include <cutils/log.h>
+#else
+#define LOGV(format, ...) fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+#define LOGE(format, ...) fprintf (stderr, LOG_TAG format, ## __VA_ARGS__)
+#define LOGI(format, ...) fprintf (stdout, LOG_TAG format, ## __VA_ARGS__)
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#endif
+
+/* Define the structure that holds the GKI variables
+*/
+#if GKI_DYNAMIC_MEMORY == FALSE
+tGKI_CB gki_cb;
+#endif
+
+#define NANOSEC_PER_MILLISEC (1000000)
+#define NSEC_PER_SEC (1000*NANOSEC_PER_MILLISEC)
+
+/* works only for 1ms to 1000ms heart beat ranges */
+#define LINUX_SEC (1000/TICKS_PER_SEC)
+// #define GKI_TICK_TIMER_DEBUG
+
+#define LOCK(m) pthread_mutex_lock(&m)
+#define UNLOCK(m) pthread_mutex_unlock(&m)
+#define INIT(m) pthread_mutex_init(&m, NULL)
+
+
+/* this kind of mutex go into tGKI_OS control block!!!! */
+/* static pthread_mutex_t GKI_sched_mutex; */
+/*static pthread_mutex_t thread_delay_mutex;
+static pthread_cond_t thread_delay_cond;
+static pthread_mutex_t gki_timer_update_mutex;
+static pthread_cond_t gki_timer_update_cond;
+*/
+#ifdef NO_GKI_RUN_RETURN
+static pthread_t timer_thread_id = 0;
+#endif
+
+
+/* For Android */
+
+#ifndef GKI_SHUTDOWN_EVT
+#define GKI_SHUTDOWN_EVT APPL_EVT_7
+#endif
+
+typedef struct
+{
+ UINT8 task_id; /* GKI task id */
+ TASKPTR task_entry; /* Task entry function*/
+ UINT32 params; /* Extra params to pass to task entry function */
+ pthread_cond_t* pCond; /* for android*/
+ pthread_mutex_t* pMutex; /* for android*/
+} gki_pthread_info_t;
+gki_pthread_info_t gki_pthread_info[GKI_MAX_TASKS];
+
+static void* GKI_run_worker_thread (void*);
+
+/*******************************************************************************
+**
+** Function gki_task_entry
+**
+** Description entry point of GKI created tasks
+**
+** Returns void
+**
+*******************************************************************************/
+void gki_task_entry(UINT32 params)
+{
+ pthread_t thread_id = pthread_self();
+ gki_pthread_info_t *p_pthread_info = (gki_pthread_info_t *)params;
+ GKI_TRACE_5("gki_task_entry task_id=%i, thread_id=%x/%x, pCond/pMutex=%x/%x", p_pthread_info->task_id,
+ gki_cb.os.thread_id[p_pthread_info->task_id], pthread_self(),
+ p_pthread_info->pCond, p_pthread_info->pMutex);
+
+ gki_cb.os.thread_id[p_pthread_info->task_id] = thread_id;
+ /* Call the actual thread entry point */
+ (p_pthread_info->task_entry)(p_pthread_info->params);
+
+ GKI_TRACE_1("gki_task task_id=%i terminating", p_pthread_info->task_id);
+ gki_cb.os.thread_id[p_pthread_info->task_id] = 0;
+
+ pthread_exit(0); /* GKI tasks have no return value */
+}
+/* end android */
+
+#ifndef ANDROID
+void GKI_TRACE(char *fmt, ...)
+{
+ LOCK(gki_cb.os.GKI_trace_mutex);
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+ UNLOCK(gki_cb.os.GKI_trace_mutex);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function GKI_init
+**
+** Description This function is called once at startup to initialize
+** all the timer structures.
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_init(void)
+{
+ pthread_mutexattr_t attr;
+ tGKI_OS *p_os;
+
+ memset (&gki_cb, 0, sizeof (gki_cb));
+
+ gki_buffer_init();
+ gki_timers_init();
+ gki_cb.com.OSTicks = (UINT32) times(0);
+
+ pthread_mutexattr_init(&attr);
+
+#ifndef __CYGWIN__
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+ p_os = &gki_cb.os;
+ pthread_mutex_init(&p_os->GKI_mutex, &attr);
+ /* pthread_mutex_init(&GKI_sched_mutex, NULL); */
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);
+#endif
+ /* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
+ /* pthread_cond_init (&thread_delay_cond, NULL); */
+
+ /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
+ * this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
+ p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
+ pthread_mutex_init(&p_os->gki_timer_mutex, NULL);
+ pthread_cond_init(&p_os->gki_timer_cond, NULL);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_os_tick_count
+**
+** Description This function is called to retrieve the native OS system tick.
+**
+** Returns Tick count of native OS.
+**
+*******************************************************************************/
+UINT32 GKI_get_os_tick_count(void)
+{
+
+ /* TODO - add any OS specific code here
+ **/
+ return (gki_cb.com.OSTicks);
+}
+
+/*******************************************************************************
+**
+** Function GKI_create_task
+**
+** Description This function is called to create a new OSS task.
+**
+** Parameters: task_entry - (input) pointer to the entry function of the task
+** task_id - (input) Task id is mapped to priority
+** taskname - (input) name given to the task
+** stack - (input) pointer to the top of the stack (highest memory location)
+** stacksize - (input) size of the stack allocated for the task
+**
+** Returns GKI_SUCCESS if all OK, GKI_FAILURE if any problem
+**
+** NOTE This function take some parameters that may not be needed
+** by your particular OS. They are here for compatability
+** of the function prototype.
+**
+*******************************************************************************/
+UINT8 GKI_create_task (TASKPTR task_entry, UINT8 task_id, INT8 *taskname, UINT16 *stack, UINT16 stacksize, void* pCondVar, void* pMutex)
+{
+ UINT16 i;
+ UINT8 *p;
+ struct sched_param param;
+ int policy, ret = 0;
+ pthread_condattr_t attr;
+ pthread_attr_t attr1;
+
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ GKI_TRACE_5 ("GKI_create_task func=0x%x id=%d name=%s stack=0x%x stackSize=%d", task_entry, task_id, taskname, stack, stacksize);
+
+ if (task_id >= GKI_MAX_TASKS)
+ {
+ GKI_TRACE_0("Error! task ID > max task allowed");
+ return (GKI_FAILURE);
+ }
+
+
+ gki_cb.com.OSRdyTbl[task_id] = TASK_READY;
+ gki_cb.com.OSTName[task_id] = taskname;
+ gki_cb.com.OSWaitTmr[task_id] = 0;
+ gki_cb.com.OSWaitEvt[task_id] = 0;
+
+ /* Initialize mutex and condition variable objects for events and timeouts */
+ pthread_mutex_init(&gki_cb.os.thread_evt_mutex[task_id], NULL);
+ pthread_cond_init (&gki_cb.os.thread_evt_cond[task_id], &attr);
+ pthread_mutex_init(&gki_cb.os.thread_timeout_mutex[task_id], NULL);
+ pthread_cond_init (&gki_cb.os.thread_timeout_cond[task_id], &attr);
+
+ pthread_attr_init(&attr1);
+ /* by default, pthread creates a joinable thread */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ pthread_attr_setdetachstate(&attr1, PTHREAD_CREATE_DETACHED);
+
+ GKI_TRACE_3("GKI creating task %i, pCond/pMutex=%x/%x", task_id, pCondVar, pMutex);
+#else
+ GKI_TRACE_1("GKI creating JOINABLE task %i", task_id);
+#endif
+
+ /* On Android, the new tasks starts running before 'gki_cb.os.thread_id[task_id]' is initialized */
+ /* Pass task_id to new task so it can initialize gki_cb.os.thread_id[task_id] for it calls GKI_wait */
+ gki_pthread_info[task_id].task_id = task_id;
+ gki_pthread_info[task_id].task_entry = task_entry;
+ gki_pthread_info[task_id].params = 0;
+ gki_pthread_info[task_id].pCond = (pthread_cond_t*)pCondVar;
+ gki_pthread_info[task_id].pMutex = (pthread_mutex_t*)pMutex;
+
+ ret = pthread_create( &gki_cb.os.thread_id[task_id],
+ &attr1,
+ (void *)gki_task_entry,
+ &gki_pthread_info[task_id]);
+
+ if (ret != 0)
+ {
+ GKI_TRACE_2("pthread_create failed(%d), %s!", ret, taskname);
+ return GKI_FAILURE;
+ }
+
+ if(pthread_getschedparam(gki_cb.os.thread_id[task_id], &policy, ¶m)==0)
+ {
+#if defined(PBS_SQL_TASK)
+ if (task_id == PBS_SQL_TASK)
+ {
+ GKI_TRACE_0("PBS SQL lowest priority task");
+ policy = SCHED_NORMAL;
+ }
+ else
+#endif
+ {
+ policy = SCHED_RR;
+ param.sched_priority = 30 - task_id - 2;
+ }
+ pthread_setschedparam(gki_cb.os.thread_id[task_id], policy, ¶m);
+ }
+
+ GKI_TRACE_6( "Leaving GKI_create_task %x %d %x %s %x %d",
+ task_entry,
+ task_id,
+ gki_cb.os.thread_id[task_id],
+ taskname,
+ stack,
+ stacksize);
+
+ return (GKI_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function GKI_shutdown
+**
+** Description shutdowns the GKI tasks/threads in from max task id to 0 and frees
+** pthread resources!
+** IMPORTANT: in case of join method, GKI_shutdown must be called outside
+** a GKI thread context!
+**
+** Returns void
+**
+*******************************************************************************/
+#define WAKE_LOCK_ID "brcm_nfca"
+
+void GKI_shutdown(void)
+{
+ UINT8 task_id;
+ volatile int *p_run_cond = &gki_cb.os.no_timer_suspend;
+ int oldCOnd = 0;
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ int i = 0;
+#else
+ int result;
+#endif
+
+ /* release threads and set as TASK_DEAD. going from low to high priority fixes
+ * GKI_exception problem due to btu->hci sleep request events */
+ for (task_id = GKI_MAX_TASKS; task_id > 0; task_id--)
+ {
+ if (gki_cb.com.OSRdyTbl[task_id - 1] != TASK_DEAD)
+ {
+ gki_cb.com.OSRdyTbl[task_id - 1] = TASK_DEAD;
+
+ /* paranoi settings, make sure that we do not execute any mailbox events */
+ gki_cb.com.OSWaitEvt[task_id-1] &= ~(TASK_MBOX_0_EVT_MASK|TASK_MBOX_1_EVT_MASK|
+ TASK_MBOX_2_EVT_MASK|TASK_MBOX_3_EVT_MASK);
+ GKI_send_event(task_id - 1, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ i = 0;
+
+ while ((gki_cb.com.OSWaitEvt[task_id - 1] != 0) && (++i < 10))
+ usleep(100 * 1000);
+#else
+ /* wait for proper Arnold Schwarzenegger task state */
+ result = pthread_join( gki_cb.os.thread_id[task_id-1], NULL );
+ if ( result < 0 )
+ {
+ GKI_TRACE_1( "pthread_join() FAILED: result: %d", result );
+ }
+#endif
+ GKI_TRACE_1( "GKI_shutdown(): task %s dead", gki_cb.com.OSTName[task_id]);
+ GKI_exit_task(task_id - 1);
+ }
+ }
+
+ /* Destroy mutex and condition variable objects */
+ pthread_mutex_destroy(&gki_cb.os.GKI_mutex);
+ /* pthread_mutex_destroy(&GKI_sched_mutex); */
+#if (GKI_DEBUG == TRUE)
+ pthread_mutex_destroy(&gki_cb.os.GKI_trace_mutex);
+#endif
+ /* pthread_mutex_destroy(&thread_delay_mutex);
+ pthread_cond_destroy (&thread_delay_cond); */
+#if ( FALSE == GKI_PTHREAD_JOINABLE )
+ i = 0;
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+ shutdown_timer = 1;
+#endif
+ if (gki_cb.os.gki_timer_wake_lock_on)
+ {
+ GKI_TRACE_0("GKI_shutdown : release_wake_lock(brcm_btld)");
+ release_wake_lock(WAKE_LOCK_ID);
+ gki_cb.os.gki_timer_wake_lock_on = 0;
+ }
+ oldCOnd = *p_run_cond;
+ *p_run_cond = GKI_TIMER_TICK_EXIT_COND;
+ if (oldCOnd == GKI_TIMER_TICK_STOP_COND)
+ pthread_cond_signal( &gki_cb.os.gki_timer_cond );
+
+}
+
+/*******************************************************************************
+ **
+ ** Function GKI_run
+ **
+ ** Description This function runs a task
+ **
+ ** Parameters: start: TRUE start system tick (again), FALSE stop
+ **
+ ** Returns void
+ **
+ *********************************************************************************/
+void gki_system_tick_start_stop_cback(BOOLEAN start)
+{
+ tGKI_OS *p_os = &gki_cb.os;
+ volatile int *p_run_cond = &p_os->no_timer_suspend;
+ volatile static int wake_lock_count;
+ if ( FALSE == start )
+ {
+ /* this can lead to a race condition. however as we only read this variable in the timer loop
+ * we should be fine with this approach. otherwise uncomment below mutexes.
+ */
+ /* GKI_disable(); */
+ *p_run_cond = GKI_TIMER_TICK_STOP_COND;
+ /* GKI_enable(); */
+#ifdef GKI_TICK_TIMER_DEBUG
+ BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> STOP GKI_timer_update(), wake_lock_count:%d", --wake_lock_count);
+#endif
+ release_wake_lock(WAKE_LOCK_ID);
+ gki_cb.os.gki_timer_wake_lock_on = 0;
+ }
+ else
+ {
+ /* restart GKI_timer_update() loop */
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+ gki_cb.os.gki_timer_wake_lock_on = 1;
+ *p_run_cond = GKI_TIMER_TICK_RUN_COND;
+ pthread_mutex_lock( &p_os->gki_timer_mutex );
+ pthread_cond_signal( &p_os->gki_timer_cond );
+ pthread_mutex_unlock( &p_os->gki_timer_mutex );
+
+#ifdef GKI_TICK_TIMER_DEBUG
+ BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> START GKI_timer_update(), wake_lock_count:%d", ++wake_lock_count );
+#endif
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function timer_thread
+**
+** Description Timer thread
+**
+** Parameters: id - (input) timer ID
+**
+** Returns void
+**
+*********************************************************************************/
+#ifdef NO_GKI_RUN_RETURN
+void timer_thread(signed long id)
+{
+ GKI_TRACE_1("%s enter", __func__);
+ struct timespec delay;
+ int timeout = 1000; /* 10 ms per system tick */
+ int err;
+
+ while(!shutdown_timer)
+ {
+ 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);
+
+ GKI_timer_update(1);
+ }
+ GKI_TRACE_1("%s exit", __func__);
+ pthread_exit(NULL);
+}
+#endif
+
+/*******************************************************************************
+**
+** Function GKI_run
+**
+** Description This function runs a task
+**
+** Parameters: p_task_id - (input) pointer to task id
+**
+** Returns void
+**
+** NOTE This function is only needed for operating systems where
+** starting a task is a 2-step process. Most OS's do it in
+** one step, If your OS does it in one step, this function
+** should be empty.
+*********************************************************************************/
+void GKI_run (void *p_task_id)
+{
+ GKI_TRACE_1("%s enter", __func__);
+ int retval = EACCES;
+ static pthread_t workerThreadId = 0;
+
+ retval = pthread_create (&workerThreadId, NULL, GKI_run_worker_thread, NULL);
+ if (retval != 0)
+ {
+ GKI_TRACE_ERROR_2 ("%s: fail create thread %d", __func__, retval);
+ }
+ GKI_TRACE_1("%s exit", __func__);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_run_worker_thread
+**
+** Description This function runs a task
+**
+** Parameters: None
+**
+** Returns: error code
+*********************************************************************************/
+void* GKI_run_worker_thread (void* dummy)
+{
+ GKI_TRACE_1("%s: enter", __func__);
+ struct timespec delay;
+ int err = 0;
+ volatile int * p_run_cond = &gki_cb.os.no_timer_suspend;
+
+#ifndef GKI_NO_TICK_STOP
+ /* register start stop function which disable timer loop in GKI_run() when no timers are
+ * in any GKI/BTA/BTU this should save power when BTLD is idle! */
+ GKI_timer_queue_register_callback( gki_system_tick_start_stop_cback );
+ GKI_TRACE_1( "%s: Start/Stop GKI_timer_update_registered!", __func__ );
+#endif
+
+#ifdef NO_GKI_RUN_RETURN
+ GKI_TRACE_1("%s: GKI_run == NO_GKI_RUN_RETURN", __func__);
+ pthread_attr_t timer_attr;
+
+ shutdown_timer = 0;
+
+ pthread_attr_init(&timer_attr);
+ pthread_attr_setdetachstate(&timer_attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create( &timer_thread_id,
+ &timer_attr,
+ timer_thread,
+ NULL) != 0 )
+ {
+ GKI_TRACE_1("%s: pthread_create failed to create timer_thread!", __func__);
+ return NULL;
+ }
+#else
+ GKI_TRACE_3("%s: run_cond(%x)=%d ", __func__, p_run_cond, *p_run_cond);
+ for (;GKI_TIMER_TICK_EXIT_COND != *p_run_cond;)
+ {
+ do
+ {
+ /* adjust hear bit tick in btld by changning TICKS_PER_SEC!!!!! this formula works only for
+ * 1-1000ms heart beat units! */
+ delay.tv_sec = LINUX_SEC / 1000;
+ delay.tv_nsec = 1000 * 1000 * (LINUX_SEC % 1000);
+
+ /* [u]sleep can't be used because it uses SIGALRM */
+ do
+ {
+ err = nanosleep(&delay, &delay);
+ } while (err < 0 && errno == EINTR);
+
+ /* the unit should be alsways 1 (1 tick). only if you vary for some reason heart beat tick
+ * e.g. power saving you may want to provide more ticks
+ */
+ GKI_timer_update( 1 );
+ /* BT_TRACE_2( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, "update: tv_sec: %d, tv_nsec: %d", delay.tv_sec, delay.tv_nsec ); */
+ } while ( GKI_TIMER_TICK_RUN_COND == *p_run_cond);
+
+ /* currently on reason to exit above loop is no_timer_suspend == GKI_TIMER_TICK_STOP_COND
+ * block timer main thread till re-armed by */
+#ifdef GKI_TICK_TIMER_DEBUG
+ BT_TRACE_0( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> SUSPENDED GKI_timer_update()" );
+#endif
+ if (GKI_TIMER_TICK_EXIT_COND != *p_run_cond) {
+ GKI_TRACE_1("%s: waiting timer mutex", __func__);
+ pthread_mutex_lock( &gki_cb.os.gki_timer_mutex );
+ pthread_cond_wait( &gki_cb.os.gki_timer_cond, &gki_cb.os.gki_timer_mutex );
+ pthread_mutex_unlock( &gki_cb.os.gki_timer_mutex );
+ GKI_TRACE_1("%s: exited timer mutex", __func__);
+ }
+ /* potentially we need to adjust os gki_cb.com.OSTicks */
+
+#ifdef GKI_TICK_TIMER_DEBUG
+ BT_TRACE_1( TRACE_LAYER_HCI, TRACE_TYPE_DEBUG, ">>> RESTARTED GKI_timer_update(): run_cond: %d",
+ *p_run_cond );
+#endif
+ } /* for */
+#endif
+ GKI_TRACE_1("%s: exit", __func__);
+ return NULL;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_stop
+**
+** Description This function is called to stop
+** the tasks and timers when the system is being stopped
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put specific code here.
+**
+*******************************************************************************/
+void GKI_stop (void)
+{
+ UINT8 task_id;
+
+ /* gki_queue_timer_cback(FALSE); */
+ /* TODO - add code here if needed*/
+
+ for(task_id = 0; task_id<GKI_MAX_TASKS; task_id++)
+ {
+ if(gki_cb.com.OSRdyTbl[task_id] != TASK_DEAD)
+ {
+ GKI_exit_task(task_id);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_wait
+**
+** Description This function is called by tasks to wait for a specific
+** event or set of events. The task may specify the duration
+** that it wants to wait for, or 0 if infinite.
+**
+** Parameters: flag - (input) the event or set of events to wait for
+** timeout - (input) the duration that the task wants to wait
+** for the specific events (in system ticks)
+**
+**
+** Returns the event mask of received events or zero if timeout
+**
+*******************************************************************************/
+UINT16 GKI_wait (UINT16 flag, UINT32 timeout)
+{
+ UINT16 evt;
+ UINT8 rtask;
+ struct timespec abstime = { 0, 0 };
+ int sec;
+ int nano_sec;
+
+ rtask = GKI_get_taskid();
+ GKI_TRACE_3("GKI_wait %d %x %d", rtask, flag, timeout);
+ if (rtask >= GKI_MAX_TASKS) {
+ pthread_exit(NULL);
+ return 0;
+ }
+
+ gki_pthread_info_t* p_pthread_info = &gki_pthread_info[rtask];
+ if (p_pthread_info->pCond != NULL && p_pthread_info->pMutex != NULL) {
+ int ret;
+ GKI_TRACE_3("GKI_wait task=%i, pCond/pMutex = %x/%x", rtask, p_pthread_info->pCond, p_pthread_info->pMutex);
+ ret = pthread_mutex_lock(p_pthread_info->pMutex);
+ ret = pthread_cond_signal(p_pthread_info->pCond);
+ ret = pthread_mutex_unlock(p_pthread_info->pMutex);
+ p_pthread_info->pMutex = NULL;
+ p_pthread_info->pCond = NULL;
+ }
+ gki_cb.com.OSWaitForEvt[rtask] = flag;
+
+ /* protect OSWaitEvt[rtask] from modification from an other thread */
+ pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[rtask]);
+
+#if 0 /* for clean scheduling we probably should always call pthread_cond_wait() */
+ /* Check if anything in any of the mailboxes. There is a potential race condition where OSTaskQFirst[rtask]
+ has been modified. however this should only result in addtional call to pthread_cond_wait() but as
+ the cond is met, it will exit immediately (depending on schedulling) */
+ if (gki_cb.com.OSTaskQFirst[rtask][0])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][1])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][2])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][3])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+#endif
+
+ if (!(gki_cb.com.OSWaitEvt[rtask] & flag))
+ {
+ if (timeout)
+ {
+ // timeout = GKI_MS_TO_TICKS(timeout); /* convert from milliseconds to ticks */
+
+ /* get current system time */
+ // clock_gettime(CLOCK_MONOTONIC, &currSysTime);
+ // abstime.tv_sec = currSysTime.time;
+ // abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;
+ clock_gettime(CLOCK_MONOTONIC, &abstime);
+
+ /* add timeout */
+ sec = timeout / 1000;
+ nano_sec = (timeout % 1000) * NANOSEC_PER_MILLISEC;
+ abstime.tv_nsec += nano_sec;
+ if (abstime.tv_nsec > NSEC_PER_SEC)
+ {
+ abstime.tv_sec += (abstime.tv_nsec / NSEC_PER_SEC);
+ abstime.tv_nsec = abstime.tv_nsec % NSEC_PER_SEC;
+ }
+ abstime.tv_sec += sec;
+
+ pthread_cond_timedwait(&gki_cb.os.thread_evt_cond[rtask],
+ &gki_cb.os.thread_evt_mutex[rtask], &abstime);
+
+ }
+ else
+ {
+ pthread_cond_wait(&gki_cb.os.thread_evt_cond[rtask], &gki_cb.os.thread_evt_mutex[rtask]);
+ }
+
+ /* TODO: check, this is probably neither not needed depending on phtread_cond_wait() implmentation,
+ e.g. it looks like it is implemented as a counter in which case multiple cond_signal
+ should NOT be lost! */
+ // we are waking up after waiting for some events, so refresh variables
+ // no need to call GKI_disable() here as we know that we will have some events as we've been waking up after condition pending or timeout
+ if (gki_cb.com.OSTaskQFirst[rtask][0])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_0_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][1])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_1_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][2])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_2_EVT_MASK;
+ if (gki_cb.com.OSTaskQFirst[rtask][3])
+ gki_cb.com.OSWaitEvt[rtask] |= TASK_MBOX_3_EVT_MASK;
+
+ if (gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+ {
+ gki_cb.com.OSWaitEvt[rtask] = 0;
+ /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock when cond is met */
+ pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+ GKI_TRACE_1("GKI TASK_DEAD received. exit thread %d...", rtask );
+
+ gki_cb.os.thread_id[rtask] = 0;
+ pthread_exit(NULL);
+ return (EVENT_MASK(GKI_SHUTDOWN_EVT));
+ }
+ }
+
+ /* Clear the wait for event mask */
+ gki_cb.com.OSWaitForEvt[rtask] = 0;
+
+ /* Return only those bits which user wants... */
+ evt = gki_cb.com.OSWaitEvt[rtask] & flag;
+
+ /* Clear only those bits which user wants... */
+ gki_cb.com.OSWaitEvt[rtask] &= ~flag;
+
+ /* unlock thread_evt_mutex as pthread_cond_wait() does auto lock mutex when cond is met */
+ pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[rtask]);
+ GKI_TRACE_4("GKI_wait %d %x %d %x resumed", rtask, flag, timeout, evt);
+
+ return (evt);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_delay
+**
+** Description This function is called by tasks to sleep unconditionally
+** for a specified amount of time. The duration is in milliseconds
+**
+** Parameters: timeout - (input) the duration in milliseconds
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_delay (UINT32 timeout)
+{
+ UINT8 rtask = GKI_get_taskid();
+ struct timespec delay;
+ int err;
+
+ GKI_TRACE_2("GKI_delay %d %d", rtask, timeout);
+
+ 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);
+
+ /* Check if task was killed while sleeping */
+ /* NOTE
+ ** if you do not implement task killing, you do not
+ ** need this check.
+ */
+ if (rtask && gki_cb.com.OSRdyTbl[rtask] == TASK_DEAD)
+ {
+ }
+
+ GKI_TRACE_2("GKI_delay %d %d done", rtask, timeout);
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_send_event
+**
+** Description This function is called by tasks to send events to other
+** tasks. Tasks can also send events to themselves.
+**
+** Parameters: task_id - (input) The id of the task to which the event has to
+** be sent
+** event - (input) The event that has to be sent
+**
+**
+** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+*******************************************************************************/
+UINT8 GKI_send_event (UINT8 task_id, UINT16 event)
+{
+ GKI_TRACE_2("GKI_send_event %d %x", task_id, event);
+
+ /* use efficient coding to avoid pipeline stalls */
+ if (task_id < GKI_MAX_TASKS)
+ {
+ /* protect OSWaitEvt[task_id] from manipulation in GKI_wait() */
+ pthread_mutex_lock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+ /* Set the event bit */
+ gki_cb.com.OSWaitEvt[task_id] |= event;
+
+ pthread_cond_signal(&gki_cb.os.thread_evt_cond[task_id]);
+
+ pthread_mutex_unlock(&gki_cb.os.thread_evt_mutex[task_id]);
+
+ GKI_TRACE_2("GKI_send_event %d %x done", task_id, event);
+ return ( GKI_SUCCESS );
+ }
+ return (GKI_FAILURE);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_isend_event
+**
+** Description This function is called from ISRs to send events to other
+** tasks. The only difference between this function and GKI_send_event
+** is that this function assumes interrupts are already disabled.
+**
+** Parameters: task_id - (input) The destination task Id for the event.
+** event - (input) The event flag
+**
+** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put your code here, otherwise you can delete the entire
+** body of the function.
+**
+*******************************************************************************/
+UINT8 GKI_isend_event (UINT8 task_id, UINT16 event)
+{
+
+ GKI_TRACE_2("GKI_isend_event %d %x", task_id, event);
+ GKI_TRACE_2("GKI_isend_event %d %x done", task_id, event);
+ return GKI_send_event(task_id, event);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_taskid
+**
+** Description This function gets the currently running task ID.
+**
+** Returns task ID
+**
+** NOTE The Widcomm upper stack and profiles may run as a single task.
+** If you only have one GKI task, then you can hard-code this
+** function to return a '1'. Otherwise, you should have some
+** OS-specific method to determine the current task.
+**
+*******************************************************************************/
+UINT8 GKI_get_taskid (void)
+{
+ int i;
+
+ pthread_t thread_id = pthread_self( );
+ for (i = 0; i < GKI_MAX_TASKS; i++) {
+ if (gki_cb.os.thread_id[i] == thread_id) {
+ GKI_TRACE_2("GKI_get_taskid %x %d done", thread_id, i);
+ return(i);
+ }
+ }
+
+ GKI_TRACE_1("GKI_get_taskid: thread id = %x, task id = -1", thread_id);
+
+ return(-1);
+}
+
+/*******************************************************************************
+**
+** Function GKI_map_taskname
+**
+** Description This function gets the task name of the taskid passed as arg.
+** If GKI_MAX_TASKS is passed as arg the currently running task
+** name is returned
+**
+** Parameters: task_id - (input) The id of the task whose name is being
+** sought. GKI_MAX_TASKS is passed to get the name of the
+** currently running task.
+**
+** Returns pointer to task name
+**
+** NOTE this function needs no customization
+**
+*******************************************************************************/
+UINT8 *GKI_map_taskname (UINT8 task_id)
+{
+ GKI_TRACE_1("GKI_map_taskname %d", task_id);
+
+ if (task_id < GKI_MAX_TASKS)
+ {
+ GKI_TRACE_2("GKI_map_taskname %d %s done", task_id, gki_cb.com.OSTName[task_id]);
+ return (gki_cb.com.OSTName[task_id]);
+ }
+ else if (task_id == GKI_MAX_TASKS )
+ {
+ return (gki_cb.com.OSTName[GKI_get_taskid()]);
+ }
+ else
+ {
+ return (UINT8*) "BAD";
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_enable
+**
+** Description This function enables interrupts.
+**
+** Returns void
+**
+*******************************************************************************/
+void GKI_enable (void)
+{
+ GKI_TRACE_0("GKI_enable");
+ pthread_mutex_unlock(&gki_cb.os.GKI_mutex);
+/* pthread_mutex_xx is nesting save, no need for this: already_disabled = 0; */
+ GKI_TRACE_0("Leaving GKI_enable");
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_disable
+**
+** Description This function disables interrupts.
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_disable (void)
+{
+ //GKI_TRACE_0("GKI_disable");
+
+/* pthread_mutex_xx is nesting save, no need for this: if (!already_disabled) {
+ already_disabled = 1; */
+ pthread_mutex_lock(&gki_cb.os.GKI_mutex);
+/* } */
+ //GKI_TRACE_0("Leaving GKI_disable");
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_exception
+**
+** Description This function throws an exception.
+** This is normally only called for a nonrecoverable error.
+**
+** Parameters: code - (input) The code for the error
+** msg - (input) The message that has to be logged
+**
+** Returns void
+**
+*******************************************************************************/
+
+void GKI_exception (UINT16 code, char *msg)
+{
+ UINT8 task_id;
+ int i = 0;
+
+ GKI_TRACE_ERROR_0( "GKI_exception(): Task State Table");
+
+ for(task_id = 0; task_id < GKI_MAX_TASKS; task_id++)
+ {
+ GKI_TRACE_ERROR_3( "TASK ID [%d] task name [%s] state [%d]",
+ task_id,
+ gki_cb.com.OSTName[task_id],
+ gki_cb.com.OSRdyTbl[task_id]);
+ }
+
+ GKI_TRACE_ERROR_2("GKI_exception %d %s", code, msg);
+ GKI_TRACE_ERROR_0( "********************************************************************");
+ GKI_TRACE_ERROR_2( "* GKI_exception(): %d %s", code, msg);
+ GKI_TRACE_ERROR_0( "********************************************************************");
+
+#if (GKI_DEBUG == TRUE)
+ GKI_disable();
+
+ if (gki_cb.com.ExceptionCnt < GKI_MAX_EXCEPTION)
+ {
+ EXCEPTION_T *pExp;
+
+ pExp = &gki_cb.com.Exception[gki_cb.com.ExceptionCnt++];
+ pExp->type = code;
+ pExp->taskid = GKI_get_taskid();
+ strncpy((char *)pExp->msg, msg, GKI_MAX_EXCEPTION_MSGLEN - 1);
+ }
+
+ GKI_enable();
+#endif
+
+ GKI_TRACE_ERROR_2("GKI_exception %d %s done", code, msg);
+
+
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_get_time_stamp
+**
+** Description This function formats the time into a user area
+**
+** Parameters: tbuf - (output) the address to the memory containing the
+** formatted time
+**
+** Returns the address of the user area containing the formatted time
+** The format of the time is ????
+**
+** NOTE This function is only called by OBEX.
+**
+*******************************************************************************/
+INT8 *GKI_get_time_stamp (INT8 *tbuf)
+{
+ UINT32 ms_time;
+ UINT32 s_time;
+ UINT32 m_time;
+ UINT32 h_time;
+ INT8 *p_out = tbuf;
+
+ gki_cb.com.OSTicks = times(0);
+ ms_time = GKI_TICKS_TO_MS(gki_cb.com.OSTicks);
+ s_time = ms_time/100; /* 100 Ticks per second */
+ m_time = s_time/60;
+ h_time = m_time/60;
+
+ ms_time -= s_time*100;
+ s_time -= m_time*60;
+ m_time -= h_time*60;
+
+ *p_out++ = (INT8)((h_time / 10) + '0');
+ *p_out++ = (INT8)((h_time % 10) + '0');
+ *p_out++ = ':';
+ *p_out++ = (INT8)((m_time / 10) + '0');
+ *p_out++ = (INT8)((m_time % 10) + '0');
+ *p_out++ = ':';
+ *p_out++ = (INT8)((s_time / 10) + '0');
+ *p_out++ = (INT8)((s_time % 10) + '0');
+ *p_out++ = ':';
+ *p_out++ = (INT8)((ms_time / 10) + '0');
+ *p_out++ = (INT8)((ms_time % 10) + '0');
+ *p_out++ = ':';
+ *p_out = 0;
+
+ return (tbuf);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_register_mempool
+**
+** Description This function registers a specific memory pool.
+**
+** Parameters: p_mem - (input) pointer to the memory pool
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If your OS has different memory pools, you
+** can tell GKI the pool to use by calling this function.
+**
+*******************************************************************************/
+void GKI_register_mempool (void *p_mem)
+{
+ gki_cb.com.p_user_mempool = p_mem;
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function GKI_os_malloc
+**
+** Description This function allocates memory
+**
+** Parameters: size - (input) The size of the memory that has to be
+** allocated
+**
+** Returns the address of the memory allocated, or NULL if failed
+**
+** NOTE This function is called by the Widcomm stack when
+** dynamic memory allocation is used. (see dyn_mem.h)
+**
+*******************************************************************************/
+void *GKI_os_malloc (UINT32 size)
+{
+ return (malloc(size));
+}
+
+/*******************************************************************************
+**
+** Function GKI_os_free
+**
+** Description This function frees memory
+**
+** Parameters: size - (input) The address of the memory that has to be
+** freed
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. It is only called from within GKI if dynamic
+**
+*******************************************************************************/
+void GKI_os_free (void *p_mem)
+{
+ if(p_mem != NULL)
+ free(p_mem);
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_suspend_task()
+**
+** Description This function suspends the task specified in the argument.
+**
+** Parameters: task_id - (input) the id of the task that has to suspended
+**
+** Returns GKI_SUCCESS if all OK, else GKI_FAILURE
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to implement task suspension capability,
+** put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_suspend_task (UINT8 task_id)
+{
+ GKI_TRACE_1("GKI_suspend_task %d - NOT implemented", task_id);
+
+
+ GKI_TRACE_1("GKI_suspend_task %d done", task_id);
+
+ return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_resume_task()
+**
+** Description This function resumes the task specified in the argument.
+**
+** Parameters: task_id - (input) the id of the task that has to resumed
+**
+** Returns GKI_SUCCESS if all OK
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to implement task suspension capability,
+** put specific code here.
+**
+*******************************************************************************/
+UINT8 GKI_resume_task (UINT8 task_id)
+{
+ GKI_TRACE_1("GKI_resume_task %d - NOT implemented", task_id);
+
+
+ GKI_TRACE_1("GKI_resume_task %d done", task_id);
+
+ return (GKI_SUCCESS);
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_exit_task
+**
+** Description This function is called to stop a GKI task.
+**
+** Parameters: task_id - (input) the id of the task that has to be stopped
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put specific code here to kill a task.
+**
+*******************************************************************************/
+void GKI_exit_task (UINT8 task_id)
+{
+ GKI_disable();
+ gki_cb.com.OSRdyTbl[task_id] = TASK_DEAD;
+
+ /* Destroy mutex and condition variable objects */
+ pthread_mutex_destroy(&gki_cb.os.thread_evt_mutex[task_id]);
+ pthread_cond_destroy (&gki_cb.os.thread_evt_cond[task_id]);
+ pthread_mutex_destroy(&gki_cb.os.thread_timeout_mutex[task_id]);
+ pthread_cond_destroy (&gki_cb.os.thread_timeout_cond[task_id]);
+
+ GKI_enable();
+
+ //GKI_send_event(task_id, EVENT_MASK(GKI_SHUTDOWN_EVT));
+
+ GKI_TRACE_1("GKI_exit_task %d done", task_id);
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_sched_lock
+**
+** Description This function is called by tasks to disable scheduler
+** task context switching.
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put code here to tell the OS to disable context switching.
+**
+*******************************************************************************/
+void GKI_sched_lock(void)
+{
+ GKI_TRACE_0("GKI_sched_lock");
+ GKI_disable ();
+ return;
+}
+
+
+/*******************************************************************************
+**
+** Function GKI_sched_unlock
+**
+** Description This function is called by tasks to enable scheduler switching.
+**
+** Returns void
+**
+** NOTE This function is NOT called by the Widcomm stack and
+** profiles. If you want to use it in your own implementation,
+** put code here to tell the OS to re-enable context switching.
+**
+*******************************************************************************/
+void GKI_sched_unlock(void)
+{
+ GKI_TRACE_0("GKI_sched_unlock");
+ GKI_enable ();
+}
+
+/*******************************************************************************
+**
+** Function GKI_shiftdown
+**
+** Description shift memory down (to make space to insert a record)
+**
+*******************************************************************************/
+void GKI_shiftdown (UINT8 *p_mem, UINT32 len, UINT32 shift_amount)
+{
+ register UINT8 *ps = p_mem + len - 1;
+ register UINT8 *pd = ps + shift_amount;
+ register UINT32 xx;
+
+ for (xx = 0; xx < len; xx++)
+ *pd-- = *ps--;
+}
+
+/*******************************************************************************
+**
+** Function GKI_shiftup
+**
+** Description shift memory up (to delete a record)
+**
+*******************************************************************************/
+void GKI_shiftup (UINT8 *p_dest, UINT8 *p_src, UINT32 len)
+{
+ register UINT8 *ps = p_src;
+ register UINT8 *pd = p_dest;
+ register UINT32 xx;
+
+ for (xx = 0; xx < len; xx++)
+ *pd++ = *ps++;
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_api.c b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
new file mode 100644
index 0000000..e47fabf
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_api.c
@@ -0,0 +1,326 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * NFC Hardware Abstraction Layer API: Implementation for Broadcom NFC
+ * controllers
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+/*******************************************************************************
+** NFC_HAL_TASK declarations
+*******************************************************************************/
+#define NFC_HAL_TASK_STR ((INT8 *) "NFC_HAL_TASK")
+#define NFC_HAL_TASK_STACK_SIZE 0x400
+UINT32 nfc_hal_task_stack[(NFC_HAL_TASK_STACK_SIZE+3)/4];
+
+/*******************************************************************************
+**
+** Function HAL_NfcInitialize
+**
+** Description Called when HAL library is loaded.
+**
+** Initialize GKI and start the HCIT task
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcInitialize (void)
+{
+ /* Initialize HAL control block */
+ nfc_hal_main_init ();
+
+ HAL_TRACE_API1 ("HAL_NfcInitialize (): NFC_HAL_TASK id=%i", NFC_HAL_TASK);
+
+
+#ifndef NFC_HAL_SHARED_GKI
+ /* Initialize GKI (not needed if using shared NFC/HAL GKI resources) */
+ GKI_init ();
+ GKI_enable ();
+#endif
+
+ /* Create the NCI transport task */
+ GKI_create_task ((TASKPTR)nfc_hal_main_task,
+ NFC_HAL_TASK,
+ NFC_HAL_TASK_STR,
+ (UINT16 *) ((UINT8 *)nfc_hal_task_stack + NFC_HAL_TASK_STACK_SIZE),
+ sizeof(nfc_hal_task_stack), NULL, NULL);
+
+#ifndef NFC_HAL_SHARED_GKI
+ /* Start GKI scheduler (not needed if using shared NFC/HAL GKI resources) */
+ GKI_run (0);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcTerminate
+**
+** Description Called to terminate NFC HAL
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcTerminate(void)
+{
+ HAL_TRACE_API0 ("HAL_NfcTerminate ()");
+}
+
+
+/*******************************************************************************
+**
+** Function HAL_NfcOpen
+**
+** Description Open transport and intialize the NFCC, and
+** Register callback for HAL event notifications,
+**
+** HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcOpen (tHAL_NFC_CBACK *p_hal_cback, tHAL_NFC_DATA_CBACK *p_data_cback)
+{
+ HAL_TRACE_API0 ("HAL_NfcOpen ()");
+
+ /* Only handle if HAL is not opened (stack cback is NULL) */
+ if (p_hal_cback)
+ {
+ nfc_hal_dm_init ();
+ nfc_hal_cb.p_stack_cback = p_hal_cback;
+ nfc_hal_cb.p_data_cback = p_data_cback;
+
+ /* Send startup event to NFC_HAL_TASK */
+ GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_INITIALIZE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcClose
+**
+** Description Prepare for shutdown. A HAL_CLOSE_DONE_EVENT will be
+** reported when complete.
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcClose (void)
+{
+ HAL_TRACE_API0 ("HAL_NfcClose ()");
+
+ /* Only handle if HAL is opened (stack cback is not-NULL) */
+ if (nfc_hal_cb.p_stack_cback)
+ {
+ /* Send shutdown event to NFC_HAL_TASK */
+ GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_TERMINATE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcCoreInitialized
+**
+** Description Called after the CORE_INIT_RSP is received from the NFCC.
+** At this time, the HAL can do any chip-specific configuration,
+** and when finished signal the libnfc-nci with event
+** HAL_POST_INIT_DONE.
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcCoreInitialized (UINT8 *p_core_init_rsp_params)
+{
+ NFC_HDR *p_msg;
+ UINT16 size;
+
+ HAL_TRACE_API0 ("HAL_NfcCoreInitialized ()");
+
+ /* NCI payload len + NCI header size */
+ size = p_core_init_rsp_params[2] + NCI_MSG_HDR_SIZE;
+
+ /* Send message to NFC_HAL_TASK */
+ if ((p_msg = (NFC_HDR *)GKI_getbuf ((UINT16)(size + NFC_HDR_SIZE))) != NULL)
+ {
+ p_msg->event = NFC_HAL_EVT_POST_CORE_RESET;
+ p_msg->offset = 0;
+ p_msg->len = size;
+ p_msg->layer_specific = 0;
+ memcpy ((UINT8 *)(p_msg + 1) + p_msg->offset, p_core_init_rsp_params, size);
+
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcWrite
+**
+** Description Send an NCI control message or data packet to the
+** transport. If an NCI command message exceeds the transport
+** size, HAL is responsible for fragmenting it, Data packets
+** must be of the correct size.
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcWrite (UINT16 data_len, UINT8 *p_data)
+{
+ NFC_HDR *p_msg;
+ UINT8 mt;
+
+ HAL_TRACE_API0 ("HAL_NfcWrite ()");
+
+ if (data_len > (NCI_MAX_CTRL_SIZE + NCI_MSG_HDR_SIZE))
+ {
+ HAL_TRACE_ERROR1 ("HAL_NfcWrite (): too many bytes (%d)", data_len);
+ return;
+ }
+
+ /* Send message to NFC_HAL_TASK */
+ if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ p_msg->event = NFC_HAL_EVT_TO_NFC_NCI;
+ p_msg->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+ p_msg->len = data_len;
+ memcpy ((UINT8 *)(p_msg+1) + p_msg->offset, p_data, data_len);
+
+ /* Check if message is a command or data */
+ mt = (*(p_data) & NCI_MT_MASK) >> NCI_MT_SHIFT;
+ p_msg->layer_specific = (mt == NCI_MT_CMD) ? NFC_HAL_WAIT_RSP_CMD : 0;
+
+
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcPreDiscover
+**
+** Description Perform any vendor-specific pre-discovery actions (if needed)
+** If any actions were performed TRUE will be returned, and
+** HAL_PRE_DISCOVER_DONE_EVENT will notify when actions are
+** completed.
+**
+** Returns TRUE if vendor-specific pre-discovery actions initialized
+** FALSE if no vendor-specific pre-discovery actions are needed.
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPreDiscover (void)
+{
+ BOOLEAN status = FALSE;
+
+ NFC_HDR *p_msg;
+
+ HAL_TRACE_API0 ("HAL_NfcPreDiscover ()");
+ if (nfc_hal_cb.pre_discover_done == FALSE)
+ {
+ nfc_hal_cb.pre_discover_done = TRUE;
+ if (p_nfc_hal_pre_discover_cfg && *p_nfc_hal_pre_discover_cfg)
+ {
+ status = TRUE;
+ /* Send message to NFC_HAL_TASK */
+ if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ p_msg->event = NFC_HAL_EVT_PRE_DISCOVER;
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+ }
+ }
+
+ HAL_TRACE_API1 ("HAL_NfcPreDiscover status:%d", status);
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcControlGranted
+**
+** Description Grant control to HAL control for sending NCI commands.
+**
+** Call in response to HAL_REQUEST_CONTROL_EVENT.
+**
+** Must only be called when there are no NCI commands pending.
+**
+** HAL_RELEASE_CONTROL_EVENT will notify when HAL no longer
+** needs control of NCI.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcControlGranted (void)
+{
+ NFC_HDR *p_msg;
+ HAL_TRACE_API0 ("HAL_NfcControlGranted ()");
+
+ /* Send message to NFC_HAL_TASK */
+ if ((p_msg = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ p_msg->event = NFC_HAL_EVT_CONTROL_GRANTED;
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcPowerCycle
+**
+** Description Restart NFCC by power cyle
+**
+** HAL_OPEN_CPLT_EVT will notify when operation is complete.
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcPowerCycle (void)
+{
+ HAL_TRACE_API0 ("HAL_NfcPowerCycle ()");
+
+ /* Only handle if HAL is opened (stack cback is not-NULL) */
+ if (nfc_hal_cb.p_stack_cback)
+ {
+ /* Send power cycle event to NFC_HAL_TASK */
+ GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_POWER_CYCLE);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcGetMaxNfcee
+**
+** Description Retrieve the maximum number of NFCEEs supported by NFCC
+**
+** Returns the maximum number of NFCEEs supported by NFCC
+**
+*******************************************************************************/
+UINT8 HAL_NfcGetMaxNfcee (void)
+{
+ HAL_TRACE_API1 ("HAL_NfcGetMaxNfcee: %d",nfc_hal_cb.max_ee);
+ return nfc_hal_cb.max_ee;
+}
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
new file mode 100644
index 0000000..aaae0a4
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_brcm.c
@@ -0,0 +1,30 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * This file contains function of the NFC unit to receive/process NFC VS
+ * commands.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_int.h"
+#include "userial.h"
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
new file mode 100644
index 0000000..9e200f8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm.c
@@ -0,0 +1,1289 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * Vendor-specific handler for DM events
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "upio.h"
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+#define NFC_HAL_I93_RW_CFG_LEN (5)
+#define NFC_HAL_I93_RW_CFG_PARAM_LEN (3)
+#define NFC_HAL_I93_AFI (0)
+#define NFC_HAL_I93_ENABLE_SMART_POLL (1)
+
+static UINT8 nfc_hal_dm_i93_rw_cfg[NFC_HAL_I93_RW_CFG_LEN] =
+{
+ NCI_PARAM_ID_I93_DATARATE,
+ NFC_HAL_I93_RW_CFG_PARAM_LEN,
+ NFC_HAL_I93_FLAG_DATA_RATE, /* Bit0:Sub carrier, Bit1:Data rate, Bit4:Enable/Disable AFI */
+ NFC_HAL_I93_AFI, /* AFI if Bit 4 is set in the flag byte */
+ NFC_HAL_I93_ENABLE_SMART_POLL /* Bit0:Enable/Disable smart poll */
+};
+
+static UINT8 nfc_hal_dm_set_fw_fsm_cmd[NCI_MSG_HDR_SIZE + 1] =
+{
+ NCI_MTS_CMD|NCI_GID_PROP,
+ NCI_MSG_SET_FWFSM,
+ 0x01,
+ 0x00,
+};
+#define NCI_SET_FWFSM_OFFSET_ENABLE 3
+
+#define NCI_PROP_PARAM_SIZE_XTAL_INDEX 3 /* length of parameters in XTAL_INDEX CMD */
+#ifndef NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX
+#define NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX 20
+#endif
+
+const UINT8 nfc_hal_dm_get_build_info_cmd[NCI_MSG_HDR_SIZE] =
+{
+ NCI_MTS_CMD|NCI_GID_PROP,
+ NCI_MSG_GET_BUILD_INFO,
+ 0x00
+};
+#define NCI_BUILD_INFO_OFFSET_HWID 25 /* HW ID offset in build info RSP */
+
+const UINT8 nfc_hal_dm_get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+{
+ NCI_MTS_CMD|NCI_GID_PROP,
+ NCI_MSG_GET_PATCH_VERSION,
+ 0x00
+};
+#define NCI_PATCH_INFO_VERSION_LEN 16 /* Length of patch version string in PATCH_INFO */
+
+/*****************************************************************************
+** Extern function prototypes
+*****************************************************************************/
+extern UINT8 *p_nfc_hal_dm_lptd_cfg;
+extern UINT8 *p_nfc_hal_dm_pll_325_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_cfg;
+extern UINT8 *p_nfc_hal_dm_start_up_vsc_cfg;
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+extern tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem;
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_set_config
+**
+** Description Send NCI config items to NFCC
+**
+** Returns tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS nfc_hal_dm_set_config (UINT8 tlv_size,
+ UINT8 *p_param_tlvs,
+ tNFC_HAL_NCI_CBACK *p_cback)
+{
+ UINT8 *p_buff, *p;
+ UINT8 num_param = 0, param_len, rem_len, *p_tlv;
+ UINT16 cmd_len = NCI_MSG_HDR_SIZE + tlv_size + 1;
+ tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+ if ((tlv_size == 0)||(p_param_tlvs == NULL))
+ {
+ return status;
+ }
+
+ if ((p_buff = (UINT8 *) GKI_getbuf ((UINT16)(NCI_MSG_HDR_SIZE + tlv_size))) != NULL)
+ {
+ p = p_buff;
+
+ NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1 (p, NCI_MSG_CORE_SET_CONFIG);
+ UINT8_TO_STREAM (p, (UINT8) (tlv_size + 1));
+
+ rem_len = tlv_size;
+ p_tlv = p_param_tlvs;
+ while (rem_len > 1)
+ {
+ num_param++; /* number of params */
+
+ p_tlv ++; /* param type */
+ param_len = *p_tlv++; /* param length */
+
+ rem_len -= 2; /* param type and length */
+ if (rem_len >= param_len)
+ {
+ rem_len -= param_len;
+ p_tlv += param_len; /* next param_type */
+
+ if (rem_len == 0)
+ {
+ status = HAL_NFC_STATUS_OK;
+ break;
+ }
+ }
+ else
+ {
+ /* error found */
+ break;
+ }
+ }
+
+ if (status == HAL_NFC_STATUS_OK)
+ {
+ UINT8_TO_STREAM (p, num_param);
+ ARRAY_TO_STREAM (p, p_param_tlvs, tlv_size);
+
+ nfc_hal_dm_send_nci_cmd (p_buff, cmd_len, p_cback);
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_dm_set_config ():Bad TLV");
+ }
+
+ GKI_freebuf (p_buff);
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_set_fw_fsm
+**
+** Description Enable or disable FW FSM
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_fw_fsm (BOOLEAN enable, tNFC_HAL_NCI_CBACK *p_cback)
+{
+ if (enable)
+ nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x01; /* Enable, default is disabled */
+ else
+ nfc_hal_dm_set_fw_fsm_cmd[NCI_SET_FWFSM_OFFSET_ENABLE] = 0x00; /* Disable */
+
+ nfc_hal_dm_send_nci_cmd (nfc_hal_dm_set_fw_fsm_cmd, NCI_MSG_HDR_SIZE + 1, p_cback);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_config_nfcc_cback
+**
+** Description Callback for NCI vendor specific command complete
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+ if (nfc_hal_cb.dev_cb.next_dm_config == NFC_HAL_DM_CONFIG_NONE)
+ {
+ nfc_hal_hci_enable ();
+ }
+ else
+ {
+ nfc_hal_dm_config_nfcc ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_send_startup_vsc
+**
+** Description Send VS command before NFA start-up
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_dm_send_startup_vsc (void)
+{
+ UINT8 *p, *p_end;
+ UINT16 len;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_dm_send_startup_vsc ()");
+
+ /* VSC must have NCI header at least */
+ if (nfc_hal_cb.dev_cb.next_startup_vsc + NCI_MSG_HDR_SIZE - 1 <= *p_nfc_hal_dm_start_up_vsc_cfg)
+ {
+ p = p_nfc_hal_dm_start_up_vsc_cfg + nfc_hal_cb.dev_cb.next_startup_vsc;
+ len = *(p + 2);
+ p_end = p + NCI_MSG_HDR_SIZE - 1 + len;
+
+ if (p_end <= p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+ {
+ /* move to next VSC */
+ nfc_hal_cb.dev_cb.next_startup_vsc += NCI_MSG_HDR_SIZE + len;
+
+ /* if this is last VSC */
+ if (p_end == p_nfc_hal_dm_start_up_vsc_cfg + *p_nfc_hal_dm_start_up_vsc_cfg)
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+
+ nfc_hal_dm_send_nci_cmd (p, (UINT16)(NCI_MSG_HDR_SIZE + len), nfc_hal_dm_config_nfcc_cback);
+ return;
+ }
+ }
+
+ HAL_TRACE_ERROR0 ("nfc_hal_dm_send_startup_vsc (): Bad start-up VSC");
+
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_config_nfcc
+**
+** Description Send VS config before NFA start-up
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_config_nfcc (void)
+{
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_config_nfcc (): next_dm_config = %d", nfc_hal_cb.dev_cb.next_dm_config);
+
+ if ((p_nfc_hal_dm_lptd_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_LPTD))
+ {
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_PLL_325;
+
+ if (nfc_hal_dm_set_config (p_nfc_hal_dm_lptd_cfg[0],
+ &p_nfc_hal_dm_lptd_cfg[1],
+ nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+ {
+ return;
+ }
+ else
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+ return;
+ }
+ }
+
+ if ((p_nfc_hal_dm_pll_325_cfg) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_PLL_325))
+ {
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP;
+
+ if (nfc_hal_dm_set_config (NFC_HAL_PLL_325_SETCONFIG_PARAM_LEN,
+ p_nfc_hal_dm_pll_325_cfg,
+ nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+ {
+ return;
+ }
+ else
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+ return;
+ }
+ }
+
+ if ((p_nfc_hal_dm_start_up_cfg[0]) && (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP))
+ {
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_I93_DATA_RATE;
+ if (nfc_hal_dm_set_config (p_nfc_hal_dm_start_up_cfg[0],
+ &p_nfc_hal_dm_start_up_cfg[1],
+ nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+ {
+ return;
+ }
+ else
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+ return;
+ }
+ }
+
+#if (NFC_HAL_I93_FLAG_DATA_RATE == NFC_HAL_I93_FLAG_DATA_RATE_HIGH)
+ if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_I93_DATA_RATE)
+ {
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_FW_FSM;
+ if (nfc_hal_dm_set_config (NFC_HAL_I93_RW_CFG_LEN,
+ nfc_hal_dm_i93_rw_cfg,
+ nfc_hal_dm_config_nfcc_cback) == HAL_NFC_STATUS_OK)
+ {
+ return;
+ }
+ else
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
+ return;
+ }
+ }
+#endif
+
+ /* FW FSM is disabled as default in NFCC */
+ if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_FW_FSM)
+ {
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_START_UP_VSC;
+ nfc_hal_dm_set_fw_fsm (NFC_HAL_DM_MULTI_TECH_RESP, nfc_hal_dm_config_nfcc_cback);
+ return;
+ }
+
+ if (nfc_hal_cb.dev_cb.next_dm_config <= NFC_HAL_DM_CONFIG_START_UP_VSC)
+ {
+ if (p_nfc_hal_dm_start_up_vsc_cfg && *p_nfc_hal_dm_start_up_vsc_cfg)
+ {
+ nfc_hal_dm_send_startup_vsc ();
+ return;
+ }
+ }
+
+ /* nothing to config */
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_NONE;
+ nfc_hal_dm_config_nfcc_cback (0, 0, NULL);
+}
+
+/*******************************************************************************
+**
+** Function: nfc_hal_dm_get_xtal_index
+**
+** Description: Return Xtal index and frequency
+**
+** Returns: tNFC_HAL_XTAL_INDEX
+**
+*******************************************************************************/
+tNFC_HAL_XTAL_INDEX nfc_hal_dm_get_xtal_index (UINT32 brcm_hw_id, UINT16 *p_xtal_freq)
+{
+ UINT8 xx;
+
+ HAL_TRACE_DEBUG1("nfc_hal_dm_get_xtal_index() brcm_hw_id:0x%x", brcm_hw_id);
+
+ for (xx = 0; xx < nfc_post_reset_cb.dev_init_config.num_xtal_cfg; xx++)
+ {
+ if ((brcm_hw_id & BRCM_NFC_GEN_MASK)
+ == nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].brcm_hw_id)
+ {
+ *p_xtal_freq = nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_freq;
+ return (nfc_post_reset_cb.dev_init_config.xtal_cfg[xx].xtal_index);
+ }
+ }
+
+ /* if not found */
+ *p_xtal_freq = 0;
+ return (NFC_HAL_XTAL_INDEX_MAX);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_set_xtal_freq_index
+**
+** Description Set crystal frequency index
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_xtal_freq_index (void)
+{
+ UINT8 nci_brcm_xtal_index_cmd[NCI_MSG_HDR_SIZE + NCI_PROP_PARAM_MAX_SIZE_XTAL_INDEX];
+ UINT8 *p;
+ tNFC_HAL_XTAL_INDEX xtal_index;
+ UINT16 xtal_freq;
+ UINT8 cmd_len = NCI_PROP_PARAM_SIZE_XTAL_INDEX;
+ extern UINT8 *p_nfc_hal_dm_xtal_params_cfg;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_xtal_freq_index (): brcm_hw_id = 0x%x", nfc_hal_cb.dev_cb.brcm_hw_id);
+
+ xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+ if ((xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL) && (p_nfc_hal_dm_xtal_params_cfg))
+ {
+ cmd_len += p_nfc_hal_dm_xtal_params_cfg[0]; /* [0] is the length of extra params */
+ }
+
+ p = nci_brcm_xtal_index_cmd;
+ UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP));
+ UINT8_TO_STREAM (p, NCI_MSG_GET_XTAL_INDEX_FROM_DH);
+ UINT8_TO_STREAM (p, cmd_len);
+ UINT8_TO_STREAM (p, xtal_index);
+ UINT16_TO_STREAM (p, xtal_freq);
+ if (cmd_len > NCI_PROP_PARAM_SIZE_XTAL_INDEX)
+ {
+ memcpy (p, &p_nfc_hal_dm_xtal_params_cfg[1], p_nfc_hal_dm_xtal_params_cfg[0]);
+ }
+
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_XTAL_SET);
+
+ nfc_hal_dm_send_nci_cmd (nci_brcm_xtal_index_cmd, NCI_MSG_HDR_SIZE + cmd_len, NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_send_get_build_info_cmd
+**
+** Description Send NCI_MSG_GET_BUILD_INFO CMD
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_get_build_info_cmd (void)
+{
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_BUILD_INFO);
+
+ /* get build information to find out HW */
+ nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_build_info_cmd, NCI_MSG_HDR_SIZE, NULL);
+}
+/*******************************************************************************
+**
+** Function: nfc_hal_dm_adjust_hw_id
+**
+** Description: The hw_id of certain chips are shifted by 8 bits.
+** Adjust the hw_id before processing.
+**
+** Returns: Nothing
+**
+*******************************************************************************/
+static UINT32 nfc_hal_dm_adjust_hw_id (UINT32 hw_id)
+{
+ if ((hw_id & 0xF0000000) == 0)
+ hw_id <<= 4; /* shift hw_id by 4 bits to align w the format of most chips */
+ return hw_id;
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_check_xtal
+**
+** Description check if need to send xtal command.
+** If not, proceed to next step get_patch_version.
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_dm_check_xtal (void)
+{
+ UINT16 xtal_freq;
+ tNFC_HAL_XTAL_INDEX xtal_index;
+
+ /* if NFCC needs to set Xtal frequency before getting patch version */
+ xtal_index = nfc_hal_dm_get_xtal_index (nfc_hal_cb.dev_cb.brcm_hw_id, &xtal_freq);
+ if ((xtal_index < NFC_HAL_XTAL_INDEX_MAX) || (xtal_index == NFC_HAL_XTAL_INDEX_SPECIAL))
+ {
+ {
+ /* set Xtal index before getting patch version */
+ nfc_hal_dm_set_xtal_freq_index ();
+ return;
+ }
+ }
+
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO);
+
+ nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_pre_set_mem_cback
+**
+** Description This is pre-set mem complete callback.
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_dm_pre_set_mem_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+ UINT8 status = pData->p_param_buf[0];
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_pre_set_mem_cback: %d", status);
+ /* if it is completed */
+ if (status == HCI_SUCCESS)
+ {
+ if (!nfc_hal_dm_check_pre_set_mem())
+ {
+ return;
+ }
+ }
+ nfc_hal_dm_check_xtal();
+}
+
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_check_pre_set_mem
+**
+** Description Check if need to send the command.
+**
+** Returns TRUE if done.
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_check_pre_set_mem (void)
+{
+ UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH];
+ UINT8 *p;
+ UINT32 addr = 0;
+
+ if (p_nfc_hal_dm_pre_set_mem)
+ addr = p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].addr;
+ HAL_TRACE_DEBUG2 ("nfc_hal_dm_check_pre_set_mem: %d/0x%x", nfc_hal_cb.pre_set_mem_idx, addr);
+ if (addr == 0)
+ {
+ return TRUE;
+ }
+ p = cmd;
+
+ /* Add the command */
+ UINT16_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM);
+ UINT8_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM_LENGTH);
+
+ UINT8_TO_STREAM (p, HCI_BRCM_PRE_SET_MEM_TYPE);
+ UINT32_TO_STREAM (p, addr);
+ UINT8_TO_STREAM (p, 0);
+ UINT32_TO_STREAM (p, p_nfc_hal_dm_pre_set_mem[nfc_hal_cb.pre_set_mem_idx].data);
+ nfc_hal_cb.pre_set_mem_idx++;
+
+ nfc_hal_dm_send_bt_cmd (cmd,
+ NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_PRE_SET_MEM_LENGTH,
+ nfc_hal_dm_pre_set_mem_cback);
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_proc_msg_during_init
+**
+** Description Process NCI message while initializing NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 reset_reason, reset_type;
+ UINT8 mt, pbf, gid, op_code;
+ UINT8 *p_old, old_gid, old_oid, old_mt;
+ UINT8 u8;
+ tNFC_HAL_NCI_CBACK *p_cback = NULL;
+ UINT8 chipverlen;
+ UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+ UINT32 hw_id = 0;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state);
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+ NCI_MSG_PRS_HDR1 (p, op_code);
+
+ /* check if waiting for this response */
+ if ( (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD)
+ ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC) )
+ {
+ if (mt == NCI_MT_RSP)
+ {
+ p_old = nfc_hal_cb.ncit_cb.last_hdr;
+ NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid);
+ old_oid = ((*p_old) & NCI_OID_MASK);
+ /* make sure this is the RSP we are waiting for before updating the command window */
+ if ((old_gid == gid) && (old_oid == op_code))
+ {
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+ p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+ nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ }
+ }
+ }
+
+ if (gid == NCI_GID_CORE)
+ {
+ if (op_code == NCI_MSG_CORE_RESET)
+ {
+ if (mt == NCI_MT_NTF)
+ {
+ if ( (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+ ||(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET) )
+ {
+ /*
+ ** Core reset ntf in the following cases;
+ ** 1) after power up (raising REG_PU)
+ ** 2) after setting xtal index
+ ** Start pre-initializing NFCC
+ */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer);
+ nfc_hal_dm_pre_init_nfcc ();
+ }
+ else
+ {
+ /* Core reset ntf after post-patch download, Call reset notification callback */
+ p++; /* Skip over param len */
+ STREAM_TO_UINT8 (reset_reason, p);
+ STREAM_TO_UINT8 (reset_type, p);
+ nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type);
+ }
+ }
+ }
+ else if (p_cback)
+ {
+ (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+ p_msg->len,
+ (UINT8 *) (p_msg + 1) + p_msg->offset);
+ }
+ }
+ else if (gid == NCI_GID_PROP) /* this is for download patch */
+ {
+ if (mt == NCI_MT_NTF)
+ op_code |= NCI_NTF_BIT;
+ else
+ op_code |= NCI_RSP_BIT;
+
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET)
+ {
+ if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH))
+ {
+ /* start timer in case that NFCC doesn't send RESET NTF after loading patch from NVM */
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_POST_XTAL_SET);
+
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+ ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+ }
+ }
+ else if ( (op_code == NFC_VS_GET_BUILD_INFO_EVT)
+ &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) )
+ {
+ p += NCI_BUILD_INFO_OFFSET_HWID;
+
+ STREAM_TO_UINT32 (hw_id, p);
+ nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id (hw_id);
+ HAL_TRACE_DEBUG2 ("brcm_hw_id: 0x%x -> 0x%x", hw_id, nfc_hal_cb.dev_cb.brcm_hw_id);
+
+ STREAM_TO_UINT8 (chipverlen, p);
+ memset (chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN);
+
+ STREAM_TO_ARRAY (chipverstr, p, chipverlen);
+
+ nfc_hal_hci_handle_build_info (chipverlen, chipverstr);
+ nfc_hal_cb.pre_set_mem_idx = 0;
+ if (!nfc_hal_dm_check_pre_set_mem())
+ {
+ /* pre-set mem started */
+ return;
+ }
+ nfc_hal_dm_check_xtal();
+ }
+ else if ( (op_code == NFC_VS_GET_PATCH_VERSION_EVT)
+ &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO) )
+ {
+ /* Store NVM info to control block */
+
+ /* Skip over rsp len */
+ p++;
+
+ /* Get project id */
+ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.project_id, p);
+
+ /* RFU */
+ p++;
+
+ /* Get chip version string */
+ STREAM_TO_UINT8 (u8, p);
+ if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN)
+ u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN;
+ memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8);
+ p += NCI_PATCH_INFO_VERSION_LEN;
+
+ /* Get major/minor version */
+ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_major, p);
+ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_minor, p);
+
+ /* Skip over max_size and patch_max_size */
+ p += 4;
+
+ /* Get current lpm patch size */
+ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.lpm_size, p);
+ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.fpm_size, p);
+
+ /* clear all flags which may be set during previous initialization */
+ nfc_hal_cb.nvm_cb.flags = 0;
+
+ /* Set patch present flag */
+ if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size))
+ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT;
+
+ /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+ STREAM_TO_UINT8 (u8, p);
+ if (u8)
+ {
+ /* LPM patch in NVM fails CRC check */
+ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD;
+ }
+
+
+ /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */
+ STREAM_TO_UINT8 (u8, p);
+ if (u8)
+ {
+ /* FPM patch in NVM fails CRC check */
+ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD;
+ }
+
+ /* Check if downloading patch to RAM only (no NVM) */
+ STREAM_TO_UINT8 (nfc_hal_cb.nvm_cb.nvm_type, p);
+ if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+ {
+ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM;
+ }
+
+ /* let platform update baudrate or download patch */
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE);
+ nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, nfc_hal_cb.nvm_cb.nvm_type);
+ }
+ else if (p_cback)
+ {
+ (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code),
+ p_msg->len,
+ (UINT8 *) (p_msg + 1) + p_msg->offset);
+ }
+ else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT)
+ {
+ HAL_TRACE_DEBUG0 ("signature!!");
+ nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code),
+ p_msg->len,
+ (UINT8 *) (p_msg + 1) + p_msg->offset);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_send_nci_cmd
+**
+** Description Send NCI command to NFCC while initializing BRCM NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_nci_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_NCI_CBACK *p_cback)
+{
+ NFC_HDR *p_buf;
+ UINT8 *ps;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_nci_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+ if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_dm_send_nci_cmd(): no command window");
+ return;
+ }
+
+ if ((p_buf = (NFC_HDR *)GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_VSC;
+
+ p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+ p_buf->event = NFC_HAL_EVT_TO_NFC_NCI;
+ p_buf->len = len;
+
+ memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+ /* Keep a copy of the command and send to NCI transport */
+
+ /* save the message header to double check the response */
+ ps = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ memcpy(nfc_hal_cb.ncit_cb.last_hdr, ps, NFC_HAL_SAVED_HDR_SIZE);
+ memcpy(nfc_hal_cb.ncit_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_HAL_SAVED_CMD_SIZE);
+
+ /* save the callback for NCI VSCs */
+ nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+ nfc_hal_nci_send_cmd (p_buf);
+
+ /* start NFC command-timeout timer */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+ ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_send_pend_cmd
+**
+** Description Send a command to NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_pend_cmd (void)
+{
+ NFC_HDR *p_buf = nfc_hal_cb.ncit_cb.p_pend_cmd;
+ UINT8 *p;
+
+ if (p_buf == NULL)
+ return;
+
+ /* check low power mode state */
+ if (!nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+ {
+ return;
+ }
+
+ if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+ {
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+ DispHciCmd (p_buf);
+#endif
+
+ /* save the message header to double check the response */
+ p = (UINT8 *)(p_buf + 1) + p_buf->offset;
+ memcpy(nfc_hal_cb.ncit_cb.last_hdr, p, NFC_HAL_SAVED_HDR_SIZE);
+
+ /* add packet type for BT message */
+ p_buf->offset--;
+ p_buf->len++;
+
+ p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+ *p = HCIT_TYPE_COMMAND;
+
+ USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+ GKI_freebuf (p_buf);
+ nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+
+ /* start NFC command-timeout timer */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer, (UINT16)(NFC_HAL_TTYPE_NCI_WAIT_RSP),
+ ((UINT32) NFC_HAL_CMD_TOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_send_bt_cmd
+**
+** Description Send BT message to NFCC while initializing BRCM NFCC
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_send_bt_cmd (const UINT8 *p_data, UINT16 len, tNFC_HAL_BTVSC_CPLT_CBACK *p_cback)
+{
+ NFC_HDR *p_buf;
+ char buff[300];
+ char tmp[4];
+ buff[0] = 0;
+ int i;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_send_bt_cmd (): nci_wait_rsp = 0x%x", nfc_hal_cb.ncit_cb.nci_wait_rsp);
+
+ for (i = 0; i < len; i++)
+ {
+ sprintf (tmp, "%02x ", p_data[i]);
+ strcat(buff, tmp);
+ }
+ HAL_TRACE_DEBUG2 ("nfc_hal_dm_send_bt_cmd (): HCI Write (%d bytes): %s", len, buff);
+
+ if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_dm_send_bt_cmd(): no command window");
+ return;
+ }
+
+ if ((p_buf = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_PROP;
+
+ p_buf->offset = NFC_HAL_NCI_MSG_OFFSET_SIZE;
+ p_buf->len = len;
+
+ memcpy ((UINT8*) (p_buf + 1) + p_buf->offset, p_data, len);
+
+ /* save the callback for NCI VSCs) */
+ nfc_hal_cb.ncit_cb.p_vsc_cback = (void *)p_cback;
+
+ nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf;
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+ {
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_CONTROL_DONE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_REQUEST_CONTROL_EVT, HAL_NFC_STATUS_OK);
+ return;
+ }
+
+ nfc_hal_dm_send_pend_cmd();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_set_nfc_wake
+**
+** Description Set NFC_WAKE line
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_set_nfc_wake (UINT8 cmd)
+{
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_set_nfc_wake () %s",
+ (cmd == NFC_HAL_ASSERT_NFC_WAKE ? "ASSERT" : "DEASSERT"));
+
+ /*
+ ** nfc_wake_active_mode cmd result of voltage on NFC_WAKE
+ **
+ ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_ASSERT_NFC_WAKE (0) pull down NFC_WAKE (GND)
+ ** NFC_HAL_LP_ACTIVE_LOW (0) NFC_HAL_DEASSERT_NFC_WAKE (1) pull up NFC_WAKE (VCC)
+ ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_ASSERT_NFC_WAKE (0) pull up NFC_WAKE (VCC)
+ ** NFC_HAL_LP_ACTIVE_HIGH (1) NFC_HAL_DEASSERT_NFC_WAKE (1) pull down NFC_WAKE (GND)
+ */
+
+ if (cmd == nfc_hal_cb.dev_cb.nfc_wake_active_mode)
+ UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_OFF); /* pull down NFC_WAKE */
+ else
+ UPIO_Set (UPIO_GENERAL, NFC_HAL_LP_NFC_WAKE_GPIO, UPIO_ON); /* pull up NFC_WAKE */
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_power_mode_execute
+**
+** Description If snooze mode is enabled in full power mode,
+** Assert NFC_WAKE before sending data
+** Deassert NFC_WAKE when idle timer expires
+**
+** Returns TRUE if DH can send data to NFCC
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_dm_power_mode_execute (tNFC_HAL_LP_EVT event)
+{
+ BOOLEAN send_to_nfcc = FALSE;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_dm_power_mode_execute () event = %d", event);
+
+ if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+ {
+ if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+ {
+ /* if any transport activity */
+ if ( (event == NFC_HAL_LP_TX_DATA_EVT)
+ ||(event == NFC_HAL_LP_RX_DATA_EVT) )
+ {
+ /* if idle timer is not running */
+ if (nfc_hal_cb.dev_cb.lp_timer.in_use == FALSE)
+ {
+ nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+ }
+
+ /* start or extend idle timer */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+ ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+ else if (event == NFC_HAL_LP_TIMEOUT_EVT)
+ {
+ /* let NFCC go to snooze mode */
+ nfc_hal_dm_set_nfc_wake (NFC_HAL_DEASSERT_NFC_WAKE);
+ }
+ }
+
+ send_to_nfcc = TRUE;
+ }
+
+ return (send_to_nfcc);
+}
+
+/*******************************************************************************
+**
+** Function nci_brcm_lp_timeout_cback
+**
+** Description callback function for low power timeout
+**
+** Returns void
+**
+*******************************************************************************/
+static void nci_brcm_lp_timeout_cback (void *p_tle)
+{
+ HAL_TRACE_DEBUG0 ("nci_brcm_lp_timeout_cback ()");
+
+ nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TIMEOUT_EVT);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_pre_init_nfcc
+**
+** Description This function initializes Broadcom specific control blocks for
+** NCI transport
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_pre_init_nfcc (void)
+{
+ HAL_TRACE_DEBUG0 ("nfc_hal_dm_pre_init_nfcc ()");
+
+ /* if it was waiting for core reset notification after raising REG_PU */
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE)
+ {
+ nfc_hal_dm_send_get_build_info_cmd ();
+ }
+ /* if it was waiting for core reset notification after setting Xtal */
+ else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET)
+ {
+ {
+ /* Core reset ntf after xtal setting indicating NFCC loaded patch from NVM */
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_PATCH_INFO);
+
+ nfc_hal_dm_send_nci_cmd (nfc_hal_dm_get_patch_version_cmd, NCI_MSG_HDR_SIZE, NULL);
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_shutting_down_nfcc
+**
+** Description This function initializes Broadcom specific control blocks for
+** NCI transport
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_shutting_down_nfcc (void)
+{
+ HAL_TRACE_DEBUG0 ("nfc_hal_dm_shutting_down_nfcc ()");
+
+ nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_CLOSING;
+
+ /* reset low power mode variables */
+ if ( (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+ &&(nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE) )
+ {
+ nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+ }
+
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+
+ nfc_hal_cb.dev_cb.power_mode = NFC_HAL_POWER_MODE_FULL;
+ nfc_hal_cb.dev_cb.snooze_mode = NFC_HAL_LP_SNOOZE_MODE_NONE;
+
+ /* Stop all timers */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ nfc_hal_cb.hci_cb.hcp_conn_id = 0;
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+#endif
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_init
+**
+** Description This function initializes Broadcom specific control blocks for
+** NCI transport
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_dm_init (void)
+{
+ HAL_TRACE_DEBUG0 ("nfc_hal_dm_init ()");
+
+ nfc_hal_cb.dev_cb.lp_timer.p_cback = nci_brcm_lp_timeout_cback;
+
+ nfc_hal_cb.ncit_cb.nci_wait_rsp_timer.p_cback = nfc_hal_nci_cmd_timeout_cback;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ nfc_hal_cb.hci_cb.hci_timer.p_cback = nfc_hal_hci_timeout_cback;
+#endif
+
+ nfc_hal_cb.pre_discover_done = FALSE;
+
+ nfc_post_reset_cb.spd_nvm_detection_cur_count = 0;
+ nfc_post_reset_cb.spd_skip_on_power_cycle = FALSE;
+
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcDevInitDone
+**
+** Description Notify that pre-initialization of NFCC is complete
+**
+** Returns void
+**
+*******************************************************************************/
+void HAL_NfcPreInitDone (tHAL_NFC_STATUS status)
+{
+ HAL_TRACE_DEBUG1 ("HAL_NfcPreInitDone () status=%d", status);
+
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+
+ nfc_hal_main_pre_init_done (status);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcReInit
+**
+** Description This function is called to restart initialization after REG_PU
+** toggled because of failure to detect NVM type or download patchram.
+**
+** Note This function should be called only during the HAL init process
+**
+** Returns HAL_NFC_STATUS_OK if successfully initiated
+** HAL_NFC_STATUS_FAILED otherwise
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcReInit (void)
+{
+ tHAL_NFC_STATUS status = HAL_NFC_STATUS_FAILED;
+
+ HAL_TRACE_DEBUG1 ("HAL_NfcReInit () init st=0x%x", nfc_hal_cb.dev_cb.initializing_state);
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+ {
+ {
+ /* Wait for NFCC to enable - Core reset notification */
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+ /* NFCC Enable timeout */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+ ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+ }
+
+ status = HAL_NFC_STATUS_OK;
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_dm_set_snooze_mode_cback
+**
+** Description This is snooze update complete callback.
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_dm_set_snooze_mode_cback (tNFC_HAL_BTVSC_CPLT *pData)
+{
+ UINT8 status = pData->p_param_buf[0];
+ tHAL_NFC_STATUS hal_status;
+ tHAL_NFC_STATUS_CBACK *p_cback;
+
+ /* if it is completed */
+ if (status == HCI_SUCCESS)
+ {
+ /* update snooze mode */
+ nfc_hal_cb.dev_cb.snooze_mode = nfc_hal_cb.dev_cb.new_snooze_mode;
+
+ nfc_hal_dm_set_nfc_wake (NFC_HAL_ASSERT_NFC_WAKE);
+
+ if ( nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+ {
+ /* start idle timer */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.dev_cb.lp_timer, 0x00,
+ ((UINT32) NFC_HAL_LP_IDLE_TIMEOUT) * QUICK_TIMER_TICKS_PER_SEC / 1000);
+ }
+ else
+ {
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.dev_cb.lp_timer);
+ }
+ hal_status = HAL_NFC_STATUS_OK;
+ }
+ else
+ {
+ hal_status = HAL_NFC_STATUS_FAILED;
+ }
+
+ if (nfc_hal_cb.dev_cb.p_prop_cback)
+ {
+ p_cback = nfc_hal_cb.dev_cb.p_prop_cback;
+ nfc_hal_cb.dev_cb.p_prop_cback = NULL;
+ (*p_cback) (hal_status);
+ }
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcSetSnoozeMode
+**
+** Description Set snooze mode
+** snooze_mode
+** NFC_HAL_LP_SNOOZE_MODE_NONE - Snooze mode disabled
+** NFC_HAL_LP_SNOOZE_MODE_UART - Snooze mode for UART
+** NFC_HAL_LP_SNOOZE_MODE_SPI_I2C - Snooze mode for SPI/I2C
+**
+** idle_threshold_dh/idle_threshold_nfcc
+** Idle Threshold Host in 100ms unit
+**
+** nfc_wake_active_mode/dh_wake_active_mode
+** NFC_HAL_LP_ACTIVE_LOW - high to low voltage is asserting
+** NFC_HAL_LP_ACTIVE_HIGH - low to high voltage is asserting
+**
+** p_snooze_cback
+** Notify status of operation
+**
+** Returns tHAL_NFC_STATUS
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcSetSnoozeMode (UINT8 snooze_mode,
+ UINT8 idle_threshold_dh,
+ UINT8 idle_threshold_nfcc,
+ UINT8 nfc_wake_active_mode,
+ UINT8 dh_wake_active_mode,
+ tHAL_NFC_STATUS_CBACK *p_snooze_cback)
+{
+ UINT8 cmd[NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH];
+ UINT8 *p;
+
+ HAL_TRACE_API1 ("HAL_NfcSetSnoozeMode (): snooze_mode = %d", snooze_mode);
+
+ nfc_hal_cb.dev_cb.new_snooze_mode = snooze_mode;
+ nfc_hal_cb.dev_cb.nfc_wake_active_mode = nfc_wake_active_mode;
+ nfc_hal_cb.dev_cb.p_prop_cback = p_snooze_cback;
+
+ p = cmd;
+
+ /* Add the HCI command */
+ UINT16_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE);
+ UINT8_TO_STREAM (p, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+ memset (p, 0x00, HCI_BRCM_WRITE_SLEEP_MODE_LENGTH);
+
+ UINT8_TO_STREAM (p, snooze_mode); /* Sleep Mode */
+
+ UINT8_TO_STREAM (p, idle_threshold_dh); /* Idle Threshold Host */
+ UINT8_TO_STREAM (p, idle_threshold_nfcc); /* Idle Threshold HC */
+ UINT8_TO_STREAM (p, nfc_wake_active_mode); /* BT Wake Active Mode */
+ UINT8_TO_STREAM (p, dh_wake_active_mode); /* Host Wake Active Mode */
+
+ nfc_hal_dm_send_bt_cmd (cmd,
+ NFC_HAL_BT_HCI_CMD_HDR_SIZE + HCI_BRCM_WRITE_SLEEP_MODE_LENGTH,
+ nfc_hal_dm_set_snooze_mode_cback);
+ return (NCI_STATUS_OK);
+}
+
+
+
+
+
+
+
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
new file mode 100644
index 0000000..7c8e1e8
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_dm_cfg.c
@@ -0,0 +1,182 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * This file contains compile-time configurable constants for BRCM HAL
+ * modules
+ *
+ ******************************************************************************/
+#include "nfc_hal_int.h"
+#include "nci_defs.h"
+#include "nfc_brcm_defs.h"
+
+/* the SetConfig at start up*/
+UINT8 nfc_hal_start_up_cfg[] = {
+ /* TLV len */ 31,
+ /* B0 */ NCI_PARAM_ID_EMVCO_ENABLE,
+ /* B1 */ 1,
+ /* B2 */ 1, /* (1 = enable emvco mode, 0 = disable emvco mode) Default = 0.*/
+ /* B3 */ NCI_PARAM_ID_CONTINUE_MODE, /* NFCC will restart discovery after deactivated */
+ /* B4 */ 1,
+ /* B5 */ 1, /* (1 = enable, 0 = disable) Default = 0.*/
+ /* B6 */ NCI_PARAM_ID_RFU_CONFIG,
+ /* B7 */ 0x14,
+ /* B8 */ 0x00,
+ /* B9 */ 0x00,
+ /* B10*/ 0x00,
+ /* B11*/ 0x00,
+ /* B12*/ 0x0E,
+ /* B13*/ 0xE8,
+ /* B14*/ 0xF0,
+ /* B15*/ 0x55,
+ /* B16*/ 0x00,
+ /* B17*/ 0x0F, /* CE3 SO delay in sec */
+ /* B18*/ 0x00,
+ /* B19*/ 0x00,
+ /* B20*/ 0x00,
+ /* B21*/ 0x00,
+ /* B22*/ 0x00,
+ /* B23*/ 0x00,
+ /* B24*/ 0x00,
+ /* B25*/ 0x00,
+ /* B26*/ 0x00,
+ /* B27*/ 0x00,
+ /* B28*/ NCI_PARAM_ID_ACT_ORDER, /* polling sequence */
+ /* B29*/ 1,
+ /* B30*/ 1, /* (1 = active mode polling before passive, 0 = passive polling first) Default = 0.*/
+};
+
+UINT8 *p_nfc_hal_dm_start_up_cfg = (UINT8 *) nfc_hal_start_up_cfg;
+
+/* the VSCs at start up:
+ * The VSCs are specified in TLV format similar to nfa_start_up_cfg[]
+ * first byte is the TLV total len.
+ * B0 is the first T; i.e. the opcode for the VSC
+ * B1 is the len of the VSC parameters/payload
+ * */
+UINT8 nfc_hal_dm_start_up_vsc_cfg[] = {
+ /* TLV len */ 5,
+ /* B0 */ NCI_MTS_CMD|NCI_GID_PROP,
+ /* B1 */ NCI_MSG_FRAME_LOG,
+ /* B2 */ 2,
+ /* B3 */ 0, /* 1 to enable RF frames */
+ /* B4 */ 1 /* 1 to enable SWP frames */
+};
+
+UINT8 *p_nfc_hal_dm_start_up_vsc_cfg = NULL;
+
+/* the SetConfig at HAL_NfcPreDiscover. This is done once after HAL_NfcOpen */
+UINT8 nfc_hal_pre_discover_cfg[] = {
+ /* TLV len */ 0x0A,
+ /* B0 */ NCI_PARAM_ID_SWPCFG,
+ /* B1 */ 0x08,
+ /* B2 */ 0x01,
+ /* B3 */ 0x08,
+ /* B4 */ 0x00,
+ /* B5 */ 0x04,
+ /* B6 */ 0x80,
+ /* B7 */ 0xC3,
+ /* B8 */ 0xC9,
+ /* B9 */ 0x01
+};
+
+UINT8 *p_nfc_hal_pre_discover_cfg = NULL;
+
+/* LPTD parameters (LowPowerTagDetection)
+ * This is typical values for 20791B2
+ * The timing and threshold parameters used for a customer handset/hardware may vary
+ * depending on antenna and should be verified during a customer testing phase.
+ * the data fields without comments are too complicated. Please see ""
+ * */
+const UINT8 nfc_hal_dm_lptd_cfg[] =
+{
+ 21, /* total TLV length excluding itself */
+ NCI_PARAM_ID_TAGSNIFF_CFG, /* type */
+ 19, /* length */
+ 0x01, /* B0 enable: 0/disable, 1/enable*/
+ 0x02, /* B1 poll count: number of full power poll before starting lptd poll */
+ 0xFF, /* B2 sniff count lsb: number of lptd poll before switching to full power poll */
+ 0xFF, /* B3 sniff count msb */
+ 0x80, /* B4 threshold: Bigger thresholds give a smaller LPTD range but more immunity to false detections. Smaller thresholds increase LPTD range at the cost of greater likelihood of false detections. */
+ 0x40, /* B5 delay lsb: delay (us) to sampling power */
+ 0x00, /* B6 delay msb */
+ 0x40, /* B7 carrier threshold lsb */
+ 0x00, /* B8 carrier threshold msb */
+ 0x80, /* B9 mode: Bitwise variable used to enable various algorithm modes.*/
+ 0x80, /* B10 0-offset lsb */
+ 0x00, /* B11 0-offset msb */
+ 0x10, /* B12 field sense time lsb */
+ 0x00, /* B13 field sense time msb */
+ 0x00, /* B14 false detect threshold lsb: 0x00 to disable LPTD NTF. The number of false tag detections to resport LPTD NTF. */
+ 0x00, /* B15 false detect threshold msb. A false tag detect - full poll results in no tag being detected.*/
+ 0x75, /* B16 mode1; Bitwise variable used to enable various algorithm modes. */
+ 0x0D, /* B17 lptd ant cfg rx */
+ 0x30, /* B18 lptd rdr cfg ve */
+};
+
+UINT8 *p_nfc_hal_dm_lptd_cfg = (UINT8 *) &nfc_hal_dm_lptd_cfg[0];
+
+/*
+** NFCC has a table which has 9 XTAL frequencies: 9.6, 13, 16.2, 19.2, 24, 26, 38.4, 52 and 37.4 in MHz.
+** For these 9 xtal frequencies, host doesn't need to configure PLL325.
+** For 43341, host doesn't need to configure it at all.
+*/
+UINT8 *p_nfc_hal_dm_pll_325_cfg = NULL;
+
+/*
+** Proprietary pre-set is required, if not NULL.
+*/
+tNFC_HAL_DM_PRE_SET_MEM *p_nfc_hal_dm_pre_set_mem = NULL;
+
+tNFC_HAL_CFG nfc_hal_cfg =
+{
+ FALSE, /* set nfc_hal_prm_nvm_required to TRUE, if the platform wants to abort PRM process without NVM */
+ (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT, /* max time to wait for RESET NTF after setting REG_PU to high
+ ** If NFCC doesn't have NVM or cannot load patch from NVM without Xtal setting
+ ** then set it to short to optimize bootup time because NFCC cannot send RESET NTF.
+ ** Otherwise, it depends on NVM type and size of patchram.
+ */
+ (UINT16) NFC_HAL_NFCC_ENABLE_TIMEOUT /* max time to wait for RESET NTF after setting Xtal frequency
+ ** It depends on NVM type and size of patchram.
+ */
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ ,
+ TRUE, /* set nfc_hal_first_boot to TRUE, if platform enables NFC for the first time after bootup */
+ (HAL_NFC_HCI_UICC0_HOST | HAL_NFC_HCI_UICC1_HOST | HAL_NFC_HCI_UICC2_HOST) /* Set bit(s) for supported UICC(s) */
+#endif
+};
+
+tNFC_HAL_CFG *p_nfc_hal_cfg= (tNFC_HAL_CFG *) &nfc_hal_cfg;
+
+const UINT8 nfc_hal_dm_xtal_params_cfg [] =
+{
+ 8, /* length */
+ 0x00, /* B0 Rfpll_cfg_pll_xtal_div_2 */
+ 0x00, /* B1 Rfpll_cfg_pll_vcocal1_0_cal_ref_timeout */
+ 0x00, /* B2 Rfpll_cfg_pll_vcocal2_cal_count */
+ 0x00, /* B3 Rfpll_cfg_pll_vcocal3_cal_count */
+ 0x00, /* B4 Rfpll_cfg_pll_dsm_b_msb_wild_base */
+ 0x00, /* B5 Rfpll_cfg_pll_dsm_b_lsb_3_wild_base_3 */
+ 0x00, /* B6 Rfpll_cfg_pll_dsm_b_lsb_2_wild_base_2 */
+ 0x00 /* B7 Rfpll_cfg_pll_dsm_b_lsb_1_wild_base_1 */
+};
+
+/* By default, the XTAL command does not need these extra params. */
+UINT8 *p_nfc_hal_dm_xtal_params_cfg = NULL;
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
new file mode 100644
index 0000000..6b573d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci.c
@@ -0,0 +1,817 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * Vendor-specific handler for HCI events
+ *
+ ******************************************************************************/
+#include "gki.h"
+#include "nfc_hal_target.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+#include <string.h>
+
+
+#ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
+#define NFC_HAL_HCI_NV_READ_TIMEOUT 1000
+#endif
+
+#ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
+#define NFC_HAL_HCI_NFCC_RSP_TIMEOUT 3000
+#endif
+
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET 0x0C
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET 0x32
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET 0x7F
+#define NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET 0xB4
+
+#define NFC_HAL_HCI_PIPE_VALID_MASK 0x80
+
+#define NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL 0xFF
+#define NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL 0xFE
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_DM_BCM20791B3_STR[] = "20791B3";
+#define NFC_HAL_DM_BCM20791B3_STR_LEN (sizeof (NFC_HAL_DM_BCM20791B3_STR)-1)
+
+/* Version string for BCM20791B4 */
+const UINT8 NFC_HAL_DM_BCM20791B4_STR[] = "20791B4";
+#define NFC_HAL_DM_BCM20791B4_STR_LEN (sizeof (NFC_HAL_DM_BCM20791B4_STR)-1)
+
+/* Version string for BCM43341B0 */
+const UINT8 NFC_HAL_DM_BCM43341B0_STR[] = "43341B0";
+#define NFC_HAL_DM_BCM43341B0_STR_LEN (sizeof (NFC_HAL_DM_BCM43341B0_STR)-1)
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
+static void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void);
+static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
+static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_evt_hdlr
+**
+** Description Processing event for NFA HCI
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
+{
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_evt_hdlr ()");
+
+ switch (p_evt_data->hdr.event)
+ {
+ case NFC_HAL_HCI_RSP_NV_READ_EVT:
+ if ( (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf && (p_evt_data->nv_read.block == HC_F3_NV_BLOCK || p_evt_data->nv_read.block == HC_F4_NV_BLOCK || p_evt_data->nv_read.block == HC_F5_NV_BLOCK))
+ ||(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf && p_evt_data->nv_read.block == HC_F2_NV_BLOCK) )
+ {
+ nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
+ }
+ else
+ {
+ /* Invalid block or no buffer, Ignore */
+ HAL_TRACE_ERROR1 ("nfc_hal_hci_evt_hdlr: No buffer for handling read NV block: 0x%02x", p_evt_data->nv_read.block);
+ }
+ break;
+
+ case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
+ /* NV Ram write completed - nothing to do... */
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_enable
+**
+** Description Program nv data on to controller
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_hci_enable (void)
+{
+
+ UINT8 *p_hci_netwk_cmd;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_enable ()");
+
+ if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE)
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for NVM Type: 0x%02x", nfc_hal_cb.nvm_cb.nvm_type);
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+ return;
+ }
+
+ if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+ {
+ p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+ GKI_freebuf (p_hci_netwk_cmd);
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+ }
+
+ if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+ {
+ p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+ GKI_freebuf (p_hci_netwk_cmd);
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+ }
+
+ if ( (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+ ||((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) && ((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM)))
+ ||(p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST) )
+ {
+ if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+ }
+ else
+ {
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+ nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
+ if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST)
+ {
+ memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+ nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+ }
+ else
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_enable (): Skip send F3 HCI NETWK CMD for UICC Mask: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support);
+ nfc_hal_hci_set_next_hci_netwk_config (HC_F3_NV_BLOCK);
+ }
+
+ }
+ }
+ else
+ {
+ HAL_TRACE_DEBUG2 ("nfc_hal_hci_enable (): No HCI NETWK CMD to send for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+ nfc_hal_hci_set_next_hci_netwk_config (HC_F2_NV_BLOCK);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_handle_build_info
+**
+** Description handle build info evt
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_build_info (UINT8 chipverlen, UINT8 *p_chipverstr)
+{
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_build_info ()");
+
+ if ((chipverlen == NFC_HAL_DM_BCM20791B3_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B3_STR, p_chipverstr, NFC_HAL_DM_BCM20791B3_STR_LEN) == 0))
+ {
+ /* BCM2079B3 FW - eSE restarted for patch download */
+ nfc_hal_cb.hci_cb.hci_fw_workaround = TRUE;
+ nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = TRUE;
+ }
+ else if ( ((chipverlen == NFC_HAL_DM_BCM20791B4_STR_LEN) && (memcmp (NFC_HAL_DM_BCM20791B4_STR, p_chipverstr, NFC_HAL_DM_BCM20791B4_STR_LEN) == 0))
+ ||((chipverlen == NFC_HAL_DM_BCM43341B0_STR_LEN) && (memcmp (NFC_HAL_DM_BCM43341B0_STR, p_chipverstr, NFC_HAL_DM_BCM43341B0_STR_LEN) == 0)) )
+ {
+ /* BCM43341B0/BCM2079B4 FW - eSE restarted for patch download */
+ nfc_hal_cb.hci_cb.hci_fw_workaround = TRUE;
+ nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+ }
+ else
+ {
+ /* BCM2079B5 FW - eSE not be restarted for patch download from UICC */
+ nfc_hal_cb.hci_cb.hci_fw_workaround = FALSE;
+ nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = FALSE;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_handle_hci_netwk_info
+**
+** Description Handler function for HCI Network Notification
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
+{
+ UINT8 *p = p_data;
+ UINT16 data_len;
+ UINT8 target_handle = 0;
+ UINT8 hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+ UINT8 block = 0;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info ()");
+
+ /* skip NCI header byte0 (MT,GID), byte1 (OID) */
+ p += 2;
+
+ STREAM_TO_UINT8 (data_len, p);
+ target_handle = *(UINT8 *) p;
+
+ if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
+ {
+ /* Correct the session id assigned by DH */
+ *(p+1) = nfc_hal_cb.hci_cb.dh_session_id[0];
+ nfc_hal_nv_co_write (p, data_len, HC_F2_NV_BLOCK);
+ return;
+ }
+
+ if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
+ {
+ block = HC_F3_NV_BLOCK;
+ }
+ else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
+ {
+ block = HC_F4_NV_BLOCK;
+ }
+ else if (target_handle == NFC_HAL_HCI_UICC2_TARGET_HANDLE)
+ {
+ block = HC_F5_NV_BLOCK;
+ }
+ else
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Invalid Target handle: 0x%02x", target_handle);
+ return;
+ }
+
+ if ( (!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd)
+ ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+ ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+ ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK)
+ ||(p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] & NFC_HAL_HCI_PIPE_VALID_MASK) )
+ {
+ /* HCI Network notification received for UICC0/UICC1/UICC2, Update nv data */
+ nfc_hal_nv_co_write (p, data_len, block);
+ }
+ else
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
+ hci_netwk_cmd[0] = target_handle;
+ memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+ nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh
+**
+** Description Fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (void)
+{
+ NFC_HDR *p_msg;
+ UINT8 *p, *ps;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (): Fake ADM_NOTIFY_ALL_PIPE_CLEARED (0x%02x) from HAL", NFC_HAL_HCI_HOST_ID_UICC1);
+
+ /* Start of new message. Allocate a buffer for message */
+ if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ /* Initialize NFC_HDR */
+ p_msg->len = NCI_DATA_HDR_SIZE + 0x03;
+ p_msg->event = 0;
+ p_msg->offset = 0;
+ p_msg->layer_specific = 0;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ ps = p;
+ NCI_DATA_BLD_HDR (p, nfc_hal_cb.hci_cb.hcp_conn_id, 0x03);
+ /* HCP header with ADMIN pipe id and chaining bit set */
+ *p++ = ((1 << 0x07) | (NFC_HAL_HCI_ADMIN_PIPE & 0x7F));
+ /* HCP Message header with Command type instruction and ADM_NOTIFY_ALL_PIPE_CLEARED command */
+ *p++ = ((NFC_HAL_HCI_COMMAND_TYPE << 6) | (NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED & 0x3F));
+ /* HCP Data with UICC1 host id */
+ *p = NFC_HAL_HCI_HOST_ID_UICC1;
+
+#ifdef DISP_NCI
+ DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+ nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("Unable to allocate buffer for faking ADM_NOTIFY_ALL_PIPE_CLEARED cmd from HAL to stack");
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_handle_hcp_pkt_to_hc
+**
+** Description Handle HCP Packet from NFC task to Host Controller
+**
+** Returns FALSE to send the packet to host controller
+** TRUE to drop the packet and fake credit ntf for hcp connection
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_hci_handle_hcp_pkt_to_hc (UINT8 *p_data)
+{
+ UINT8 chaining_bit;
+ UINT8 pipe;
+ UINT8 type;
+ UINT8 inst;
+ UINT8 index;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_to_hc ()");
+
+ chaining_bit = ((*p_data) >> 0x07) & 0x01;
+ pipe = (*p_data++) & 0x7F;
+
+ if ( (chaining_bit)
+ &&(pipe == NFC_HAL_HCI_ADMIN_PIPE) )
+ {
+ type = ((*p_data) >> 0x06) & 0x03;
+
+ if (type == NFC_HAL_HCI_COMMAND_TYPE)
+ {
+ inst = (*p_data++ & 0x3F);
+ if (inst == NFC_HAL_HCI_ANY_GET_PARAMETER)
+ {
+ index = *(p_data++);
+ if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+ {
+ /* Set flag to modify session id[0] on response
+ * from host controller to set session id cmd
+ */
+ nfc_hal_cb.hci_cb.update_session_id = TRUE;
+ }
+ }
+ else if (inst == NFC_HAL_HCI_ANY_SET_PARAMETER)
+ {
+ index = *(p_data++);
+ if (index == NFC_HAL_HCI_WHITELIST_INDEX)
+ {
+ if ( (nfc_hal_cb.hci_cb.hci_fw_workaround)
+ &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC) )
+ {
+ /* Set flag to fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task after
+ * response from host controller to set whitelist cmd
+ */
+ nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = TRUE;
+ }
+ }
+ else if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX)
+ {
+ nfc_hal_cb.hci_cb.dh_session_id[0] = *p_data;
+ if (p_nfc_hal_cfg->nfc_hal_first_boot)
+ *p_data = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+ else
+ *p_data = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+ }
+ }
+ }
+ else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+ {
+ if ( (nfc_hal_cb.hci_cb.hci_fw_workaround)
+ &&(nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)
+ &&(nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1) )
+ {
+ /* Got response to the fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd sent by HAL to nfc task */
+ nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = FALSE;
+ /* return TRUE to drop this hcp without forwarding to host controller */
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_handle_hcp_pkt_from_hc
+**
+** Description Handle HCP Packet from Host controller to Terminal Host
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_hcp_pkt_from_hc (UINT8 *p_data)
+{
+ UINT8 chaining_bit;
+ UINT8 pipe;
+ UINT8 type;
+ UINT8 inst;
+ UINT8 hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
+ UINT8 source_host;
+ UINT8 block = 0;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_handle_hcp_pkt_from_hc ()");
+
+ chaining_bit = ((*p_data) >> 0x07) & 0x01;
+ pipe = (*p_data++) & 0x7F;
+
+ if ( (chaining_bit)
+ &&(pipe == NFC_HAL_HCI_ADMIN_PIPE) )
+ {
+ type = ((*p_data) >> 0x06) & 0x03;
+
+ if (type == NFC_HAL_HCI_COMMAND_TYPE)
+ {
+ if (!nfc_hal_cb.hci_cb.hci_fw_workaround)
+ return;
+
+ inst = (*p_data++ & 0x3F);
+
+ if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
+ {
+ STREAM_TO_UINT8 (source_host, p_data);
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Received ADM_NOTIFY_ALL_PIPE_CLEARED command for UICC: 0x%02x", source_host);
+ if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
+ {
+ block = HC_F3_NV_BLOCK;
+ hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+ }
+ else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
+ {
+ block = HC_F4_NV_BLOCK;
+ hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+ }
+ else if (source_host == NFC_HAL_HCI_HOST_ID_UICC2)
+ {
+ block = HC_F5_NV_BLOCK;
+ hci_netwk_cmd[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
+ }
+
+ if (source_host >= NFC_HAL_HCI_HOST_ID_UICC0)
+ {
+ /* Reset Session ID */
+ memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+ nfc_hal_nv_co_write (hci_netwk_cmd, 1, block);
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv file for block: 0x%02x", block);
+ }
+ }
+ }
+ else if (type == NFC_HAL_HCI_RESPONSE_TYPE)
+ {
+ if (nfc_hal_cb.hci_cb.update_session_id)
+ {
+ nfc_hal_cb.hci_cb.update_session_id = FALSE;
+ inst = (*p_data++ & 0x3F);
+ if (inst == NFC_HAL_HCI_ANY_OK)
+ {
+ /* Correct the session id assigned by DH */
+ *p_data = nfc_hal_cb.hci_cb.dh_session_id[0];
+ }
+ }
+ else if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)
+ {
+ /* NVM Type is UICC and got response from host controller
+ * to Set whitelist command. Now fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to
+ * NFC Task and then forward the whitelist cmd response
+ */
+ nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh ();
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_handle_nv_read
+**
+** Description handler function for nv read complete event
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
+{
+ UINT8 *p;
+ UINT8 *p_hci_netwk_info = NULL;
+
+ HAL_TRACE_DEBUG3 ("nfc_hal_hci_handle_nv_read (): Block: [0x%02x], Status: [0x%02x], Size: [0x%04x]", block, status, size);
+
+ /* Stop timer as NVDATA Read Completed */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
+
+ switch (block)
+ {
+ case HC_F3_NV_BLOCK:
+ case HC_F4_NV_BLOCK:
+ case HC_F5_NV_BLOCK:
+ if ( (status != HAL_NFC_STATUS_OK)
+ ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE)
+ ||(size < NFC_HAL_HCI_MIN_NETWK_INFO_SIZE)
+ ||((nfc_hal_cb.hci_cb.hci_fw_workaround) && (block == HC_F4_NV_BLOCK) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)) )
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+ memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+ if (block == HC_F3_NV_BLOCK)
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
+ else if (block == HC_F4_NV_BLOCK)
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
+ else
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
+
+ memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
+ size = NFC_HAL_HCI_NETWK_INFO_SIZE;
+ }
+
+ p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
+ break;
+
+ case HC_F2_NV_BLOCK:
+ nfc_hal_cb.hci_cb.dh_session_id[0] = nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1];
+ if (p_nfc_hal_cfg->nfc_hal_first_boot)
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
+ else
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
+
+ if ( (status != HAL_NFC_STATUS_OK)
+ ||(size > NFC_HAL_HCI_DH_NETWK_INFO_SIZE)
+ ||(size < NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE) )
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration for block:0x%02x", block);
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[0] = NFC_HAL_HCI_DH_TARGET_HANDLE;
+ nfc_hal_cb.hci_cb.dh_session_id[0] = 0xFF;
+ memset (&nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[2], 0xFF, (NFC_HAL_HCI_SESSION_ID_LEN - 1));
+ memset ((nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_SESSION_ID_LEN + 1), 0, (NFC_HAL_HCI_DH_NETWK_INFO_SIZE - NFC_HAL_HCI_SESSION_ID_LEN - 1));
+ size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
+ p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE;
+ }
+ else
+ {
+ if ((nfc_hal_cb.hci_cb.hci_fw_workaround) && (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))
+ {
+ /* if NVM Type is UICC, then UICC1 will find session id mismatch when activated for patch download,
+ * and will remove pipes connected to DH even before DH is enabled, So DH will update NFCC
+ * control block by removing all dynamic pipes connected to UICC1 */
+
+ nfc_hal_hci_remove_dyn_pipe_to_uicc1 ();
+ size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
+ }
+ p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ p = p_hci_netwk_info;
+ /* Send HCI Network ntf command using nv data */
+ NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
+ NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
+ UINT8_TO_STREAM (p, (UINT8) size);
+
+ nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
+
+ nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_remove_dyn_pipe_to_uicc1
+**
+** Description Prepare hci network command read from nv file removing
+** all pipes connected to UICC1
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_remove_dyn_pipe_to_uicc1 (void)
+{
+ UINT8 *p, *np;
+ UINT8 num_dyn_pipes = 0, new_num_dyn_pipes = 0;
+ UINT8 xx;
+ UINT8 source_host, dest_host, pipe_id;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_remove_dyn_pipe_to_uicc1 ()");
+
+ p = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+ np = p;
+ num_dyn_pipes = *(p - 1);
+
+ for (xx = 0; xx < num_dyn_pipes; xx++,p += NFC_HAL_HCI_PIPE_INFO_SIZE)
+ {
+ source_host = *(UINT8 *) (p);
+ dest_host = *(UINT8 *) (p + 1);
+ pipe_id = *(UINT8 *) (p + 4);
+
+ if ((source_host != NFC_HAL_HCI_HOST_ID_UICC1) && (dest_host != NFC_HAL_HCI_HOST_ID_UICC1))
+ {
+ memcpy (np, p, NFC_HAL_HCI_PIPE_INFO_SIZE);
+ np += NFC_HAL_HCI_PIPE_INFO_SIZE;
+ new_num_dyn_pipes++;
+ }
+ }
+
+ memset ((UINT8 *) (np), 0, NFC_HAL_HCI_PIPE_INFO_SIZE * (20 - new_num_dyn_pipes));
+
+ /* Update number of pipes after removing pipes connected to UICC1 */
+ p = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf + NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
+ *(p - 1) = new_num_dyn_pipes;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_init_complete
+**
+** Description Notify VSC initialization is complete
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
+{
+ UINT8 *p_hci_netwk_cmd;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_init_complete (): Status: [0x%02x]", status);
+
+ if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
+ {
+ p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
+ GKI_freebuf (p_hci_netwk_cmd);
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
+ }
+
+ if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+ {
+ p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
+ GKI_freebuf (p_hci_netwk_cmd);
+ nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
+ }
+
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_set_next_hci_netwk_config
+**
+** Description set next hci network configuration
+**
+** Returns None
+**
+*******************************************************************************/
+void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
+{
+ UINT8 *p_hci_netwk_cmd;
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_hci_set_next_hci_netwk_config (): Block: [0x%02x]", block);
+
+ switch (block)
+ {
+ case HC_F3_NV_BLOCK:
+ if ( (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST)
+ &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
+ &&((!nfc_hal_cb.hci_cb.hci_fw_workaround) || (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM)) )
+ {
+ /* Send command to read nvram data for 0xF4 */
+ memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+ nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+ break;
+ }
+ HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F4 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+ case HC_F4_NV_BLOCK:
+ if ( (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)
+ &&(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf) )
+ {
+ /* Send command to read nvram data for 0xF5 */
+ memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
+ nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F5_NV_BLOCK);
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+ break;
+ }
+ HAL_TRACE_DEBUG2 ("nfc_hal_hci_set_next_hci_netwk_config (): Skip send F5 HCI NETWK CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x", p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
+
+ case HC_F5_NV_BLOCK:
+ if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+ }
+ else
+ {
+ nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
+ /* Send command to read nvram data for 0xF2 */
+ memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
+ nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_F2_NV_BLOCK);
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
+ }
+ break;
+
+ case HC_F2_NV_BLOCK:
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
+ break;
+
+ default:
+ HAL_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
+ /* Brcm initialization failed */
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_hci_vsc_cback
+**
+** Description process VS callback event from stack
+**
+** Returns none
+**
+*******************************************************************************/
+static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+ UINT8 *p_ret = NULL;
+ UINT8 status;
+
+ p_ret = p_data + NCI_MSG_HDR_SIZE;
+ status = *p_ret;
+
+ HAL_TRACE_DEBUG3 ("nfc_hal_hci_vsc_cback (): Event: [0x%02x], Data length: [0x%04x], Status: [0x%02x]", event, data_len, status);
+
+ if (event != NFC_VS_HCI_NETWK_RSP)
+ return;
+
+ if (status != HAL_NFC_STATUS_OK)
+ {
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+ return;
+ }
+
+ switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
+ {
+ case HC_F3_NV_BLOCK:
+ case HC_F4_NV_BLOCK:
+ case HC_F5_NV_BLOCK:
+ case HC_F2_NV_BLOCK:
+ nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
+ break;
+
+ default:
+ /* Ignore the event */
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_cmd_timeout_cback
+**
+** Description callback function for timeout
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_hci_timeout_cback (void *p_tle)
+{
+ TIMER_LIST_ENT *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
+
+ if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
+ nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
+ }
+}
+
+#endif
+
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
new file mode 100644
index 0000000..49236f9
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_hci_ci.c
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * This file contains the call-in functions for NFC HAL HCI
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "gki.h"
+#include "nfc_hal_api.h"
+#include "nfc_hal_int.h"
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+#include "nfc_hal_nv_ci.h"
+#include "nfc_hal_nv_co.h"
+
+/*******************************************************************************
+**
+** Function nfc_hal_nv_ci_read
+**
+** Description call-in function for non volatile memory read acess
+**
+** Returns none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_read (UINT16 num_bytes_read, tNFC_HAL_NV_CO_STATUS status, UINT8 block)
+{
+ tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+ /* Send message to NCIT task */
+ if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+ {
+ p_msg->nv_read.hdr.event = NFC_HAL_HCI_RSP_NV_READ_EVT;
+ p_msg->hdr.offset = 0;
+ p_msg->hdr.len = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+ p_msg->hdr.layer_specific = 0;
+
+ if ( (status == NFC_HAL_NV_CO_OK)
+ &&(num_bytes_read != 0) )
+ p_msg->nv_read.status = HAL_NFC_STATUS_OK;
+ else
+ p_msg->nv_read.status = HAL_NFC_STATUS_FAILED;
+
+ p_msg->nv_read.size = num_bytes_read;
+ p_msg->nv_read.block = block;
+
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nv_ci_write
+**
+** Description call-in function for non volatile memory write acess
+**
+** Returns none
+**
+*******************************************************************************/
+void nfc_hal_nv_ci_write (tNFC_HAL_NV_CO_STATUS status)
+{
+ tNFC_HAL_HCI_EVENT_DATA *p_msg;
+
+ if ((p_msg = (tNFC_HAL_HCI_EVENT_DATA *) GKI_getbuf (sizeof (tNFC_HAL_HCI_EVENT_DATA))) != NULL)
+ {
+ p_msg->nv_write.hdr.event = NFC_HAL_HCI_RSP_NV_WRITE_EVT;
+ p_msg->nv_write.hdr.offset = 0;
+ p_msg->nv_write.hdr.len = sizeof (tNFC_HAL_HCI_RSP_NV_READ_EVT);
+ p_msg->nv_write.hdr.layer_specific = 0;
+ p_msg->nv_write.status = HAL_NFC_STATUS_OK;
+
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+}
+
+#endif
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_main.c b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
new file mode 100644
index 0000000..d7fc5d5
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_main.c
@@ -0,0 +1,752 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * Functions for handling NFC HAL NCI Transport events
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "upio.h"
+
+/****************************************************************************
+** Definitions
+****************************************************************************/
+
+/* Default NFC HAL NCI port configuration */
+NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg =
+{
+ NFC_HAL_SHARED_TRANSPORT_ENABLED, /* bSharedTransport */
+ USERIAL_BAUD_115200, /* Baud rate */
+ USERIAL_FC_HW /* Flow control */
+};
+
+/* Control block for NFC HAL NCI transport */
+#if NFC_DYNAMIC_MEMORY == FALSE
+tNFC_HAL_CB nfc_hal_cb;
+#endif
+
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+/****************************************************************************
+** Internal function prototypes
+****************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data);
+static void nfc_hal_main_handle_terminate (void);
+static void nfc_hal_main_timeout_cback (void *p_tle);
+
+#if (NFC_HAL_DEBUG == TRUE)
+const char * const nfc_hal_init_state_str[] =
+{
+ "IDLE", /* Initialization is done */
+ "W4_XTAL_SET", /* Waiting for crystal setting rsp */
+ "POST_XTAL_SET", /* Waiting for reset ntf after xtal set */
+ "W4_NFCC_ENABLE", /* Waiting for reset ntf atter REG_PU up */
+ "W4_BUILD_INFO", /* Waiting for build info rsp */
+ "W4_PATCH_INFO", /* Waiting for patch info rsp */
+ "W4_APP_COMPL", /* Waiting for complete from application */
+ "W4_POST_INIT", /* Waiting for complete of post init */
+ "W4_CONTROL", /* Waiting for control release */
+ "W4_PREDISC", /* Waiting for complete of prediscover */
+ "CLOSING" /* Shutting down */
+};
+#endif
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_init
+**
+** Description This function initializes control block for NFC HAL
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfc_hal_main_init (void)
+{
+ /* Clear control block */
+ memset (&nfc_hal_cb, 0, sizeof (tNFC_HAL_CB));
+
+ nfc_hal_cb.ncit_cb.nci_ctrl_size = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
+ nfc_hal_cb.trace_level = NFC_HAL_INITIAL_TRACE_LEVEL;
+ nfc_hal_cb.timer.p_cback = nfc_hal_main_timeout_cback;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_open_transport
+**
+** Description Open transport and prepare for new incoming message;
+**
+** Returns nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_open_transport (void)
+{
+ tUSERIAL_OPEN_CFG open_cfg;
+
+ /* Initialize control block */
+ nfc_hal_cb.ncit_cb.rcv_state = NFC_HAL_RCV_IDLE_ST; /* to process packet type */
+
+ if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+ {
+ GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+ nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+ }
+
+ /* open transport */
+ open_cfg.fmt = (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
+ open_cfg.baud = nfc_hal_trans_cfg.userial_baud;
+ open_cfg.fc = nfc_hal_trans_cfg.userial_fc;
+ open_cfg.buf = USERIAL_BUF_BYTE;
+
+ USERIAL_Open (USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
+
+ {
+ /* Wait for NFCC to enable - Core reset notification */
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
+
+ /* NFCC Enable timeout */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
+ ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfa_hal_pre_discover_done_cback
+**
+** Description Pre-discovery CFG is sent.
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfa_hal_pre_discover_done_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
+}
+
+/*******************************************************************************
+**
+** Function nfa_hal_send_pre_discover_cfg
+**
+** Description sending Pre-discovery CFG
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfa_hal_send_pre_discover_cfg (void)
+{
+ if (nfc_hal_dm_set_config (p_nfc_hal_pre_discover_cfg [0],
+ &p_nfc_hal_pre_discover_cfg[1],
+ nfa_hal_pre_discover_done_cback) != HAL_NFC_STATUS_OK)
+ {
+ nfa_hal_pre_discover_done_cback(0, 0, NULL);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_send_error
+**
+** Description send an Error event to NFC stack
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfc_hal_main_send_error (tHAL_NFC_STATUS status)
+{
+ /* Notify stack */
+ nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_userial_cback
+**
+** Description USERIAL callback for NCI transport
+**
+** Returns nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_userial_cback (tUSERIAL_PORT port, tUSERIAL_EVT evt, tUSERIAL_EVT_DATA *p_data)
+{
+ if (evt == USERIAL_RX_READY_EVT)
+ {
+ /* Notify transport task of serial port event */
+ GKI_send_event (NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
+ }
+ else if (evt == USERIAL_TX_DONE_EVT)
+ {
+ /* Serial driver has finshed sending data from USERIAL_Write */
+ /* Currently, no action is needed for this event */
+ }
+ else if (evt == USERIAL_ERR_EVT)
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of transport error");
+ if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE)
+ {
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ nfc_hal_nci_cmd_timeout_cback ((void *)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ }
+ else
+ {
+ nfc_hal_main_send_error (HAL_NFC_STATUS_ERR_TRANSPORT);
+ }
+ }
+ else if (evt == USERIAL_WAKEUP_EVT)
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d", p_data->sigs);
+ }
+ else
+ {
+ HAL_TRACE_DEBUG1 ("nfc_hal_main_userial_cback: unhandled userial evt: %i", evt);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_pre_init_done
+**
+** Description notify complete of pre-initialization
+**
+** Returns nothing
+**
+*******************************************************************************/
+void nfc_hal_main_pre_init_done (tHAL_NFC_STATUS status)
+{
+ HAL_TRACE_DEBUG1 ("nfc_hal_main_pre_init_done () status = %d", status);
+
+ if (status != HAL_NFC_STATUS_OK)
+ {
+ nfc_hal_main_handle_terminate ();
+
+ /* Close uart */
+ USERIAL_Close (USERIAL_NFC_PORT);
+ }
+
+ /* Notify NFC Task the status of initialization */
+ nfc_hal_cb.p_stack_cback (HAL_NFC_OPEN_CPLT_EVT, status);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_timeout_cback
+**
+** Description callback function for timeout
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_main_timeout_cback (void *p_tle)
+{
+ TIMER_LIST_ENT *p_tlent = (TIMER_LIST_ENT *) p_tle;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_main_timeout_cback ()");
+
+ switch (p_tlent->event)
+ {
+ case NFC_HAL_TTYPE_POWER_CYCLE:
+ nfc_hal_main_open_transport ();
+ break;
+
+ case NFC_HAL_TTYPE_NFCC_ENABLE:
+ /* NFCC should have enabled now, notify transport openned */
+ nfc_hal_dm_pre_init_nfcc ();
+ break;
+
+ default:
+ HAL_TRACE_DEBUG1 ("nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)", p_tlent->event);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_handle_terminate
+**
+** Description Handle NFI transport shutdown
+**
+** Returns nothing
+**
+*******************************************************************************/
+static void nfc_hal_main_handle_terminate (void)
+{
+ NFC_HDR *p_msg;
+
+ /* dequeue and free buffer */
+ if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL)
+ {
+ GKI_freebuf (nfc_hal_cb.ncit_cb.p_pend_cmd);
+ nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
+ }
+
+ /* Free unsent nfc rx buffer */
+ if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+ {
+ GKI_freebuf (nfc_hal_cb.ncit_cb.p_rcv_msg);
+ nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+ }
+
+ /* Free buffer for pending fragmented response/notification */
+ if (nfc_hal_cb.ncit_cb.p_frag_msg)
+ {
+ GKI_freebuf (nfc_hal_cb.ncit_cb.p_frag_msg);
+ nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
+ }
+
+ /* Free buffers in the tx mbox */
+ while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+ {
+ GKI_freebuf (p_msg);
+ }
+
+ /* notify closing transport */
+ nfc_hal_dm_shutting_down_nfcc ();
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_start_quick_timer
+**
+** Description Start a timer for the specified amount of time.
+** NOTE: The timeout resolution depends on including modules.
+** QUICK_TIMER_TICKS_PER_SEC should be used to convert from
+** time to ticks.
+**
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_main_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
+{
+ NFC_HDR *p_msg;
+
+ /* if timer list is currently empty, start periodic GKI timer */
+ if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+ {
+ /* if timer starts on other than NCIT task (script wrapper) */
+ if(GKI_get_taskid () != NFC_HAL_TASK)
+ {
+ /* post event to start timer in NCIT task */
+ if ((p_msg = (NFC_HDR *) GKI_getbuf (NFC_HDR_SIZE)) != NULL)
+ {
+ p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
+ GKI_send_msg (NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
+ }
+ }
+ else
+ {
+ GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+ }
+ }
+
+ GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+ p_tle->event = type;
+ p_tle->ticks = timeout; /* Save the number of ticks for the timer */
+
+ GKI_add_to_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_stop_quick_timer
+**
+** Description Stop a timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_main_stop_quick_timer (TIMER_LIST_ENT *p_tle)
+{
+ GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+ {
+ GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_process_quick_timer_evt
+**
+** Description Process quick timer event
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_main_process_quick_timer_evt (void)
+{
+ TIMER_LIST_ENT *p_tle;
+
+ GKI_update_timer_list (&nfc_hal_cb.quick_timer_queue, 1);
+
+ while ((nfc_hal_cb.quick_timer_queue.p_first) && (!nfc_hal_cb.quick_timer_queue.p_first->ticks))
+ {
+ p_tle = nfc_hal_cb.quick_timer_queue.p_first;
+ GKI_remove_from_timer_list (&nfc_hal_cb.quick_timer_queue, p_tle);
+
+ if (p_tle->p_cback)
+ {
+ (*p_tle->p_cback) (p_tle);
+ }
+ }
+
+ /* if timer list is empty stop periodic GKI timer */
+ if (nfc_hal_cb.quick_timer_queue.p_first == NULL)
+ {
+ GKI_stop_timer (NFC_HAL_QUICK_TIMER_ID);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_send_nci_msg_to_nfc_task
+**
+** Description This function is called to send nci message to nfc task
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_send_nci_msg_to_nfc_task (NFC_HDR * p_msg)
+{
+#ifdef NFC_HAL_SHARED_GKI
+ /* Using shared NFC/HAL GKI resources - send message buffer directly to NFC_TASK for processing */
+ p_msg->event = BT_EVT_TO_NFC_NCI;
+ GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
+#else
+ /* Send NCI message to the stack */
+ nfc_hal_cb.p_data_cback (p_msg->len, (UINT8 *) ((p_msg + 1)
+ + p_msg->offset));
+ GKI_freebuf(p_msg);
+#endif
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_send_credit_ntf_for_cid
+**
+** Description This function is called to send credit ntf
+** for the specified connection id to nfc task
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_send_credit_ntf_for_cid (UINT8 cid)
+{
+ NFC_HDR *p_msg;
+ UINT8 *p, *ps;
+
+ /* Start of new message. Allocate a buffer for message */
+ if ((p_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ /* Initialize NFC_HDR */
+ p_msg->len = NCI_DATA_HDR_SIZE + 0x03;
+ p_msg->event = 0;
+ p_msg->offset = 0;
+ p_msg->layer_specific = 0;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ ps = p;
+ NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE);
+ NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS);
+ UINT8_TO_STREAM (p, 0x03);
+
+ /* Number of credit entries */
+ *p++ = 0x01;
+ /* Connection id of the credit ntf */
+ *p++ = cid;
+ /* Number of credits */
+ *p = 0x01;
+#ifdef DISP_NCI
+ DISP_NCI (ps, (UINT16) p_msg->len, TRUE);
+#endif
+ nfc_hal_send_nci_msg_to_nfc_task (p_msg);
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("Unable to allocate buffer for Sending credit ntf to stack");
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_send_message
+**
+** Description This function is calledto send an NCI message.
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_main_send_message (NFC_HDR *p_msg)
+{
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ UINT8 cid, pbf;
+ UINT16 data_len;
+#endif
+ UINT8 *ps, *pp;
+ UINT16 len = p_msg->len;
+#ifdef DISP_NCI
+ UINT8 delta;
+#endif
+
+ HAL_TRACE_DEBUG1 ("nfc_hal_main_send_message() ls:0x%x", p_msg->layer_specific);
+ if ( (p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD)
+ ||(p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC) )
+ {
+ nfc_hal_nci_send_cmd (p_msg);
+ }
+ else
+ {
+ /* NFC task has fragmented the data packet to the appropriate size
+ * and data credit is available; just send it */
+
+ /* add NCI packet type in front of message */
+ nfc_hal_nci_add_nfc_pkt_type (p_msg);
+
+ /* send this packet to transport */
+ ps = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = ps + 1;
+#ifdef DISP_NCI
+ delta = p_msg->len - len;
+ DISP_NCI (ps + delta, (UINT16) (p_msg->len - delta), FALSE);
+#endif
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ if (nfc_hal_cb.hci_cb.hcp_conn_id)
+ {
+ NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+ if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+ {
+ if (nfc_hal_hci_handle_hcp_pkt_to_hc (pp))
+ {
+ HAL_TRACE_DEBUG0 ("nfc_hal_main_send_message() - Drop rsp to Fake cmd, Fake credit ntf");
+ GKI_freebuf (p_msg);
+ nfc_hal_send_credit_ntf_for_cid (cid);
+ return;
+ }
+ }
+
+ }
+#endif
+
+ /* check low power mode state */
+ if (nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT))
+ {
+ USERIAL_Write (USERIAL_NFC_PORT, ps, p_msg->len);
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_main_send_message(): drop data in low power mode");
+ }
+ GKI_freebuf (p_msg);
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_main_task
+**
+** Description NFC HAL NCI transport event processing task
+**
+** Returns 0
+**
+*******************************************************************************/
+UINT32 nfc_hal_main_task (UINT32 param)
+{
+ UINT16 event;
+ UINT8 byte;
+ UINT8 num_interfaces;
+ UINT8 *p;
+ NFC_HDR *p_msg;
+ BOOLEAN free_msg;
+
+ HAL_TRACE_DEBUG0 ("NFC_HAL_TASK started");
+
+ /* Main loop */
+ while (TRUE)
+ {
+ event = GKI_wait (0xFFFF, 0);
+
+ /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
+ if (event & NFC_HAL_TASK_EVT_INITIALIZE)
+ {
+ HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC transport...");
+
+ nfc_hal_main_open_transport ();
+ }
+
+ /* Check for terminate event */
+ if (event & NFC_HAL_TASK_EVT_TERMINATE)
+ {
+ HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
+ nfc_hal_main_handle_terminate ();
+
+ /* Close uart */
+ USERIAL_Close (USERIAL_NFC_PORT);
+
+ if (nfc_hal_cb.p_stack_cback)
+ {
+ nfc_hal_cb.p_stack_cback (HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
+ nfc_hal_cb.p_stack_cback = NULL;
+ }
+ continue;
+ }
+
+ /* Check for power cycle event */
+ if (event & NFC_HAL_TASK_EVT_POWER_CYCLE)
+ {
+ HAL_TRACE_DEBUG0 ("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
+ nfc_hal_main_handle_terminate ();
+
+ /* Close uart */
+ USERIAL_Close (USERIAL_NFC_PORT);
+
+ /* power cycle timeout */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
+ (NFC_HAL_POWER_CYCLE_DELAY*QUICK_TIMER_TICKS_PER_SEC)/1000);
+ continue;
+ }
+
+ /* NCI message ready to be sent to NFCC */
+ if (event & NFC_HAL_TASK_EVT_MBOX)
+ {
+ while ((p_msg = (NFC_HDR *) GKI_read_mbox (NFC_HAL_TASK_MBOX)) != NULL)
+ {
+ free_msg = TRUE;
+ switch (p_msg->event & NFC_EVT_MASK)
+ {
+ case NFC_HAL_EVT_TO_NFC_NCI:
+ nfc_hal_main_send_message (p_msg);
+ /* do not free buffer. NCI VS code may keep it for processing later */
+ free_msg = FALSE;
+ break;
+
+ case NFC_HAL_EVT_POST_CORE_RESET:
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
+
+ /* set NCI Control packet size from CORE_INIT_RSP */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
+ p += 5;
+ STREAM_TO_UINT8 (num_interfaces, p);
+ p += (num_interfaces + 3);
+ nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
+
+ /* start post initialization */
+ nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
+ nfc_hal_cb.dev_cb.next_startup_vsc = 1;
+
+ nfc_hal_dm_config_nfcc ();
+ break;
+
+ case NFC_HAL_EVT_TO_START_QUICK_TIMER:
+ GKI_start_timer (NFC_HAL_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
+ break;
+
+ case NFC_HAL_EVT_HCI:
+ nfc_hal_hci_evt_hdlr ((tNFC_HAL_HCI_EVENT_DATA *) p_msg);
+ break;
+
+ case NFC_HAL_EVT_PRE_DISCOVER:
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE);
+ nfa_hal_send_pre_discover_cfg ();
+ break;
+
+ case NFC_HAL_EVT_CONTROL_GRANTED:
+ nfc_hal_dm_send_pend_cmd ();
+ break;
+
+ default:
+ break;
+ }
+
+ if (free_msg)
+ GKI_freebuf (p_msg);
+ }
+ }
+
+ /* Data waiting to be read from serial port */
+ if (event & NFC_HAL_TASK_EVT_DATA_RDY)
+ {
+ while (TRUE)
+ {
+ /* Read one byte to see if there is anything waiting to be read */
+ if (USERIAL_Read (USERIAL_NFC_PORT, &byte, 1) == 0)
+ {
+ break;
+ }
+
+ if (nfc_hal_nci_receive_msg (byte))
+ {
+ /* complete of receiving NCI message */
+ nfc_hal_nci_assemble_nci_msg ();
+ if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+ {
+ if (nfc_hal_nci_preproc_rx_nci_msg (nfc_hal_cb.ncit_cb.p_rcv_msg))
+ {
+ /* Send NCI message to the stack */
+ nfc_hal_send_nci_msg_to_nfc_task (nfc_hal_cb.ncit_cb.p_rcv_msg);
+ }
+ else
+ {
+ if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+ GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+ }
+ nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+ }
+ }
+ } /* while (TRUE) */
+ }
+
+ /* Process quick timer tick */
+ if (event & NFC_HAL_QUICK_TIMER_EVT_MASK)
+ {
+ nfc_hal_main_process_quick_timer_evt ();
+ }
+ }
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_main_task terminated");
+
+ GKI_exit_task (GKI_get_taskid ());
+ return 0;
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcSetTraceLevel
+**
+** Description This function sets the trace level for HAL. If called with
+** a value of 0xFF, it simply returns the current trace level.
+**
+** Returns The new or current trace level
+**
+*******************************************************************************/
+UINT8 HAL_NfcSetTraceLevel (UINT8 new_level)
+{
+ if (new_level != 0xFF)
+ nfc_hal_cb.trace_level = new_level;
+
+ return (nfc_hal_cb.trace_level);
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
new file mode 100644
index 0000000..f4eb9af
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_nci.c
@@ -0,0 +1,887 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2010-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/******************************************************************************
+ *
+ * This file contains function of the NFC unit to receive/process NCI/VS
+ * commands/responses.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "nfc_hal_post_reset.h"
+#include "userial.h"
+#include "nci_defs.h"
+
+
+/*****************************************************************************
+** Constants and types
+*****************************************************************************/
+
+/*****************************************************************************
+** Local function prototypes
+*****************************************************************************/
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_assemble_nci_msg
+**
+** Description This function is called to reassemble the received NCI
+** response/notification packet, if required.
+** (The data packets are posted to NFC task for reassembly)
+**
+** Returns void.
+**
+*******************************************************************************/
+void nfc_hal_nci_assemble_nci_msg (void)
+{
+ NFC_HDR *p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg;
+ UINT8 u8;
+ UINT8 *p, *pp;
+ UINT8 hdr[2];
+ UINT8 *ps, *pd;
+ UINT16 size, needed;
+ BOOLEAN disp_again = FALSE;
+
+ if ((p_msg == NULL) || (p_msg->len < NCI_MSG_HDR_SIZE))
+ return;
+
+#ifdef DISP_NCI
+ DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+#endif
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ u8 = *p++;
+ /* remove the PBF bit for potential reassembly later */
+ hdr[0] = u8 & ~NCI_PBF_MASK;
+ if ((u8 & NCI_MT_MASK) == NCI_MT_DATA)
+ {
+ /* clear the RFU in octet1 */
+ *(p) = 0;
+ /* data packet reassembly is performed in NFC task */
+ return;
+ }
+ else
+ {
+ *(p) &= NCI_OID_MASK;
+ }
+
+ hdr[1] = *p;
+ pp = hdr;
+ /* save octet0 and octet1 of an NCI header in layer_specific for the received packet */
+ STREAM_TO_UINT16 (p_msg->layer_specific, pp);
+
+ if (nfc_hal_cb.ncit_cb.p_frag_msg)
+ {
+ if (nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific != p_msg->layer_specific)
+ {
+ /* check if these fragments are of the same NCI message */
+ HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() - different messages 0x%x, 0x%x!!", nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific, p_msg->layer_specific);
+ nfc_hal_cb.ncit_cb.nci_ras |= NFC_HAL_NCI_RAS_ERROR;
+ }
+ else if (nfc_hal_cb.ncit_cb.nci_ras == 0)
+ {
+ disp_again = TRUE;
+ /* if not previous reassembly error, append the new fragment */
+ p_msg->offset += NCI_MSG_HDR_SIZE;
+ p_msg->len -= NCI_MSG_HDR_SIZE;
+ size = GKI_get_buf_size (nfc_hal_cb.ncit_cb.p_frag_msg);
+ needed = (NFC_HDR_SIZE + nfc_hal_cb.ncit_cb.p_frag_msg->len + nfc_hal_cb.ncit_cb.p_frag_msg->offset + p_msg->len);
+ if (size >= needed)
+ {
+ /* the buffer for reassembly is big enough to append the new fragment */
+ ps = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pd = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + nfc_hal_cb.ncit_cb.p_frag_msg->len;
+ memcpy (pd, ps, p_msg->len);
+ nfc_hal_cb.ncit_cb.p_frag_msg->len += p_msg->len;
+ /* adjust the NCI packet length */
+ pd = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + 2;
+ *pd = (UINT8) (nfc_hal_cb.ncit_cb.p_frag_msg->len - NCI_MSG_HDR_SIZE);
+ }
+ else
+ {
+ nfc_hal_cb.ncit_cb.nci_ras |= NFC_HAL_NCI_RAS_TOO_BIG;
+ HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() buffer overrun (%d + %d)!!", nfc_hal_cb.ncit_cb.p_frag_msg->len, p_msg->len);
+ }
+ }
+ /* we are done with this new fragment, free it */
+ GKI_freebuf (p_msg);
+ }
+ else
+ {
+ nfc_hal_cb.ncit_cb.p_frag_msg = p_msg;
+ }
+
+
+ if ((u8 & NCI_PBF_MASK) == NCI_PBF_NO_OR_LAST)
+ {
+ /* last fragment */
+ p_msg = nfc_hal_cb.ncit_cb.p_frag_msg;
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ *p = u8; /* this should make the PBF flag as Last Fragment */
+ nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
+
+ p_msg->layer_specific = nfc_hal_cb.ncit_cb.nci_ras;
+ /* still report the data packet, if the incoming packet is too big */
+ if (nfc_hal_cb.ncit_cb.nci_ras & NFC_HAL_NCI_RAS_ERROR)
+ {
+ /* NFCC reported NCI fragments for different NCI messages and this is the last fragment - drop it */
+ HAL_TRACE_ERROR0 ("nfc_hal_nci_assemble_nci_msg() clearing NCI_RAS_ERROR");
+ GKI_freebuf (p_msg);
+ p_msg = NULL;
+ }
+#ifdef DISP_NCI
+ if ((nfc_hal_cb.ncit_cb.nci_ras == 0) && (disp_again))
+ {
+ DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
+ }
+#endif
+ /* clear the error flags, so the next NCI packet is clean */
+ nfc_hal_cb.ncit_cb.nci_ras = 0;
+ }
+ else
+ {
+ /* still reassembling */
+ p_msg = NULL;
+ }
+
+ nfc_hal_cb.ncit_cb.p_rcv_msg = p_msg;
+}
+
+/*****************************************************************************
+**
+** Function nfc_hal_nci_receive_nci_msg
+**
+** Description
+** Handle incoming data (NCI events) from the serial port.
+**
+** If there is data waiting from the serial port, this funciton reads the
+** data and parses it. Once an entire NCI message has been read, it sends
+** the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_nci_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+ UINT16 len;
+ BOOLEAN msg_received = FALSE;
+
+ switch (p_cb->rcv_state)
+ {
+ case NFC_HAL_RCV_NCI_MSG_ST:
+
+ /* Initialize rx parameters */
+ p_cb->rcv_state = NFC_HAL_RCV_NCI_HDR_ST;
+ p_cb->rcv_len = NCI_MSG_HDR_SIZE;
+
+ /* Start of new message. Allocate a buffer for message */
+ if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ /* Initialize NFC_HDR */
+ p_cb->p_rcv_msg->len = 0;
+ p_cb->p_rcv_msg->event = 0;
+ p_cb->p_rcv_msg->offset = 0;
+
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("Unable to allocate buffer for incoming NCI message.");
+ }
+ p_cb->rcv_len--;
+ break;
+
+ case NFC_HAL_RCV_NCI_HDR_ST:
+
+ if (p_cb->p_rcv_msg)
+ {
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+ }
+
+ p_cb->rcv_len--;
+
+ /* Check if we read in entire NFC message header yet */
+ if (p_cb->rcv_len == 0)
+ {
+ p_cb->rcv_len = byte;
+
+ /* If non-zero payload, then go to receive-data state */
+ if (byte > 0)
+ {
+ p_cb->rcv_state = NFC_HAL_RCV_NCI_PAYLOAD_ST;
+ }
+ else
+ {
+ msg_received = TRUE;
+ p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+ }
+ }
+ break;
+
+ case NFC_HAL_RCV_NCI_PAYLOAD_ST:
+
+ p_cb->rcv_len--;
+ if (p_cb->p_rcv_msg)
+ {
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+ if (p_cb->rcv_len > 0)
+ {
+ /* Read in the rest of the message */
+ len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len), p_cb->rcv_len);
+ p_cb->p_rcv_msg->len += len;
+ p_cb->rcv_len -= len;
+ }
+ }
+
+ /* Check if we read in entire message yet */
+ if (p_cb->rcv_len == 0)
+ {
+ msg_received = TRUE;
+ p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
+ }
+ break;
+ }
+
+ return (msg_received);
+}
+
+/*****************************************************************************
+**
+** Function nfc_hal_nci_receive_bt_msg
+**
+** Description
+** Handle incoming BRCM specific data from the serial port.
+**
+** If there is data waiting from the serial port, this funciton reads the
+** data and parses it. Once an entire message has been read, it returns
+** TRUE.
+**
+*****************************************************************************/
+static BOOLEAN nfc_hal_nci_receive_bt_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
+{
+ UINT16 len;
+ BOOLEAN msg_received = FALSE;
+
+ switch (p_cb->rcv_state)
+ {
+ case NFC_HAL_RCV_BT_MSG_ST:
+
+ /* Initialize rx parameters */
+ p_cb->rcv_state = NFC_HAL_RCV_BT_HDR_ST;
+ p_cb->rcv_len = HCIE_PREAMBLE_SIZE;
+
+ if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
+ {
+ /* Initialize NFC_HDR */
+ p_cb->p_rcv_msg->len = 0;
+ p_cb->p_rcv_msg->event = 0;
+ p_cb->p_rcv_msg->offset = 0;
+
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("[nfc] Unable to allocate buffer for incoming NCI message.");
+ }
+ p_cb->rcv_len--;
+ break;
+
+ case NFC_HAL_RCV_BT_HDR_ST:
+ if (p_cb->p_rcv_msg)
+ {
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+ }
+ p_cb->rcv_len--;
+
+ /* Check if we received entire preamble yet */
+ if (p_cb->rcv_len == 0)
+ {
+ /* Received entire preamble. Length is in the last byte(s) of the preamble */
+ p_cb->rcv_len = byte;
+
+ /* Verify that buffer is big enough to fit message */
+ if ((p_cb->p_rcv_msg) &&
+ ((sizeof (NFC_HDR) + HCIE_PREAMBLE_SIZE + byte) > GKI_get_buf_size (p_cb->p_rcv_msg)) )
+ {
+ /* Message cannot fit into buffer */
+ GKI_freebuf (p_cb->p_rcv_msg);
+ p_cb->p_rcv_msg = NULL;
+
+ HAL_TRACE_ERROR0 ("Invalid length for incoming BT HCI message.");
+ }
+
+ /* Message length is valid */
+ if (byte)
+ {
+ /* Read rest of message */
+ p_cb->rcv_state = NFC_HAL_RCV_BT_PAYLOAD_ST;
+ }
+ else
+ {
+ /* Message has no additional parameters. (Entire message has been received) */
+ msg_received = TRUE;
+ p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; /* Next, wait for packet type of next message */
+ }
+ }
+ break;
+
+ case NFC_HAL_RCV_BT_PAYLOAD_ST:
+ p_cb->rcv_len--;
+ if (p_cb->p_rcv_msg)
+ {
+ *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
+
+ if (p_cb->rcv_len > 0)
+ {
+ /* Read in the rest of the message */
+ len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len), p_cb->rcv_len);
+ p_cb->p_rcv_msg->len += len;
+ p_cb->rcv_len -= len;
+ }
+ }
+
+ /* Check if we read in entire message yet */
+ if (p_cb->rcv_len == 0)
+ {
+ msg_received = TRUE;
+ p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST; /* Next, wait for packet type of next message */
+ }
+ break;
+ }
+
+ /* If we received entire message */
+#if (NFC_HAL_TRACE_PROTOCOL == TRUE)
+ if (msg_received && p_cb->p_rcv_msg)
+ {
+ /* Display protocol trace message */
+ DispHciEvt (p_cb->p_rcv_msg);
+ }
+#endif
+
+ return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_proc_rx_bt_msg
+**
+** Description Received BT message from NFCC
+**
+** Notify command complete if initializing NFCC
+** Forward BT message to NFC task
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_nci_proc_rx_bt_msg (void)
+{
+ UINT8 *p;
+ NFC_HDR *p_msg;
+ UINT16 opcode, old_opcode;
+ tNFC_HAL_BTVSC_CPLT vcs_cplt_params;
+ tNFC_HAL_BTVSC_CPLT_CBACK *p_cback = NULL;
+
+ /* if complete BT message is received successfully */
+ if (nfc_hal_cb.ncit_cb.p_rcv_msg)
+ {
+ p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg;
+ HAL_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state);
+ HAL_TRACE_DEBUG2 ("event: 0x%x, wait_rsp:0x%x", p_msg->event, nfc_hal_cb.ncit_cb.nci_wait_rsp);
+ /* increase the cmd window here */
+ if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
+ {
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ if (*p == HCI_COMMAND_COMPLETE_EVT)
+ {
+ p += 3; /* code, len, cmd window */
+ STREAM_TO_UINT16 (opcode, p);
+ p = nfc_hal_cb.ncit_cb.last_hdr;
+ STREAM_TO_UINT16 (old_opcode, p);
+ if (opcode == old_opcode)
+ {
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+ p_cback = (tNFC_HAL_BTVSC_CPLT_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
+ nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
+ }
+ }
+ }
+
+ /* if initializing BRCM NFCC */
+ if ((nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) ||
+ (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ||
+ (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE))
+ {
+ /* this is command complete event for baud rate update or download patch */
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ p += 1; /* skip opcode */
+ STREAM_TO_UINT8 (vcs_cplt_params.param_len, p);
+
+ p += 1; /* skip num command packets */
+ STREAM_TO_UINT16 (vcs_cplt_params.opcode, p);
+
+ vcs_cplt_params.param_len -= 3;
+ vcs_cplt_params.p_param_buf = p;
+
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+ {
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
+ }
+ if (p_cback)
+ {
+ nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
+ (*p_cback) (&vcs_cplt_params);
+ }
+
+ /* do not BT send message to NFC task */
+ GKI_freebuf (p_msg);
+ }
+ else
+ {
+ /* do not BT send message to NFC task */
+ GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
+ }
+ nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
+ }
+}
+
+/*****************************************************************************
+**
+** Function nfc_hal_nci_receive_msg
+**
+** Description
+** Handle incoming data (NCI events) from the serial port.
+**
+** If there is data waiting from the serial port, this funciton reads the
+** data and parses it. Once an entire NCI message has been read, it sends
+** the message the the NFC_TASK for processing
+**
+*****************************************************************************/
+BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte)
+{
+ tNFC_HAL_NCIT_CB *p_cb = &(nfc_hal_cb.ncit_cb);
+ BOOLEAN msg_received = FALSE;
+
+ if (p_cb->rcv_state == NFC_HAL_RCV_IDLE_ST)
+ {
+ /* if this is NCI message */
+ if (byte == HCIT_TYPE_NFC)
+ {
+ p_cb->rcv_state = NFC_HAL_RCV_NCI_MSG_ST;
+ }
+ /* if this is BT message */
+ else if (byte == HCIT_TYPE_EVENT)
+ {
+ p_cb->rcv_state = NFC_HAL_RCV_BT_MSG_ST;
+ }
+ else
+ {
+ HAL_TRACE_ERROR1 ("Unknown packet type drop this byte 0x%x", byte);
+ }
+ }
+ else if (p_cb->rcv_state <= NFC_HAL_RCV_NCI_PAYLOAD_ST)
+ {
+ msg_received = nfc_hal_nci_receive_nci_msg (p_cb, byte);
+ }
+ else
+ {
+ if (nfc_hal_nci_receive_bt_msg (p_cb, byte))
+ {
+ /* received BT message */
+ nfc_hal_nci_proc_rx_bt_msg ();
+ }
+ }
+
+ return (msg_received);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_preproc_rx_nci_msg
+**
+** Description NFCC sends NCI message to DH while initializing NFCC
+** processing low power mode
+**
+** Returns TRUE, if NFC task need to receive NCI message
+**
+*******************************************************************************/
+BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg)
+{
+ UINT8 *p, *pp;
+ UINT8 mt, pbf, gid, op_code;
+ UINT8 payload_len;
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ UINT8 cid;
+ UINT16 data_len;
+#endif
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_nci_preproc_rx_nci_msg()");
+
+ /* if initializing BRCM NFCC */
+ if (nfc_hal_cb.dev_cb.initializing_state != NFC_HAL_INIT_STATE_IDLE)
+ {
+ nfc_hal_dm_proc_msg_during_init (p_msg);
+ /* do not send message to NFC task while initializing NFCC */
+ return (FALSE);
+ }
+ else
+ {
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ pp = p;
+ NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+ NCI_MSG_PRS_HDR1 (p, op_code);
+ payload_len = *p++;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ if (mt == NCI_MT_DATA)
+ {
+ if (nfc_hal_cb.hci_cb.hcp_conn_id)
+ {
+ NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
+ if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
+ {
+ nfc_hal_hci_handle_hcp_pkt_from_hc (pp);
+ }
+
+ }
+ }
+
+ if (gid == NCI_GID_PROP) /* this is for hci netwk ntf */
+ {
+ if (mt == NCI_MT_NTF)
+ {
+ if (op_code == NCI_MSG_HCI_NETWK)
+ {
+ nfc_hal_hci_handle_hci_netwk_info ((UINT8 *) (p_msg + 1) + p_msg->offset);
+ }
+ }
+ }
+ else
+#endif
+ if (gid == NCI_GID_RF_MANAGE)
+ {
+ if (mt == NCI_MT_NTF)
+ {
+ if (op_code == NCI_MSG_RF_INTF_ACTIVATED)
+ {
+ if ((nfc_hal_cb.max_rf_credits) && (payload_len > 5))
+ {
+ /* API used wants to limit the RF data credits */
+ p += 5; /* skip RF disc id, interface, protocol, tech&mode, payload size */
+ if (*p > nfc_hal_cb.max_rf_credits)
+ {
+ HAL_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits);
+ *p = nfc_hal_cb.max_rf_credits;
+ }
+ }
+ }
+ }
+ }
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ else if (gid == NCI_GID_CORE)
+ {
+ if (mt == NCI_MT_RSP)
+ {
+ if (op_code == NCI_MSG_CORE_CONN_CREATE)
+ {
+ if (nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp)
+ {
+ p++; /* skip status byte */
+ nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+ p++; /* skip buff size */
+ p++; /* num of buffers */
+ nfc_hal_cb.hci_cb.hcp_conn_id = *p;
+ }
+ }
+ }
+ }
+#endif
+ }
+
+ if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
+ {
+ if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
+ {
+ /* extend idle timer */
+ nfc_hal_dm_power_mode_execute (NFC_HAL_LP_RX_DATA_EVT);
+ }
+ }
+
+ return (TRUE);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_add_nfc_pkt_type
+**
+** Description Add packet type (HCIT_TYPE_NFC)
+**
+** Returns TRUE, if NFCC can receive NCI message
+**
+*******************************************************************************/
+void nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 hcit;
+
+ /* add packet type in front of NCI header */
+ if (p_msg->offset > 0)
+ {
+ p_msg->offset--;
+ p_msg->len++;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+ *p = HCIT_TYPE_NFC;
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("nfc_hal_nci_add_nfc_pkt_type () : No space for packet type");
+ hcit = HCIT_TYPE_NFC;
+ USERIAL_Write (USERIAL_NFC_PORT, &hcit, 1);
+ }
+}
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function nci_brcm_check_cmd_create_hcp_connection
+**
+** Description Check if this is command to create HCP connection
+**
+** Returns None
+**
+*******************************************************************************/
+static void nci_brcm_check_cmd_create_hcp_connection (NFC_HDR *p_msg)
+{
+ UINT8 *p;
+ UINT8 mt, pbf, gid, op_code;
+
+ nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
+
+ p = (UINT8 *) (p_msg + 1) + p_msg->offset;
+
+ if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
+ {
+ NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
+ NCI_MSG_PRS_HDR1 (p, op_code);
+
+ if (gid == NCI_GID_CORE)
+ {
+ if (mt == NCI_MT_CMD)
+ {
+ if (op_code == NCI_MSG_CORE_CONN_CREATE)
+ {
+ if ( ((NCI_CORE_PARAM_SIZE_CON_CREATE + 4) == *p++)
+ &&(NCI_DEST_TYPE_NFCEE == *p++)
+ &&(1 == *p++)
+ &&(NCI_CON_CREATE_TAG_NFCEE_VAL == *p++)
+ &&(2 == *p++) )
+ {
+ p++;
+ if (NCI_NFCEE_INTERFACE_HCI_ACCESS == *p)
+ {
+ nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = TRUE;
+ return;
+ }
+ }
+
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_send_cmd
+**
+** Description Send NCI command to the transport
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_nci_send_cmd (NFC_HDR *p_buf)
+{
+ BOOLEAN continue_to_process = TRUE;
+ UINT8 *ps, *pd;
+ UINT16 max_len;
+ UINT16 buf_len, offset;
+ UINT8 *p;
+ UINT8 hdr[NCI_MSG_HDR_SIZE];
+ UINT8 nci_ctrl_size = nfc_hal_cb.ncit_cb.nci_ctrl_size;
+ UINT8 delta = 0;
+
+#if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
+ if ( (nfc_hal_cb.hci_cb.hcp_conn_id == 0)
+ &&(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_NONE) )
+ nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf);
+#endif
+
+ /* check low power mode state */
+ continue_to_process = nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT);
+
+ if (!continue_to_process)
+ {
+ /* save the command to be sent until NFCC is free. */
+ nfc_hal_cb.ncit_cb.p_pend_cmd = p_buf;
+ return;
+ }
+
+ max_len = nci_ctrl_size + NCI_MSG_HDR_SIZE;
+ buf_len = p_buf->len;
+ offset = p_buf->offset;
+#ifdef DISP_NCI
+ if (buf_len > max_len)
+ {
+ /* this command needs to be fragmented. display the complete packet first */
+ DISP_NCI ((UINT8 *) (p_buf + 1) + p_buf->offset, p_buf->len, FALSE);
+ }
+#endif
+ ps = (UINT8 *) (p_buf + 1) + p_buf->offset;
+ memcpy (hdr, ps, NCI_MSG_HDR_SIZE);
+ while (buf_len > max_len)
+ {
+ HAL_TRACE_DEBUG2 ("buf_len (%d) > max_len (%d)", buf_len, max_len);
+ /* the NCI command is bigger than the NFCC Max Control Packet Payload Length
+ * fragment the command */
+
+ p_buf->len = max_len;
+ ps = (UINT8 *) (p_buf + 1) + p_buf->offset;
+ /* mark the control packet as fragmented */
+ *ps |= NCI_PBF_ST_CONT;
+ /* adjust the length of this fragment */
+ ps += 2;
+ *ps = nci_ctrl_size;
+
+ /* add NCI packet type in front of message */
+ nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+ /* send this fragment to transport */
+ p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+ delta = p_buf->len - max_len;
+ DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+ USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+ /* adjust the len and offset to reflect that part of the command is already sent */
+ buf_len -= nci_ctrl_size;
+ offset += nci_ctrl_size;
+ HAL_TRACE_DEBUG2 ("p_buf->len: %d buf_len (%d)", p_buf->len, buf_len);
+ p_buf->len = buf_len;
+ p_buf->offset = offset;
+ pd = (UINT8 *) (p_buf + 1) + p_buf->offset;
+ /* restore the NCI header */
+ memcpy (pd, hdr, NCI_MSG_HDR_SIZE);
+ pd += 2;
+ *pd = (UINT8) (p_buf->len - NCI_MSG_HDR_SIZE);
+ }
+
+ HAL_TRACE_DEBUG1 ("p_buf->len: %d", p_buf->len);
+
+ /* add NCI packet type in front of message */
+ nfc_hal_nci_add_nfc_pkt_type (p_buf);
+
+ /* send this fragment to transport */
+ p = (UINT8 *) (p_buf + 1) + p_buf->offset;
+
+#ifdef DISP_NCI
+ delta = p_buf->len - buf_len;
+ DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
+#endif
+ USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
+
+ GKI_freebuf (p_buf);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_nci_cmd_timeout_cback
+**
+** Description callback function for timeout
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_nci_cmd_timeout_cback (void *p_tle)
+{
+ TIMER_LIST_ENT *p_tlent = (TIMER_LIST_ENT *)p_tle;
+
+ HAL_TRACE_DEBUG0 ("nfc_hal_nci_cmd_timeout_cback ()");
+
+ nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
+
+ if (p_tlent->event == NFC_HAL_TTYPE_NCI_WAIT_RSP)
+ {
+ if (nfc_hal_cb.dev_cb.initializing_state <= NFC_HAL_INIT_STATE_W4_PATCH_INFO)
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+ }
+ else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
+ {
+ if (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_IDLE)
+ {
+ nfc_hal_prm_process_timeout (NULL);
+ }
+ else
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+ }
+ }
+ else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_POST_INIT_DONE)
+ {
+ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+ }
+ else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
+ {
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+ }
+ else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE)
+ {
+ NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
+ nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
+ }
+ }
+}
+
+
+/*******************************************************************************
+**
+** Function HAL_NfcSetMaxRfDataCredits
+**
+** Description This function sets the maximum RF data credit for HAL.
+** If 0, use the value reported from NFCC.
+**
+** Returns none
+**
+*******************************************************************************/
+void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits)
+{
+ HAL_TRACE_DEBUG2 ("HAL_NfcSetMaxRfDataCredits %d->%d", nfc_hal_cb.max_rf_credits, max_credits);
+ nfc_hal_cb.max_rf_credits = max_credits;
+}
diff --git a/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
new file mode 100644
index 0000000..d1b739c
--- /dev/null
+++ b/halimpl/bcm2079x/hal/hal/nfc_hal_prm.c
@@ -0,0 +1,1195 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012-2014 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "nfc_hal_int.h"
+#include "userial.h"
+
+/*****************************************************************************
+* Definitions
+*****************************************************************************/
+
+/* Internal flags */
+#define NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF 0x01 /* Application provided patchram in a single buffer */
+#define NFC_HAL_PRM_FLAGS_RFU 0x02 /* Reserved for future use */
+#define NFC_HAL_PRM_FLAGS_SIGNATURE_SENT 0x04 /* Signature sent to NFCC */
+#define NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED 0x08 /* PreI2C patch required */
+#define NFC_HAL_PRM_FLAGS_BCM20791B3 0x10 /* B3 Patch (no RESET_NTF after patch download) */
+#define NFC_HAL_PRM_FLAGS_RM_RF 0x20 /* Erase Personality data */
+
+/* Secure patch download definitions */
+#define NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN 7 /* PRJID + MAJORVER + MINORVER + COUNT */
+
+/* Enumeration of power modes IDs */
+#define NFC_HAL_PRM_SPD_POWER_MODE_LPM 0
+#define NFC_HAL_PRM_SPD_POWER_MODE_FPM 1
+
+/* Version string for BCM20791B3 */
+const UINT8 NFC_HAL_PRM_BCM20791B3_STR[] = "20791B3";
+#define NFC_HAL_PRM_BCM20791B3_STR_LEN (sizeof (NFC_HAL_PRM_BCM20791B3_STR)-1)
+
+#define NFC_HAL_PRM_SPD_TOUT (6000) /* timeout for SPD events (in ms) */
+#define NFC_HAL_PRM_END_DELAY (250) /* delay before sending any new command (ms)*/
+
+#if (NFC_HAL_PRM_DEBUG == TRUE)
+#define NFC_HAL_PRM_STATE(str) HAL_TRACE_DEBUG2 ("%s st: %d", str, nfc_hal_cb.prm.state)
+#else
+#define NFC_HAL_PRM_STATE(str)
+#endif
+
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status);
+typedef struct
+{
+ UINT16 offset;
+ UINT8 len;
+} tNFC_HAL_PRM_RM_RF;
+
+const tNFC_HAL_PRM_RM_RF nfc_hal_prm_rm_rf_20795a1 [] =
+{
+ {0x0000, 0xFB},
+ {0x019C, 0x08},
+ {0x05E8, 0xFB},
+ {0, 0}
+};
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void);
+
+/*****************************************************************************
+** Extern variable from nfc_hal_dm_cfg.c
+*****************************************************************************/
+extern tNFC_HAL_CFG *p_nfc_hal_cfg;
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_handle_download_complete
+**
+** Description Patch download complete (for secure patch download)
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_download_complete (UINT8 event)
+{
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_IDLE;
+
+ /* Notify application now */
+ if (nfc_hal_cb.prm.p_cback)
+ (nfc_hal_cb.prm.p_cback) (event);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_send_next_segment
+**
+** Description Send next patch segment (for secure patch download)
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_send_next_segment (void)
+{
+ UINT8 *p_src;
+ UINT16 len, offset = nfc_hal_cb.prm.cur_patch_offset;
+ UINT8 hcit, oid, hdr0, type;
+ UINT8 chipverlen;
+ UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN];
+ UINT8 patch_hdr_size = NCI_MSG_HDR_SIZE + 1; /* 1 is for HCIT */
+
+ /* Validate that segment is at least big enought to have NCI_MSG_HDR_SIZE + 1 (hcit) */
+ if (nfc_hal_cb.prm.cur_patch_len_remaining < patch_hdr_size)
+ {
+ HAL_TRACE_ERROR0 ("Unexpected end of patch.");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ return;
+ }
+
+ /* Parse NCI command header */
+ p_src = (UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset);
+ STREAM_TO_UINT8 (hcit, p_src);
+ STREAM_TO_UINT8 (hdr0, p_src);
+ STREAM_TO_UINT8 (oid, p_src);
+ STREAM_TO_UINT8 (len, p_src);
+ STREAM_TO_UINT8 (type, p_src);
+
+
+ /* Update number of bytes comsumed */
+ nfc_hal_cb.prm.cur_patch_offset += (len + patch_hdr_size);
+ nfc_hal_cb.prm.cur_patch_len_remaining -= (len + patch_hdr_size);
+
+ /* Check if sending signature byte */
+ if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+ &&(type == NCI_SPD_TYPE_SIGNATURE) )
+ {
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+ }
+ /* Check for header */
+ else if ( (oid == NCI_MSG_SECURE_PATCH_DOWNLOAD )
+ &&(type == NCI_SPD_TYPE_HEADER) )
+ {
+ /* Check if patch is for BCM20791B3 */
+ p_src += NCI_SPD_HEADER_OFFSET_CHIPVERLEN;
+ STREAM_TO_UINT8 (chipverlen, p_src);
+ if (memcmp (nfc_hal_cb.nvm_cb.chip_ver, p_src, chipverlen) != 0)
+ {
+ HAL_TRACE_ERROR0 ("Unexpected chip ver.");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ return;
+ }
+ STREAM_TO_ARRAY (chipverstr, p_src, NCI_SPD_HEADER_CHIPVER_LEN);
+
+ if (memcmp (NFC_HAL_PRM_BCM20791B3_STR, chipverstr, NFC_HAL_PRM_BCM20791B3_STR_LEN) == 0)
+ {
+ /* Patch is for BCM2079B3 - do not wait for RESET_NTF after patch download */
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_BCM20791B3;
+ }
+ else
+ {
+ /* Patch is for BCM2079B4 or newer - wait for RESET_NTF after patch download */
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_BCM20791B3;
+ }
+ }
+
+ /* Send the command (not including HCIT here) */
+ nfc_hal_dm_send_nci_cmd ((UINT8*) (nfc_hal_cb.prm.p_cur_patch_data + offset + 1), (UINT8) (len + NCI_MSG_HDR_SIZE),
+ nfc_hal_prm_nci_command_complete_cback);
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_handle_next_patch_start
+**
+** Description Handle start of next patch (for secure patch download)
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_handle_next_patch_start (void)
+{
+ UINT32 cur_patch_mask;
+ UINT32 cur_patch_len;
+ BOOLEAN found_patch_to_download = FALSE;
+
+ while (!found_patch_to_download)
+ {
+ /* Get length of current patch */
+ cur_patch_len = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+
+ /* Check if this is a patch we need to download */
+ cur_patch_mask = ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+ if (nfc_hal_cb.prm.spd_patch_needed_mask & cur_patch_mask)
+ {
+ found_patch_to_download = TRUE;
+ }
+ else
+ {
+ /* Do not need to download this patch. Skip to next patch */
+ HAL_TRACE_DEBUG1 ("Skipping patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+ nfc_hal_cb.prm.spd_cur_patch_idx++;
+ if (nfc_hal_cb.prm.spd_cur_patch_idx >= nfc_hal_cb.prm.spd_patch_count)
+ {
+ /* No more to download */
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+ return;
+ }
+ else if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+ {
+ /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch header */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+ return;
+ }
+ else
+ {
+ /* Patch in buffer. Skip over current patch. Check next patch */
+ nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) cur_patch_len;
+ nfc_hal_cb.prm.cur_patch_offset += (UINT16) cur_patch_len;
+ }
+ }
+ }
+
+
+ /* Begin downloading patch */
+ HAL_TRACE_DEBUG1 ("Downloading patch for power_mode %i.", nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_DOWNLOADING;
+ nfc_hal_prm_spd_send_next_segment ();
+}
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_download_i2c_fix
+**
+** Description Start downloading patch for i2c fix
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_download_i2c_fix (void)
+{
+ UINT8 *p, *p_start;
+ UINT16 patchfile_project_id;
+ UINT16 patchfile_ver_major;
+ UINT16 patchfile_ver_minor;
+ UINT16 patchfile_patchsize;
+ UINT8 u8;
+
+ HAL_TRACE_DEBUG0 ("Downloading I2C fix...");
+
+ /* Save pointer and offset of patchfile, so we can resume after downloading the i2c fix */
+ nfc_hal_cb.prm.spd_patch_offset = nfc_hal_cb.prm.cur_patch_offset;
+ nfc_hal_cb.prm.spd_patch_len_remaining = nfc_hal_cb.prm.cur_patch_len_remaining;
+
+ /* Initialize pointers for downloading i2c fix */
+ nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm_i2c.p_patch;
+ nfc_hal_cb.prm.cur_patch_offset = 0;
+ nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm_i2c.len;
+
+ /* Parse the i2c patchfile */
+ if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+ {
+ /* Parse patchfile header */
+ p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+ p_start = p;
+ STREAM_TO_UINT16 (patchfile_project_id, p);
+ STREAM_TO_UINT16 (patchfile_ver_major, p);
+ STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+ /* RFU */
+ p++;
+
+ /* Check how many patches are in the patch file */
+ STREAM_TO_UINT8 (u8, p);
+
+ /* Should only be one patch */
+ if (u8 > 1)
+ {
+ HAL_TRACE_ERROR1 ("Invalid i2c fix: invalid number of patches (%i)", u8);
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ return;
+ }
+
+
+ /* Get info about the i2c patch*/
+ STREAM_TO_UINT8 (u8, p); /* power mode (not needed for i2c patch) */
+ STREAM_TO_UINT16 (patchfile_patchsize, p); /* size of patch */
+
+ /* 5 byte RFU */
+ p += 5;
+
+ /* Adjust length to exclude patchfiloe header */
+ nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */
+ nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */
+
+ /* Begin sending patch to the NFCC */
+ nfc_hal_prm_spd_send_next_segment ();
+ }
+ else
+ {
+ /* ERROR: Bad length for patchfile */
+ HAL_TRACE_ERROR0 ("Invalid i2c fix: unexpected end of patch");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ }
+}
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_check_version_continue
+**
+** Description Check patchfile version with current downloaded version
+**
+** Returns void
+**
+*******************************************************************************/
+static void nfc_hal_prm_spd_check_version_continue (void)
+{
+ HAL_TRACE_DEBUG1 ("nfc_hal_prm_spd_check_version_continue 0x%02x", nfc_hal_cb.prm.flags);
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_RM_RF)
+ {
+ HAL_TRACE_DEBUG0("erase relevant blocks in NVM");
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_RM_RF;
+ if (!nfc_hal_prm_nvm_rw_cmd())
+ {
+ /* nvm rw started successfully */
+ return;
+ }
+ }
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+ {
+ HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+ /* Download i2c fix first */
+ nfc_hal_prm_spd_download_i2c_fix ();
+ return;
+ }
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+ /* Download first segment */
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+ if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF))
+ {
+ /* Notify adaptation layer to call HAL_NfcPrmDownloadContinue with the next patch segment */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+ }
+ else
+ {
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_check_version
+**
+** Description Check patchfile version with current downloaded version
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_check_version (void)
+{
+ UINT8 *p, *p_start, i;
+ UINT32 nvm_patch_present_mask = 0;
+ UINT32 patchfile_patch_present_mask;
+ UINT16 patchfile_project_id = 0;
+ UINT16 patchfile_ver_major = 0;
+ UINT16 patchfile_ver_minor = 0;
+ UINT16 patchfile_patchsize;
+
+ UINT8 return_code = NFC_HAL_PRM_COMPLETE_EVT;
+
+ /* Initialize patchfile offset pointers */
+ p = p_start = NULL;
+ patchfile_patchsize = 0;
+
+ /* the good patches in NVM */
+ if (nfc_hal_cb.nvm_cb.lpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_LPM_BAD)))
+ nvm_patch_present_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_LPM);
+
+ if (nfc_hal_cb.nvm_cb.fpm_size && !(nfc_hal_cb.nvm_cb.flags & (NFC_HAL_NVM_FLAGS_FPM_BAD)))
+ nvm_patch_present_mask |= (1 << NFC_HAL_PRM_SPD_POWER_MODE_FPM);
+
+ /* Get patchfile version */
+ if (nfc_hal_cb.prm.cur_patch_len_remaining >= NFC_HAL_PRM_NCD_PATCHFILE_HDR_LEN)
+ {
+ /* Parse patchfile header */
+ p = (UINT8 *) nfc_hal_cb.prm.p_cur_patch_data;
+ p_start = p;
+ STREAM_TO_UINT16 (patchfile_project_id, p);
+ STREAM_TO_UINT16 (patchfile_ver_major, p);
+ STREAM_TO_UINT16 (patchfile_ver_minor, p);
+
+ /* RFU */
+ p++;
+
+ /* Check how many patches are in the patch file */
+ STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_count, p);
+
+ if (nfc_hal_cb.prm.spd_patch_count > NFC_HAL_PRM_MAX_PATCH_COUNT)
+ {
+ HAL_TRACE_ERROR2 ("Unsupported patchfile (number of patches (%i) exceeds maximum (%i)",
+ nfc_hal_cb.prm.spd_patch_count, NFC_HAL_PRM_MAX_PATCH_COUNT);
+ }
+
+ /* Mask of patches that are present in the patchfile */
+ patchfile_patch_present_mask = 0;
+
+ /* Get lengths for each patch */
+ for (i = 0; i < nfc_hal_cb.prm.spd_patch_count; i++)
+ {
+ /* Get power mode for this patch */
+ STREAM_TO_UINT8 (nfc_hal_cb.prm.spd_patch_desc[i].power_mode, p);
+
+ /* Update mask of power-modes present in the patchfile */
+ patchfile_patch_present_mask |= ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[i].power_mode);
+
+ /* Get length of patch */
+ STREAM_TO_UINT16 (nfc_hal_cb.prm.spd_patch_desc[i].len, p);
+
+ /* Add total size of patches */
+ patchfile_patchsize += nfc_hal_cb.prm.spd_patch_desc[i].len;
+
+ /* 5 byte RFU */
+ p += 5;
+ }
+
+ /* Adjust offset to after the patch file header */
+ nfc_hal_cb.prm.cur_patch_offset += (UINT16) (p - p_start); /* Bytes of patchfile transmitted/processed so far */
+ nfc_hal_cb.prm.cur_patch_len_remaining -= (UINT16) (p - p_start); /* Adjust size of patchfile */
+
+
+ HAL_TRACE_DEBUG4 ("NVM Patch info: flags=0x%04x, Ver=%i.%i, PatchMask=0x%08x",
+ nfc_hal_cb.nvm_cb.flags, nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor, nvm_patch_present_mask );
+ HAL_TRACE_DEBUG6 ("Patchfile info: ProjID=0x%04x, Ver=%i.%i, Num patches=%i, PatchMask=0x%08x, PatchSize=%i",
+ patchfile_project_id, patchfile_ver_major, patchfile_ver_minor,
+ nfc_hal_cb.prm.spd_patch_count, patchfile_patch_present_mask, patchfile_patchsize);
+
+ /*********************************************************************
+ * Version check of patchfile against NVM
+ *********************************************************************/
+ /* Download the patchfile if no patches in NVM */
+ if ((nfc_hal_cb.nvm_cb.project_id == 0) || !(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_PATCH_PRESENT))
+ {
+ /* No patch in NVM, need to download all */
+ nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+ if (nfc_hal_cb.dev_cb.brcm_hw_id == BRCM_20795A1_ID)
+ {
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_RM_RF;
+ nfc_hal_cb.prm.p_param = (void *)nfc_hal_prm_rm_rf_20795a1;
+ nfc_hal_cb.prm.param_idx = 0;
+ }
+
+ HAL_TRACE_DEBUG2 ("No previous patch detected. Downloading patch %i.%i",
+ patchfile_ver_major, patchfile_ver_minor);
+ }
+ /* Skip download if project ID of patchfile does not match NVM */
+ else if (nfc_hal_cb.nvm_cb.project_id != patchfile_project_id)
+ {
+ /* Project IDs mismatch */
+ HAL_TRACE_DEBUG2 ("Patch download skipped: Mismatched Project ID (NVM ProjId: 0x%04x, Patchfile ProjId: 0x%04x)",
+ nfc_hal_cb.nvm_cb.project_id, patchfile_project_id);
+
+ return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+ }
+ /* Skip download if version of patchfile is equal to version in NVM */
+ /* and patches of the power modes are the same as the good patches in NVM */
+ else if ( (nfc_hal_cb.nvm_cb.ver_major == patchfile_ver_major)
+ &&(nfc_hal_cb.nvm_cb.ver_minor == patchfile_ver_minor)
+ &&((nvm_patch_present_mask | patchfile_patch_present_mask) == nvm_patch_present_mask) ) /* if the NVM patch include all the patched in file */
+ {
+ HAL_TRACE_DEBUG2 ("Patch download skipped. NVM patch (version %i.%i) is the same than the patchfile ",
+ nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+
+ return_code = NFC_HAL_PRM_COMPLETE_EVT;
+ }
+ /* Remaining cases: Download all patches in the patchfile */
+ else
+ {
+ nfc_hal_cb.prm.spd_patch_needed_mask = patchfile_patch_present_mask;
+
+ HAL_TRACE_DEBUG4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+ patchfile_ver_major, patchfile_ver_minor,
+ nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+ }
+
+ }
+ else
+ {
+ /* Invalid patch file header */
+ HAL_TRACE_ERROR0 ("Invalid patch file header.");
+
+ return_code = NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT;
+ }
+
+ /* If we need to download anything, get the first patch to download */
+ if (nfc_hal_cb.prm.spd_patch_needed_mask)
+ {
+ HAL_TRACE_ERROR4 ("Downloading patch version: %i.%i (previous version in NVM: %i.%i)...",
+ patchfile_ver_major, patchfile_ver_minor,
+ nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+ /* Check if I2C patch is needed: if */
+ /* - I2C patch file was provided using HAL_NfcPrmSetI2cPatch, and */
+ /* - current patch in NVM has ProjectID=0, or */
+ /* FPM is not present or corrupted, or */
+ /* or patchfile is major-ver 76+ */
+ /* or patchfile is not for B3 (always download for B4 onward) */
+ if ( (nfc_hal_cb.prm_i2c.p_patch)
+ &&( (nfc_hal_cb.nvm_cb.project_id == 0)
+ ||(nfc_hal_cb.nvm_cb.fpm_size == 0)
+ ||(nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_FPM_BAD)
+ ||(patchfile_ver_major >= 76)
+ ||(!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3)) ))
+ {
+ HAL_TRACE_DEBUG0 ("I2C patch fix required.");
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+ }
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+ nfc_hal_prm_spd_check_version_continue ();
+ }
+ else
+ {
+ static BOOLEAN firstTime = TRUE;
+ if (firstTime)
+ {
+ HAL_TRACE_ERROR2 ("NVM patch version is %d.%d",
+ nfc_hal_cb.nvm_cb.ver_major, nfc_hal_cb.nvm_cb.ver_minor);
+ firstTime = FALSE;
+ }
+ /* Download complete */
+ nfc_hal_prm_spd_handle_download_complete (return_code);
+ }
+}
+
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_status_str
+**
+** Description Return status string for a given spd status code
+**
+** Returns Status string
+**
+*******************************************************************************/
+UINT8 *nfc_hal_prm_spd_status_str (UINT8 spd_status_code)
+{
+ char *p_str;
+
+ switch (spd_status_code)
+ {
+ case NCI_STATUS_SPD_ERROR_DEST:
+ p_str = "SPD_ERROR_DEST";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_PROJECTID:
+ p_str = "SPD_ERROR_PROJECTID";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_CHIPVER:
+ p_str = "SPD_ERROR_CHIPVER";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_MAJORVER:
+ p_str = "SPD_ERROR_MAJORVER";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_INVALID_PARAM:
+ p_str = "SPD_ERROR_INVALID_PARAM";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_INVALID_SIG:
+ p_str = "SPD_ERROR_INVALID_SIG";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_NVM_CORRUPTED:
+ p_str = "SPD_ERROR_NVM_CORRUPTED";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_PWR_MODE:
+ p_str = "SPD_ERROR_PWR_MODE";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_MSG_LEN:
+ p_str = "SPD_ERROR_MSG_LEN";
+ break;
+
+ case NCI_STATUS_SPD_ERROR_PATCHSIZE:
+ p_str = "SPD_ERROR_PATCHSIZE";
+ break;
+
+ default:
+ p_str = "Unspecified Error";
+ break;
+
+ }
+
+ return ((UINT8*) p_str);
+}
+#endif /* (NFC_HAL_TRACE_VERBOSE == TRUE) */
+/*******************************************************************************
+**
+** Function nfc_hal_prm_nvm_rw_cmd
+**
+** Description Non Volatile Read Write Command; for now only write zeros
+**
+** Returns TRUE if done.
+**
+*******************************************************************************/
+static BOOLEAN nfc_hal_prm_nvm_rw_cmd(void)
+{
+ tNFC_HAL_PRM_RM_RF *p_param = (tNFC_HAL_PRM_RM_RF *)(nfc_hal_cb.prm.p_param);
+ UINT8 *p_buff, *p, *p_end;
+ UINT8 len = 0;
+ UINT16 cmd_len;
+
+ if (p_param)
+ len = p_param[nfc_hal_cb.prm.param_idx].len;
+ HAL_TRACE_DEBUG2 ("nfc_hal_prm_nvm_rw_cmd: %d/%d", nfc_hal_cb.prm.param_idx, len);
+ if (len == 0)
+ {
+ return TRUE;
+ }
+ cmd_len = len + 7;
+
+ if ((p_buff = (UINT8 *) GKI_getbuf(cmd_len)) == NULL)
+ {
+ HAL_TRACE_ERROR0 ("NVM No buffer");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ return TRUE;
+ }
+
+ p = p_buff;
+
+ UINT8_TO_STREAM (p, (NCI_MTS_CMD|NCI_GID_PROP));
+ UINT8_TO_STREAM (p, NCI_MSG_EEPROM_RW);
+ UINT8_TO_STREAM (p, (len+4));
+ UINT8_TO_STREAM (p, 1); /* 1=write 0=read */
+ UINT16_TO_STREAM (p, p_param[nfc_hal_cb.prm.param_idx].offset);
+ UINT8_TO_STREAM (p, len);
+ memset (p, 0, len); /* Fill remaining bytes with zeros*/
+
+ nfc_hal_cb.prm.param_idx++;
+ nfc_hal_dm_send_nci_cmd(p_buff, cmd_len, nfc_hal_prm_nci_command_complete_cback);
+ GKI_freebuf (p_buff);
+ return FALSE;
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_nci_command_complete_cback
+**
+** Description Callback for NCI vendor specific command complete
+** (for secure patch download)
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_nci_command_complete_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
+{
+ UINT8 status, u8;
+ UINT8 *p;
+ UINT32 post_signature_delay;
+
+ NFC_HAL_PRM_STATE ("nfc_hal_prm_nci_command_complete_cback");
+
+ /* Stop the command-timeout timer */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+ /* Skip over NCI header */
+ p = p_data + NCI_MSG_HDR_SIZE;
+
+ /* Handle SECURE_PATCH_DOWNLOAD Rsp */
+ if (event == NFC_VS_SEC_PATCH_DOWNLOAD_EVT)
+ {
+ /* Status and error code */
+ STREAM_TO_UINT8 (status, p);
+ STREAM_TO_UINT8 (u8, p);
+
+ if (status != NCI_STATUS_OK)
+ {
+#if (NFC_HAL_TRACE_VERBOSE == TRUE)
+ HAL_TRACE_ERROR2 ("Patch download failed, reason code=0x%X (%s)", status, nfc_hal_prm_spd_status_str (status));
+#else
+ HAL_TRACE_ERROR1 ("Patch download failed, reason code=0x%X", status);
+#endif
+
+ /* Notify application */
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ return;
+ }
+
+ /* If last segment (SIGNATURE) sent */
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_SIGNATURE_SENT)
+ {
+ /* Wait for authentication complete (SECURE_PATCH_DOWNLOAD NTF), including time to commit to NVM (for BCM43341B0) */
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTHENTICATING;
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+ (NFC_HAL_PRM_COMMIT_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ return;
+ }
+ /* Download next segment */
+ else if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+ {
+ /* If patch is in a buffer, get next patch from buffer */
+ nfc_hal_prm_spd_send_next_segment ();
+ }
+ else
+ {
+ /* Notify adaptation layer to get next patch segment (via HAL_NfcPrmDownloadContinue) */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_CONTINUE_EVT);
+ }
+ }
+ /* Handle SECURE_PATCH_DOWNLOAD NTF */
+ else if (event == NFC_VS_SEC_PATCH_AUTH_EVT)
+ {
+ HAL_TRACE_DEBUG1 ("prm flags:0x%x.", nfc_hal_cb.prm.flags);
+ /* Status and error code */
+ STREAM_TO_UINT8 (status, p);
+ STREAM_TO_UINT8 (u8, p);
+
+ /* Sanity check - should only get this NTF while in AUTHENTICATING stage */
+ if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTHENTICATING)
+ {
+ if (status != NCI_STATUS_OK)
+ {
+ HAL_TRACE_ERROR0 ("Patch authentication failed");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_BAD_SIGNATURE_EVT);
+ return;
+ }
+
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED)
+ {
+ HAL_TRACE_DEBUG1 ("PreI2C patch downloaded...waiting %i ms for NFCC to reboot.", nfc_hal_cb.prm_i2c.prei2c_delay);
+
+ /* Restore pointers to patchfile */
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_I2C_FIX_REQUIRED;
+ nfc_hal_cb.prm.p_cur_patch_data = nfc_hal_cb.prm.p_spd_patch;
+ nfc_hal_cb.prm.cur_patch_offset = nfc_hal_cb.prm.spd_patch_offset;
+ nfc_hal_cb.prm.cur_patch_len_remaining = nfc_hal_cb.prm.spd_patch_len_remaining;
+
+ /* Resume normal patch download */
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+ /* Post PreI2C delay */
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00, (nfc_hal_cb.prm_i2c.prei2c_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+
+ return;
+ }
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+
+
+ /* Wait for NFCC to save the patch to NVM */
+ if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
+ {
+ /* 20791B4 or newer - wait for RESET_NTF; including time to commit to NVM (for BCM20791B4+) */
+ post_signature_delay = NFC_HAL_PRM_COMMIT_DELAY;
+ HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for RESET NTF...", post_signature_delay);
+
+ }
+ else if (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM)
+ {
+ /* No NVM. Wait for NFCC to restart */
+ post_signature_delay = NFC_HAL_PRM_END_DELAY;
+ HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NFCC to restart...", post_signature_delay);
+ }
+ else
+ {
+ /* Wait for NFCC to save the patch to NVM (need about 1 ms per byte) */
+ post_signature_delay = nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].len;
+ if (post_signature_delay < nfc_hal_cb.prm.patchram_delay)
+ post_signature_delay = nfc_hal_cb.prm.patchram_delay;
+ HAL_TRACE_DEBUG1 ("Patch downloaded and authenticated. Waiting %i ms for NVM update to complete...", post_signature_delay);
+ }
+
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_AUTH_DONE;
+
+ nfc_hal_main_start_quick_timer (&nfc_hal_cb.prm.timer, 0x00,
+ (post_signature_delay * QUICK_TIMER_TICKS_PER_SEC) / 1000);
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("Got unexpected SECURE_PATCH_DOWNLOAD NTF");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ }
+ }
+ /* Handle NCI_MSG_GET_PATCH_VERSION RSP */
+ else if (event == NFC_VS_GET_PATCH_VERSION_EVT)
+ {
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+ }
+ else if (event == NFC_VS_EEPROM_RW_EVT)
+ {
+ STREAM_TO_UINT8 (status, p);
+ if (status == NCI_STATUS_OK)
+ {
+ if (nfc_hal_prm_nvm_rw_cmd ())
+ {
+ nfc_hal_prm_spd_check_version_continue ();
+ }
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("NVM failed");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ }
+ }
+ else
+ {
+ /* Invalid response from NFCC during patch download */
+ HAL_TRACE_ERROR1 ("Invalid response from NFCC during patch download (opcode=0x%02X)", event);
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_INVALID_PATCH_EVT);
+ }
+
+ NFC_HAL_PRM_STATE ("prm_nci_command_complete_cback");
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_nfcc_ready_to_continue
+**
+** Description Continue to download patch or notify application completition
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_nfcc_ready_to_continue (void)
+{
+ UINT8 get_patch_version_cmd [NCI_MSG_HDR_SIZE] =
+ {
+ NCI_MTS_CMD|NCI_GID_PROP,
+ NCI_MSG_GET_PATCH_VERSION,
+ 0x00
+ };
+
+ /* Clear the bit for the patch we just downloaded */
+ nfc_hal_cb.prm.spd_patch_needed_mask &= ~ ((UINT32) 1 << nfc_hal_cb.prm.spd_patch_desc[nfc_hal_cb.prm.spd_cur_patch_idx].power_mode);
+
+ /* Check if another patch to download */
+ nfc_hal_cb.prm.spd_cur_patch_idx++;
+ if ((nfc_hal_cb.prm.spd_patch_needed_mask) && (nfc_hal_cb.prm.spd_cur_patch_idx < nfc_hal_cb.prm.spd_patch_count))
+ {
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER;
+ nfc_hal_cb.prm.flags &= ~NFC_HAL_PRM_FLAGS_SIGNATURE_SENT;
+
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+ {
+ /* If patch is in a buffer, get next patch from buffer */
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+ else
+ {
+ /* Notify adaptation layer to get next patch header (via HAL_NfcPrmDownloadContinue) */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_NEXT_PATCH);
+ }
+
+ }
+ else
+ {
+ /* Done downloading */
+ HAL_TRACE_DEBUG0 ("Patch downloaded and authenticated. Get new patch version.");
+ /* add get patch info again to verify the effective FW version */
+ nfc_hal_dm_send_nci_cmd (get_patch_version_cmd, NCI_MSG_HDR_SIZE, nfc_hal_prm_nci_command_complete_cback);
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_W4_GET_VERSION;
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_spd_reset_ntf
+**
+** Description Received RESET NTF from NFCC, indicating it has completed
+** reset after patch download.
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_spd_reset_ntf (UINT8 reset_reason, UINT8 reset_type)
+{
+ /* Check if we were expecting a RESET NTF */
+ if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+ {
+ HAL_TRACE_DEBUG2 ("Received RESET NTF after patch download (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+
+ /* Stop waiting for RESET NTF */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+
+ {
+ /* Continue with patch download */
+ nfc_hal_prm_nfcc_ready_to_continue ();
+ }
+ }
+ else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+ {
+ HAL_TRACE_DEBUG0 ("Received RESET NTF after pre-I2C patch download. Proceeding with patch download...");
+
+ /* Stop waiting for RESET NTF */
+ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.prm.timer);
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+ else
+ {
+ HAL_TRACE_ERROR2 ("Received unexpected RESET NTF (reset_reason=%i, reset_type=%i)", reset_reason, reset_type);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: nfc_post_final_baud_update
+**
+** Description: Called after baud rate udate
+**
+** Returns: Nothing
+**
+*******************************************************************************/
+void nfc_hal_prm_post_baud_update (tHAL_NFC_STATUS status)
+{
+ NFC_HAL_PRM_STATE ("nfc_hal_prm_post_baud_update");
+
+ if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+ {
+ /* Proceed with next step of patch download sequence */
+ nfc_hal_prm_nfcc_ready_to_continue ();
+ }
+}
+
+/*******************************************************************************
+**
+** Function nfc_hal_prm_process_timeout
+**
+** Description Process timer expireation for patch download
+**
+** Returns void
+**
+*******************************************************************************/
+void nfc_hal_prm_process_timeout (void *p_tle)
+{
+ NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+
+ if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_AUTH_DONE)
+ {
+ if (!(nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_BCM20791B3))
+ {
+ /* Timeout waiting for RESET NTF after signature sent */
+ HAL_TRACE_ERROR0 ("Timeout waiting for RESET NTF after patch download");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ }
+ else
+ {
+ nfc_hal_prm_nfcc_ready_to_continue ();
+ }
+ }
+ else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+ {
+ HAL_TRACE_DEBUG0 ("Delay after PreI2C patch download...proceeding to download firmware patch");
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+ else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_W4_GET_VERSION)
+ {
+ HAL_TRACE_DEBUG0 ("get patch version timeout???");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_COMPLETE_EVT);
+ }
+ else
+ {
+ HAL_TRACE_ERROR1 ("Patch download: command timeout (state=%i)", nfc_hal_cb.prm.state);
+
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_EVT);
+ }
+
+ NFC_HAL_PRM_STATE ("nfc_hal_prm_process_timeout");
+}
+
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmDownloadStart
+**
+** Description Initiate patch download
+**
+** Input Params
+** format_type patch format type
+** (NFC_HAL_PRM_FORMAT_BIN, NFC_HAL_PRM_FORMAT_HCD, or
+** NFC_HAL_PRM_FORMAT_NCD)
+**
+** dest_address destination adderess (needed for BIN format only)
+**
+** p_patchram_buf pointer to patchram buffer. If NULL,
+** then app must call HAL_NfcPrmDownloadContinue when
+** NFC_HAL_PRM_CONTINUE_EVT is received, to send the next
+** segment of patchram
+**
+** patchram_len size of p_patchram_buf (if non-NULL)
+**
+** patchram_delay The delay after each patch.
+** If the given value is less than the size of the patchram,
+** the size of patchram is used instead.
+**
+** p_cback callback for download status
+**
+**
+** Returns TRUE if successful, otherwise FALSE
+**
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadStart (tNFC_HAL_PRM_FORMAT format_type,
+ UINT32 dest_address,
+ UINT8 *p_patchram_buf,
+ UINT32 patchram_len,
+ UINT32 patchram_delay,
+ tNFC_HAL_PRM_CBACK *p_cback)
+{
+ HAL_TRACE_API0 ("HAL_NfcPrmDownloadStart ()");
+
+ memset (&nfc_hal_cb.prm, 0, sizeof (tNFC_HAL_PRM_CB));
+
+ if (p_patchram_buf)
+ {
+ nfc_hal_cb.prm.p_cur_patch_data = p_patchram_buf;
+ nfc_hal_cb.prm.cur_patch_offset = 0;
+ nfc_hal_cb.prm.cur_patch_len_remaining = (UINT16) patchram_len;
+ nfc_hal_cb.prm.flags |= NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF;
+
+ if (patchram_len == 0)
+ return FALSE;
+ }
+
+ nfc_hal_cb.prm.p_cback = p_cback;
+ nfc_hal_cb.prm.dest_ram = dest_address;
+ nfc_hal_cb.prm.format = format_type;
+ nfc_hal_cb.prm.patchram_delay = patchram_delay;
+
+ nfc_hal_cb.prm.timer.p_cback = nfc_hal_prm_process_timeout;
+
+ if (format_type == NFC_HAL_PRM_FORMAT_NCD)
+ {
+ /* Store patch buffer pointer and length */
+ nfc_hal_cb.prm.p_spd_patch = p_patchram_buf;
+ nfc_hal_cb.prm.spd_patch_len_remaining = (UINT16)patchram_len;
+ nfc_hal_cb.prm.spd_patch_offset = 0;
+
+ /* If patch download is required, but no NVM is available, then abort */
+ if ((p_nfc_hal_cfg->nfc_hal_prm_nvm_required) && (nfc_hal_cb.nvm_cb.flags & NFC_HAL_NVM_FLAGS_NO_NVM))
+ {
+ HAL_TRACE_ERROR0 ("This platform requires NVM and the NVM is not available - Abort");
+ nfc_hal_prm_spd_handle_download_complete (NFC_HAL_PRM_ABORT_NO_NVM_EVT);
+ return FALSE;
+ }
+
+ /* Compare patch version in NVM with version in patchfile */
+ nfc_hal_cb.prm.state = NFC_HAL_PRM_ST_SPD_COMPARE_VERSION;
+ if (nfc_hal_cb.prm.flags & NFC_HAL_PRM_FLAGS_USE_PATCHRAM_BUF)
+ {
+ /* If patchfile is in a buffer, get patch version from buffer */
+ nfc_hal_prm_spd_check_version ();
+ }
+ else
+ {
+ /* If patchfile is not in a buffer, then request patchfile header from adaptation layer. */
+ (nfc_hal_cb.prm.p_cback) (NFC_HAL_PRM_SPD_GET_PATCHFILE_HDR_EVT);
+ }
+ }
+ else
+ {
+ HAL_TRACE_ERROR0 ("Unexpected patch format.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmDownloadContinue
+**
+** Description Send next segment of patchram to controller. Called when
+** NFC_HAL_PRM_CONTINUE_EVT is received.
+**
+** Only needed if HAL_NfcPrmDownloadStart was called with
+** p_patchram_buf=NULL
+**
+** Input Params p_patch_data pointer to patch data
+** patch_data_len patch data len
+**
+** Returns TRUE if successful, otherwise FALSE
+**
+*******************************************************************************/
+BOOLEAN HAL_NfcPrmDownloadContinue (UINT8 *p_patch_data,
+ UINT16 patch_data_len)
+{
+ HAL_TRACE_API2 ("HAL_NfcPrmDownloadContinue ():state = %d, patch_data_len=%d",
+ nfc_hal_cb.prm.state, patch_data_len);
+
+ /* Check if we are in a valid state for this API */
+ if ( (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+ &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+ &&(nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_SPD_DOWNLOADING) )
+ return FALSE;
+
+ if (patch_data_len == 0)
+ return FALSE;
+
+ nfc_hal_cb.prm.cur_patch_offset = 0;
+ nfc_hal_cb.prm.p_cur_patch_data = p_patch_data;
+ nfc_hal_cb.prm.cur_patch_len_remaining = patch_data_len;
+
+ /* Call appropriate handler */
+ if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_COMPARE_VERSION)
+ {
+ nfc_hal_prm_spd_check_version ();
+ }
+ else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_GET_PATCH_HEADER)
+ {
+ nfc_hal_prm_spd_handle_next_patch_start ();
+ }
+ else if (nfc_hal_cb.prm.state == NFC_HAL_PRM_ST_SPD_DOWNLOADING)
+ {
+ nfc_hal_prm_spd_send_next_segment ();
+ }
+ else
+ {
+ HAL_TRACE_ERROR1 ("Unexpected patch state:%d.", nfc_hal_cb.prm.state);
+ }
+
+ return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmSetI2cPatch
+**
+** Description Specify patchfile for BCM20791B3 I2C fix. This fix
+** must be downloaded prior to initial patch download for I2C
+** transport
+**
+** Input Params p_i2c_patchfile_buf: pointer to patch for i2c fix
+** i2c_patchfile_len: length of patch
+** prei2c_delay: the delay before downloading main patch
+** if 0 is given, NFC_HAL_PRM_POST_I2C_FIX_DELAY is used instead.
+**
+** Returns Nothing
+**
+**
+*******************************************************************************/
+void HAL_NfcPrmSetI2cPatch (UINT8 *p_i2c_patchfile_buf, UINT16 i2c_patchfile_len, UINT32 prei2c_delay)
+{
+#if (defined (NFC_HAL_PRE_I2C_PATCH_INCLUDED) && (NFC_HAL_PRE_I2C_PATCH_INCLUDED == TRUE))
+ HAL_TRACE_API0 ("HAL_NfcPrmSetI2cPatch ()");
+
+ nfc_hal_cb.prm_i2c.prei2c_delay = NFC_HAL_PRM_POST_I2C_FIX_DELAY;
+ if (prei2c_delay)
+ nfc_hal_cb.prm_i2c.prei2c_delay = prei2c_delay;
+ nfc_hal_cb.prm_i2c.p_patch = p_i2c_patchfile_buf;
+ nfc_hal_cb.prm_i2c.len = i2c_patchfile_len;
+#endif /* NFC_HAL_PRE_I2C_PATCH_INCLUDED */
+}
+
+/*******************************************************************************
+**
+** Function HAL_NfcPrmSetSpdNciCmdPayloadSize
+**
+** Description Set Host-to-NFCC NCI message size for secure patch download
+**
+** This API must be called before calling HAL_NfcPrmDownloadStart.
+** If the API is not called, then PRM will use the default
+** message size.
+**
+** Typically, this API is only called for platforms that have
+** message-size limitations in the transport/driver.
+**
+** Valid message size range: NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE to 255.
+**
+** Returns HAL_NFC_STATUS_OK if successful
+** HAL_NFC_STATUS_FAILED otherwise
+**
+**
+*******************************************************************************/
+tHAL_NFC_STATUS HAL_NfcPrmSetSpdNciCmdPayloadSize (UINT8 max_payload_size)
+{
+ /* Validate: minimum size is NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE */
+ if (max_payload_size < NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE)
+ {
+ HAL_TRACE_ERROR2 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: invalid size (%i). Must be between %i and 255", max_payload_size, NFC_HAL_PRM_MIN_NCI_CMD_PAYLOAD_SIZE);
+ return (HAL_NFC_STATUS_FAILED);
+ }
+ else
+ {
+ HAL_TRACE_API1 ("HAL_NfcPrmSetSpdNciCmdPayloadSize: new message size during download: %i", max_payload_size);
+ nfc_hal_cb.ncit_cb.nci_ctrl_size = max_payload_size;
+ return (HAL_NFC_STATUS_OK);
+ }
+}
diff --git a/halimpl/bcm2079x/include/HalAdaptation.h b/halimpl/bcm2079x/include/HalAdaptation.h
new file mode 100644
index 0000000..9599c07
--- /dev/null
+++ b/halimpl/bcm2079x/include/HalAdaptation.h
@@ -0,0 +1,66 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * HAL Adaptation Interface (HAI). This interface regulates the interaction
+ * between standard Android HAL and Broadcom-specific HAL. It adapts
+ * Broadcom-specific features to the Android framework.
+ *
+ ******************************************************************************/
+#pragma once
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct
+{
+ struct nfc_nci_device nci_device;
+ //below declarations are private variables within Broadcom HAL
+ void* data;
+}
+bcm2079x_dev_t;
+
+
+/*
+All functions return POSIX error codes (see errno):
+ 0 means success.
+ non-zero means failure; for example EACCES.
+*/
+
+
+extern int HaiInitializeLibrary (const bcm2079x_dev_t* device);
+extern int HaiTerminateLibrary ();
+extern int HaiOpen (const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc, nfc_stack_data_callback_t* halDataCallbackFunc);
+extern int HaiClose (const bcm2079x_dev_t* device);
+extern int HaiCoreInitialized (const bcm2079x_dev_t* device, uint8_t* coreInitResponseParams);
+extern int HaiWrite (const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data);
+extern int HaiPreDiscover (const bcm2079x_dev_t* device);
+extern int HaiControlGranted (const bcm2079x_dev_t* device);
+extern int HaiPowerCycle (const bcm2079x_dev_t* device);
+extern int HaiGetMaxNfcee (const bcm2079x_dev_t* device, uint8_t* maxNfcee);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/OverrideLog.h b/halimpl/bcm2079x/include/OverrideLog.h
new file mode 100644
index 0000000..a441cbd
--- /dev/null
+++ b/halimpl/bcm2079x/include/OverrideLog.h
@@ -0,0 +1,70 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Override the Android logging macro(s) from
+ * /system/core/include/cutils/log.h. This header must be the first header
+ * included by a *.cpp file so the original Android macro can be replaced.
+ * Do not include this header in another header, because that will create
+ * unnecessary dependency.
+ *
+ ******************************************************************************/
+#pragma once
+
+//Override Android's ALOGD macro by adding a boolean expression.
+#define ALOGD(...) ((void)ALOGD_IF(appl_trace_level>=BT_TRACE_LEVEL_DEBUG, __VA_ARGS__))
+
+
+#include <cutils/log.h> //define Android logging macros
+#include "bt_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern unsigned char appl_trace_level;
+extern UINT32 ScrProtocolTraceFlag;
+
+
+/*******************************************************************************
+**
+** Function: InitializeGlobalAppLogLevel
+**
+** Description: Initialize and get global logging level from .conf or
+** Android property nfc.app_log_level. The Android property
+** overrides .conf variable.
+**
+** Returns: Global log level:
+** BT_TRACE_LEVEL_NONE 0 * No trace messages to be generated
+** BT_TRACE_LEVEL_ERROR 1 * Error condition trace messages
+** BT_TRACE_LEVEL_WARNING 2 * Warning condition trace messages
+** BT_TRACE_LEVEL_API 3 * API traces
+** BT_TRACE_LEVEL_EVENT 4 * Debug messages for events
+** BT_TRACE_LEVEL_DEBUG 5 * Debug messages (general)
+**
+*******************************************************************************/
+unsigned char InitializeGlobalAppLogLevel ();
+UINT32 InitializeProtocolLogLevel ();
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/halimpl/bcm2079x/include/StartupConfig.h b/halimpl/bcm2079x/include/StartupConfig.h
new file mode 100644
index 0000000..e56a83c
--- /dev/null
+++ b/halimpl/bcm2079x/include/StartupConfig.h
@@ -0,0 +1,93 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Construct a buffer that contains multiple Type-Length-Value contents
+ * that is used by the HAL in a CORE_SET_CONFIG NCI command.
+ ******************************************************************************/
+
+#pragma once
+#include "bt_types.h"
+#include <string>
+
+
+class StartupConfig
+{
+public:
+ typedef std::basic_string<UINT8> uint8_string;
+ StartupConfig ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: initialize
+ **
+ ** Description: Reset all member variables.
+ **
+ ** Returns: None
+ **
+ *******************************************************************************/
+ void initialize ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: getInternalBuffer
+ **
+ ** Description: Get the pointer to buffer that contains multiple
+ ** Type-Length-Value contents.
+ **
+ ** Returns: Pointer to buffer.
+ **
+ *******************************************************************************/
+ const UINT8* getInternalBuffer ();
+
+
+ /*******************************************************************************
+ **
+ ** Function: append
+ **
+ ** Description: Append new config data to internal buffer.
+ ** newContent: buffer containing new content; newContent[0] is
+ ** payload length; newContent[1..end] is payload.
+ ** newContentLen: total length of newContent.
+ **
+ ** Returns: True if ok.
+ **
+ *******************************************************************************/
+ bool append (const UINT8* newContent, UINT8 newContentLen);
+
+
+ /*******************************************************************************
+ **
+ ** Function: disableSecureElement
+ **
+ ** Description: Adjust a TLV to disable secure element(s). The TLV's type is 0xC2.
+ ** bitmask: 0xC0 = do not detect any secure element.
+ ** 0x40 = do not detect secure element in slot 0.
+ ** 0x80 = do not detect secure element in slot 1.
+ **
+ ** Returns: True if ok.
+ **
+ *******************************************************************************/
+ bool disableSecureElement (UINT8 bitmask);
+
+private:
+ static const UINT8 mMaxLength;
+ uint8_string mBuffer;
+};
diff --git a/halimpl/bcm2079x/include/android_logmsg.h b/halimpl/bcm2079x/include/android_logmsg.h
new file mode 100644
index 0000000..9922893
--- /dev/null
+++ b/halimpl/bcm2079x/include/android_logmsg.h
@@ -0,0 +1,65 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2011-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ * Decode NFC packets and print them to ADB log.
+ * If protocol decoder is not present, then decode packets into hex numbers.
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "data_types.h"
+
+
+#define DISP_NCI ProtoDispAdapterDisplayNciPacket
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+void ProtoDispAdapterUseRawOutput (BOOLEAN isUseRaw);
+void ScrLog (UINT32 trace_set_mask, const char* fmt_str, ...);
+void LogMsg (UINT32 trace_set_mask, const char *fmt_str, ...);
+void LogMsg_0 (UINT32 trace_set_mask, const char *p_str);
+void LogMsg_1 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1);
+void LogMsg_2 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2);
+void LogMsg_3 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3);
+void LogMsg_4 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4);
+void LogMsg_5 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5);
+void LogMsg_6 (UINT32 trace_set_mask, const char *fmt_str, UINT32 p1, UINT32 p2, UINT32 p3, UINT32 p4, UINT32 p5, UINT32 p6);
+UINT8* scru_dump_hex (UINT8* p, char* pTitle, UINT32 len, UINT32 layer, UINT32 type);
+void BTDISP_LOCK_LOG();
+void BTDISP_UNLOCK_LOG();
+void BTDISP_INIT_LOCK();
+void BTDISP_UNINIT_LOCK();
+void DispHciCmd (BT_HDR* p_buf);
+void DispHciEvt (BT_HDR* p_buf);
+void DispLLCP (BT_HDR *p_buf, BOOLEAN is_recv);
+void DispHcp (UINT8 *data, UINT16 len, BOOLEAN is_recv);
+void DispSNEP (UINT8 local_sap, UINT8 remote_sap, BT_HDR *p_buf, BOOLEAN is_first, BOOLEAN is_rx);
+void DispCHO (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_rx);
+void DispT3TagMessage(BT_HDR *p_msg, BOOLEAN is_rx);
+void DispRWT4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+void DispCET4Tags (BT_HDR *p_buf, BOOLEAN is_rx);
+void DispRWI93Tag (BT_HDR *p_buf, BOOLEAN is_rx, UINT8 command_to_respond);
+void DispNDEFMsg (UINT8 *pMsg, UINT32 MsgLen, BOOLEAN is_recv);
+
+
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/halimpl/bcm2079x/include/bcm2079x.h b/halimpl/bcm2079x/include/bcm2079x.h
new file mode 100644
index 0000000..beb5786
--- /dev/null
+++ b/halimpl/bcm2079x/include/bcm2079x.h
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef _BCM2079X_H
+#define _BCM2079X_H
+
+#define BCMNFC_MAGIC 0xFA
+
+/*
+ * BCMNFC power control via ioctl
+ * BCMNFC_POWER_CTL(0): power off
+ * BCMNFC_POWER_CTL(1): power on
+ * BCMNFC_WAKE_CTL(0): wake off
+ * BCMNFC_WAKE_CTL(1): wake on
+ */
+#define BCMNFC_POWER_CTL _IO(BCMNFC_MAGIC, 0x01)
+#define BCMNFC_CHANGE_ADDR _IO(BCMNFC_MAGIC, 0x02)
+#define BCMNFC_READ_FULL_PACKET _IO(BCMNFC_MAGIC, 0x03)
+#define BCMNFC_SET_WAKE_ACTIVE_STATE _IO(BCMNFC_MAGIC, 0x04)
+#define BCMNFC_WAKE_CTL _IO(BCMNFC_MAGIC, 0x05)
+#define BCMNFC_READ_MULTI_PACKETS _IO(BCMNFC_MAGIC, 0x06)
+#define BCMNFC_SET_CLIENT_ADDR _IO(BCMNFC_MAGIC, 0x07)
+
+struct bcm2079x_platform_data {
+ unsigned int irq_gpio;
+ unsigned int en_gpio;
+ int wake_gpio;
+};
+
+#endif
diff --git a/halimpl/bcm2079x/include/buildcfg.h b/halimpl/bcm2079x/include/buildcfg.h
new file mode 100644
index 0000000..32cf681
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+#include <string.h>
+#include <memory.h>
+#include <stdio.h>
+#include "data_types.h"
+
+
+#define BTE_APPL_MAX_USERIAL_DEV_NAME (256)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern UINT8 *scru_dump_hex (UINT8 *p, char *p_title, UINT32 len, UINT32 trace_layer, UINT32 trace_type);
+void DispNci (UINT8 *p, UINT16 len, BOOLEAN is_recv);
+void ProtoDispAdapterDisplayNciPacket (UINT8* nciPacket, UINT16 nciPacketLen, BOOLEAN is_recv);
+#define DISP_NCI ProtoDispAdapterDisplayNciPacket
+#define LOGMSG_TAG_NAME "NfcNciHal"
+
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/halimpl/bcm2079x/include/buildcfg_hal.h b/halimpl/bcm2079x/include/buildcfg_hal.h
new file mode 100644
index 0000000..a8136b7
--- /dev/null
+++ b/halimpl/bcm2079x/include/buildcfg_hal.h
@@ -0,0 +1,31 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+//override any HAL-specific macros
+#pragma once
+
+#include "bt_types.h"
+
+//NFC_HAL_TASK=0 is already defined in gki_hal_target.h; it executes the Broadcom HAL
+#define USERIAL_HAL_TASK 1 //execute userial's read thread
+#define GKI_RUNNER_HAL_TASK 2 //execute GKI_run(), which runs forever
+#define GKI_MAX_TASKS 3 //total of 3 tasks
+
+#define GKI_BUF0_MAX 16
+#define GKI_BUF1_MAX 16
+
+#define NFC_HAL_PRM_POST_I2C_FIX_DELAY (500)
diff --git a/halimpl/bcm2079x/include/gki_target.h b/halimpl/bcm2079x/include/gki_target.h
new file mode 100644
index 0000000..afb4f78
--- /dev/null
+++ b/halimpl/bcm2079x/include/gki_target.h
@@ -0,0 +1,19 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+#pragma once
+#include "gki_hal_target.h"
diff --git a/halimpl/bcm2079x/include/spdhelper.h b/halimpl/bcm2079x/include/spdhelper.h
new file mode 100644
index 0000000..e496c98
--- /dev/null
+++ b/halimpl/bcm2079x/include/spdhelper.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <string>
+
+using namespace std;
+#define DEFAULT_SPD_MAXRETRYCOUNT (3)
+
+class SpdHelper
+{
+public:
+ static bool isPatchBad(UINT8* prm, UINT32 len);
+ static void setPatchAsBad();
+ static void incErrorCount();
+ static bool isSpdDebug();
+
+private:
+ SpdHelper();
+ static SpdHelper& getInstance();
+
+ bool isPatchBadImpl(UINT8* prm, UINT32 len);
+ void setPatchAsBadImpl();
+ void incErrorCountImpl();
+ bool isSpdDebugImpl() {return mSpdDebug;}
+ string mPatchId;
+ int mErrorCount;
+ int mMaxErrorCount;
+ bool mIsPatchBad;
+ bool mSpdDebug;
+};
diff --git a/halimpl/bcm2079x/include/userial.h b/halimpl/bcm2079x/include/userial.h
new file mode 100644
index 0000000..7ca7369
--- /dev/null
+++ b/halimpl/bcm2079x/include/userial.h
@@ -0,0 +1,289 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2001-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * This file contains serial definitions from WIDCOMM's Universal Embedded
+ * Drivers API.
+ *
+ ******************************************************************************/
+
+#ifndef USERIAL_H
+#define USERIAL_H
+
+/*******************************************************************************
+** Serial APIs
+*******************************************************************************/
+
+/**** 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
+
+typedef UINT8 tUSERIAL_PORT;
+
+/**** 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)
+
+
+/**** Flow Control ****/
+#define USERIAL_FC_NONE 0
+#define USERIAL_FC_HW 1
+#define USERIAL_FC_SW 2
+
+/**** Data Buffering Mechanism ****/
+#define USERIAL_BUF_BYTE 0
+#define USERIAL_BUF_GKI 1
+
+/**** Signals ****/
+#define USERIAL_SIG_RTSCTS 1
+#define USERIAL_SIG_DSRDTR (1<<1)
+#define USERIAL_SIG_RI (1<<2)
+#define USERIAL_SIG_CD (1<<3)
+#define USERIAL_SIG_DTE_DEVICE (1<<4)
+
+/**** Errors *****/
+#define USERIAL_ERR_OVERRUN 1
+#define USERIAL_ERR_PARITY (1<<1)
+#define USERIAL_ERR_FRAMING (1<<2)
+#define USERIAL_ERR_BREAK (1<<3)
+
+/**** Serial Operations ****/
+#define USERIAL_OP_FLUSH 0
+#define USERIAL_OP_FLUSH_RX 1
+#define USERIAL_OP_FLUSH_TX 2
+#define USERIAL_OP_BREAK_OFF 3
+#define USERIAL_OP_BREAK_ON 4
+#define USERIAL_OP_BAUD_RD 5
+#define USERIAL_OP_BAUD_WR 6
+#define USERIAL_OP_FMT_RD 7
+#define USERIAL_OP_FMT_WR 8
+#define USERIAL_OP_SIG_RD 9
+#define USERIAL_OP_SIG_WR 10
+#define USERIAL_OP_FC_RD 11
+#define USERIAL_OP_FC_WR 12
+#define USERIAL_OP_CTS_AS_WAKEUP 13 /* H4IBSS */
+#define USERIAL_OP_CTS_AS_FC 14 /* H4IBSS */
+
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+#define USERIAL_OP_SCO_UP 20 /* LINUX SCO */
+#define USERIAL_OP_SCO_DOWN 21 /* LINUX SCO */
+#endif
+
+typedef UINT8 tUSERIAL_OP;
+
+
+/**** Serial feature types ****/
+#define USERIAL_FEAT_PORT_1 0
+#define USERIAL_FEAT_PORT_2 1
+#define USERIAL_FEAT_PORT_3 2
+#define USERIAL_FEAT_PORT_4 3
+#define USERIAL_FEAT_BAUD_AUTO 4
+#define USERIAL_FEAT_BAUD_300 5
+#define USERIAL_FEAT_BAUD_600 6
+#define USERIAL_FEAT_BAUD_1200 7
+#define USERIAL_FEAT_BAUD_2400 8
+#define USERIAL_FEAT_BAUD_9600 9
+#define USERIAL_FEAT_BAUD_19200 10
+#define USERIAL_FEAT_BAUD_57600 11
+#define USERIAL_FEAT_BAUD_115200 12
+#define USERIAL_FEAT_BAUD_230400 13
+#define USERIAL_FEAT_BAUD_460800 14
+#define USERIAL_FEAT_BAUD_921600 15
+#define USERIAL_FEAT_STOPBITS_1 16
+#define USERIAL_FEAT_STOPBITS_1_5 17
+#define USERIAL_FEAT_STOPBITS_2 18
+#define USERIAL_FEAT_PARITY_NONE 19
+#define USERIAL_FEAT_PARITY_EVEN 20
+#define USERIAL_FEAT_PARITY_ODD 21
+#define USERIAL_FEAT_DATABITS_5 22
+#define USERIAL_FEAT_DATABITS_6 23
+#define USERIAL_FEAT_DATABITS_7 24
+#define USERIAL_FEAT_DATABITS_8 25
+#define USERIAL_FEAT_FC_NONE 26
+#define USERIAL_FEAT_FC_HW 27
+#define USERIAL_FEAT_FC_SW 28
+#define USERIAL_FEAT_BUF_BYTE 29
+#define USERIAL_FEAT_BUF_GKI 30
+#define USERIAL_FEAT_SIG_RTS 31
+#define USERIAL_FEAT_SIG_CTS 32
+#define USERIAL_FEAT_SIG_DSR 33
+#define USERIAL_FEAT_SIG_DTR 34
+#define USERIAL_FEAT_SIG_RI 35
+#define USERIAL_FEAT_SIG_CD 36
+#define USERIAL_FEAT_OP_FLUSH 37
+#define USERIAL_FEAT_OP_FLUSH_RX 38
+#define USERIAL_FEAT_OP_FLUSH_TX 39
+#define USERIAL_FEAT_OP_BREAK 40
+#define USERIAL_FEAT_OP_BAUD_RD 41
+#define USERIAL_FEAT_OP_BAUD_WR 42
+#define USERIAL_FEAT_OP_FMT_RD 43
+#define USERIAL_FEAT_OP_FMT_WR 44
+#define USERIAL_FEAT_OP_SIG_RD 45
+#define USERIAL_FEAT_OP_SIG_WR 46
+#define USERIAL_FEAT_OP_FC_RD 47
+#define USERIAL_FEAT_OP_FC_WR 48
+
+typedef UINT8 tUSERIAL_FEATURE;
+
+
+/**** Event types ****/
+#define USERIAL_RX_READY_EVT 0
+#define USERIAL_TX_DONE_EVT 1
+#define USERIAL_SIG_EVT 2
+#define USERIAL_ERR_EVT 3
+#define USERIAL_WAKEUP_EVT 4 /* H4IBSS */
+
+typedef UINT8 tUSERIAL_EVT;
+
+
+/* Structure used to configure serial port during open */
+typedef struct
+{
+ UINT16 fmt; /* Data format */
+ UINT8 baud; /* Baud rate */
+ UINT8 fc; /* Flow control */
+ UINT8 buf; /* Data buffering mechanism */
+ UINT8 pool; /* GKI buffer pool for received data */
+ UINT16 size; /* Size of GKI buffer pool */
+ UINT16 offset; /* Offset in GKI buffer pool */
+} tUSERIAL_OPEN_CFG;
+
+/* Union used to pass ioctl arguments */
+typedef union
+{
+ UINT16 fmt;
+ UINT8 baud;
+ UINT8 fc;
+ UINT8 sigs;
+#if (defined LINUX_OS) && (LINUX_OS == TRUE)
+ UINT16 sco_handle;
+#endif
+} tUSERIAL_IOCTL_DATA;
+
+
+/* Union to pass event data */
+typedef union
+{
+ UINT8 sigs;
+ UINT8 error;
+} tUSERIAL_EVT_DATA;
+
+/* callback for events */
+typedef void (tUSERIAL_CBACK)(tUSERIAL_PORT, tUSERIAL_EVT, tUSERIAL_EVT_DATA *);
+
+/*******************************************************************************
+** Function Prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+UDRV_API extern void USERIAL_Init(void *);
+UDRV_API extern void USERIAL_Open(tUSERIAL_PORT, tUSERIAL_OPEN_CFG *, tUSERIAL_CBACK *);
+UDRV_API extern void USERIAL_ReadBuf(tUSERIAL_PORT, BT_HDR **);
+UDRV_API extern UINT16 USERIAL_Read(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern BOOLEAN USERIAL_WriteBuf(tUSERIAL_PORT, BT_HDR *);
+UDRV_API extern UINT16 USERIAL_Write(tUSERIAL_PORT, UINT8 *, UINT16);
+UDRV_API extern void USERIAL_Ioctl(tUSERIAL_PORT, tUSERIAL_OP, tUSERIAL_IOCTL_DATA *);
+UDRV_API extern void USERIAL_Close(tUSERIAL_PORT);
+UDRV_API extern BOOLEAN USERIAL_Feature(tUSERIAL_FEATURE);
+UDRV_API extern BOOLEAN USERIAL_IsClosed();
+UDRV_API extern void USERIAL_SetPowerOffDelays(int,int);
+UDRV_API extern void USERIAL_PowerupDevice(tUSERIAL_PORT port);
+
+/*******************************************************************************
+ **
+ ** Function USERIAL_GetLineSpeed
+ **
+ ** Description This function convert USERIAL baud to line speed.
+ **
+ ** Output Parameter None
+ **
+ ** Returns line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT32 USERIAL_GetLineSpeed(UINT8 baud);
+/*******************************************************************************
+ **
+ ** Function USERIAL_GetBaud
+ **
+ ** Description This function convert line speed to USERIAL baud.
+ **
+ ** Output Parameter None
+ **
+ ** Returns line speed
+ **
+ *******************************************************************************/
+UDRV_API extern UINT8 USERIAL_GetBaud(UINT32 line_speed);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USERIAL_H */
diff --git a/halimpl/bcm2079x/nfc_nci.c b/halimpl/bcm2079x/nfc_nci.c
new file mode 100644
index 0000000..b293c2b
--- /dev/null
+++ b/halimpl/bcm2079x/nfc_nci.c
@@ -0,0 +1,189 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+
+#define LOG_TAG "NfcNciHal"
+#include "OverrideLog.h"
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <hardware/hardware.h>
+#include <hardware/nfc.h>
+#include "HalAdaptation.h"
+
+
+/*********************************
+ * NCI HAL method implementations.
+ *********************************/
+
+
+static int hal_open (const struct nfc_nci_device *p_dev, nfc_stack_callback_t *p_hal_cback, nfc_stack_data_callback_t *p_hal_data_callback)
+{
+ int retval = 0;
+ bcm2079x_dev_t *dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiOpen (dev, p_hal_cback, p_hal_data_callback);
+ return retval;
+}
+
+
+static int hal_write (const struct nfc_nci_device *p_dev,
+ uint16_t data_len, const uint8_t *p_data)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiWrite (dev, data_len, p_data);
+ return retval;
+}
+
+
+static int hal_core_initialized (const struct nfc_nci_device *p_dev,
+ uint8_t* p_core_init_rsp_params)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiCoreInitialized (dev, p_core_init_rsp_params);
+ return retval;
+}
+
+
+static int hal_pre_discover (const struct nfc_nci_device *p_dev)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiPreDiscover (dev);
+ return retval;
+}
+
+
+static int hal_close (const struct nfc_nci_device *p_dev)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiClose (dev);
+ return retval;
+}
+
+
+static int hal_control_granted (const struct nfc_nci_device *p_dev)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiControlGranted (dev);
+ return retval;
+}
+
+
+static int hal_power_cycle (const struct nfc_nci_device *p_dev)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiPowerCycle (dev);
+ return retval;
+}
+
+
+static int hal_get_max_nfcee (const struct nfc_nci_device *p_dev, uint8_t* maxNfcee)
+{
+ int retval = 0;
+ bcm2079x_dev_t* dev = (bcm2079x_dev_t*) p_dev;
+
+ retval = HaiGetMaxNfcee (dev, maxNfcee);
+ return retval;
+}
+
+
+/*************************************
+ * Generic device handling.
+ *************************************/
+
+
+/* Close an opened nfc device instance */
+static int nfc_close (hw_device_t *dev)
+{
+ int retval = 0;
+ free (dev);
+ retval = HaiTerminateLibrary ();
+ return retval;
+}
+
+
+static int nfc_open (const hw_module_t* module, const char* name, hw_device_t** device)
+{
+ ALOGD ("%s: enter; name=%s", __FUNCTION__, name);
+ int retval = 0; //0 is ok; -1 is error
+
+ if (strcmp (name, NFC_NCI_CONTROLLER) == 0)
+ {
+ bcm2079x_dev_t *dev = calloc (1, sizeof(bcm2079x_dev_t));
+
+ // Common hw_device_t fields
+ dev->nci_device.common.tag = HARDWARE_DEVICE_TAG;
+ dev->nci_device.common.version = 0x00010000; // [31:16] major, [15:0] minor
+ dev->nci_device.common.module = (struct hw_module_t*) module;
+ dev->nci_device.common.close = nfc_close;
+
+ // NCI HAL method pointers
+ dev->nci_device.open = hal_open;
+ dev->nci_device.write = hal_write;
+ dev->nci_device.core_initialized = hal_core_initialized;
+ dev->nci_device.pre_discover = hal_pre_discover;
+ dev->nci_device.close = hal_close;
+ dev->nci_device.control_granted = hal_control_granted;
+ dev->nci_device.power_cycle = hal_power_cycle;
+ //dev->nci_device.get_max_ee = hal_get_max_nfcee;
+
+
+ // Copy in
+ *device = (hw_device_t*) dev;
+
+ retval = HaiInitializeLibrary (dev);
+ }
+ else
+ {
+ retval = -EINVAL;
+ }
+ ALOGD ("%s: exit %d", __FUNCTION__, retval);
+ return retval;
+}
+
+
+static struct hw_module_methods_t nfc_module_methods =
+{
+ .open = nfc_open,
+};
+
+
+struct nfc_nci_module_t HAL_MODULE_INFO_SYM =
+{
+ .common =
+ {
+ .tag = HARDWARE_MODULE_TAG, .module_api_version = 0x0100, // [15:8] major, [7:0] minor (1.0)
+ .hal_api_version = 0x00, // 0 is only valid value
+ .id = NFC_NCI_BCM2079X_HARDWARE_MODULE_ID,
+ .name = "BCM2079x NFC NCI HW HAL",
+ .author = "Broadcom Corporation",
+ .methods = &nfc_module_methods,
+ },
+};
diff --git a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
index 725cd89..1333636 100644
--- a/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
+++ b/halimpl/pn54x/libnfc-nxp-PN547C2_example.conf
@@ -252,4 +252,4 @@
#1 = enabling adding aid to NFCC routing table.
#0 = disabling adding aid to NFCC routing table.
NXP_ENABLE_ADD_AID=0x01
-##################################################################################
\ No newline at end of file
+##################################################################################
diff --git a/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
new file mode 100644
index 0000000..eca60d8
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN548AD_example.conf
@@ -0,0 +1,265 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x)
+
+###############################################################################
+# Application options
+# Logging Levels
+# NXPLOG_DEFAULT_LOGLEVEL 0x01
+# ANDROID_LOG_DEBUG 0x03
+# ANDROID_LOG_WARN 0x02
+# ANDROID_LOG_ERROR 0x01
+# ANDROID_LOG_SILENT 0x00
+#
+NXPLOG_EXTNS_LOGLEVEL=0x03
+NXPLOG_NCIHAL_LOGLEVEL=0x03
+NXPLOG_NCIX_LOGLEVEL=0x03
+NXPLOG_NCIR_LOGLEVEL=0x03
+NXPLOG_FWDNLD_LOGLEVEL=0x03
+NXPLOG_TML_LOGLEVEL=0x03
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File location for Firmware
+#FW_STORAGE="/vendor/firmware/libpn548_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL 1
+#define CLK_SRC_PLL 2
+
+NXP_SYS_CLK_SRC_SEL=0x02
+
+###############################################################################
+# System clock frequency selection configuration
+#define CLK_FREQ_13MHZ 1
+#define CLK_FREQ_19_2MHZ 2
+#define CLK_FREQ_24MHZ 3
+#define CLK_FREQ_26MHZ 4
+#define CLK_FREQ_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x1A
+
+NXP_SYS_CLOCK_TO_CFG=0x01
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# NFCC Configuration Control
+# Allow NFCC to manage RF Config 0x01
+# Don't allow NFCC to manage RF Config 0x00
+NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01}
+
+###############################################################################
+# Standby enable settings
+#NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, There are currently three
+#configurations (1, 2 and 3) are supported, out of them only one can be
+#supported.
+
+NXP_EXT_TVDD_CFG=0x01
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A}
+
+###############################################################################
+#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC,
+#DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 15, 05,
+ A0, EC, 01, 01,
+ A0, ED, 01, 00,
+ A0, 5E, 01, 01,
+ A0, 40, 01, 01,
+ A0, DD, 01, 2D
+ }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set 01 ,to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01
+ }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2B, 0D,
+ 28, 01, 00,
+ 21, 01, 00,
+ 30, 01, 08,
+ 31, 01, 03,
+ 33, 04, 01, 02, 03, 04,
+ 54, 01, 06,
+ 50, 01, 02,
+ 5B, 01, 00,
+ 60, 01, 0E,
+ 80, 01, 01,
+ 81, 01, 01,
+ 82, 01, 0E,
+ 18, 01, 01
+ }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+# A0, 52, 06, D3, F7, D3, F7, D3, F7,
+# A0, 53, 06, FF, FF, FF, FF, FF, FF,
+# A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE 0x01
+# UICC 0x02
+
+NXP_DEFAULT_SE=0x03
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2 0x01
+#PN65T 0x02
+#PN548AD 0x03
+#PN66T 0x04
+
+NXP_NFC_CHIP=0x03
+
+###############################################################################
+# CE when Screen state is locked
+# Disable 0x00
+# Enable 0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+#Timeout in secs to get NFCEE Discover notification
+NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable 0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout 0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
diff --git a/halimpl/pn54x/libnfc-nxp-PN65T_example.conf b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
new file mode 100644
index 0000000..21f2c18
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN65T_example.conf
@@ -0,0 +1,269 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x)
+
+###############################################################################
+# Application options
+# Logging Levels
+# NXPLOG_DEFAULT_LOGLEVEL 0x01
+# ANDROID_LOG_DEBUG 0x03
+# ANDROID_LOG_WARN 0x02
+# ANDROID_LOG_ERROR 0x01
+# ANDROID_LOG_SILENT 0x00
+#
+NXPLOG_EXTNS_LOGLEVEL=0x03
+NXPLOG_NCIHAL_LOGLEVEL=0x03
+NXPLOG_NCIX_LOGLEVEL=0x03
+NXPLOG_NCIR_LOGLEVEL=0x03
+NXPLOG_FWDNLD_LOGLEVEL=0x03
+NXPLOG_TML_LOGLEVEL=0x03
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File location for Firmware
+#FW_STORAGE="/vendor/firmware/libpn547_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL 1
+#define CLK_SRC_PLL 2
+
+NXP_SYS_CLK_SRC_SEL=0x01
+
+###############################################################################
+# System clock frequency selection configuration
+#define CLK_FREQ_13MHZ 1
+#define CLK_FREQ_19_2MHZ 2
+#define CLK_FREQ_24MHZ 3
+#define CLK_FREQ_26MHZ 4
+#define CLK_FREQ_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+NXP_SYS_CLK_FREQ_SEL=0x00
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x19
+
+NXP_SYS_CLOCK_TO_CFG=0x01
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# Standby enable settings
+NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+#Atonomous Mode
+#Enable 0x01
+#Disable 0x00
+NXP_CORE_SCRN_OFF_AUTONOMOUS_ENABLE=0x00
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+# NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+NXP_CORE_CONF_EXTN={20, 02, 1A, 05,
+ A0, EC, 01, 01,
+ A0, ED, 01, 01,
+ A0, 5E, 01, 01,
+ A0, 12, 01, 02,
+ A0, 0D, 06, 3E, 2D, 15, 88, 15, 00
+ }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01
+ }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2B, 0D,
+ 28, 01, 00,
+ 21, 01, 00,
+ 30, 01, 08,
+ 31, 01, 03,
+ 33, 04, 01, 02, 03, 04,
+ 54, 01, 06,
+ 50, 01, 02,
+ 5B, 01, 00,
+ 60, 01, 0E,
+ 80, 01, 01,
+ 81, 01, 01,
+ 82, 01, 0E,
+ 18, 01, 01
+ }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+# A0, 52, 06, D3, F7, D3, F7, D3, F7,
+# A0, 53, 06, FF, FF, FF, FF, FF, FF,
+# A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE 0x01
+# UICC 0x02
+
+NXP_DEFAULT_SE=0x02
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+##############################################################################
+#### Select the CHIP ####
+#PN547C2 0x01
+#PN65T 0x02
+#PN548AD 0x03
+#PN66T 0x04
+
+NXP_NFC_CHIP=0x02
+
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0xFF
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0xFF
+
+###############################################################################
+# CE when Screen state is locked
+# Disable 0x00
+# Enable 0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+# P61 interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LS_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 LTSM interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LTSM_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable 0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout 0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
+
+###############################################################################
+# P61 interface options for JCOP Download
+# NFC 0x01
+# SPI 0x02
+NXP_P61_JCOP_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 JCOP OS download options
+# FRAMEWORK API BY APPLICATION 0x00
+# AT BOOT_TIME 0x01
+NXP_JCOPDL_AT_BOOT_ENABLE=0x00
+
+###############################################################################
+# Loader service version
+# NFC service checks for LS version 2.0 or 2.1
+# LS2.0 0x20
+# LS2.1 0x21
+# LS2.2 0x22
+# AT NFC service intialization
+NXP_LOADER_SERVICE_VERSION=0x21
diff --git a/halimpl/pn54x/libnfc-nxp-PN66T_example.conf b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
new file mode 100644
index 0000000..c96fbb3
--- /dev/null
+++ b/halimpl/pn54x/libnfc-nxp-PN66T_example.conf
@@ -0,0 +1,301 @@
+## This file is used by NFC NXP NCI HAL(external/libnfc-nci/halimpl/pn54x)
+## and NFC Service Java Native Interface Extensions (packages/apps/Nfc/nci/jni/extns/pn54x)
+
+###############################################################################
+# Application options
+# Logging Levels
+# NXPLOG_DEFAULT_LOGLEVEL 0x01
+# ANDROID_LOG_DEBUG 0x03
+# ANDROID_LOG_WARN 0x02
+# ANDROID_LOG_ERROR 0x01
+# ANDROID_LOG_SILENT 0x00
+#
+NXPLOG_EXTNS_LOGLEVEL=0x03
+NXPLOG_NCIHAL_LOGLEVEL=0x03
+NXPLOG_NCIX_LOGLEVEL=0x03
+NXPLOG_NCIR_LOGLEVEL=0x03
+NXPLOG_FWDNLD_LOGLEVEL=0x03
+NXPLOG_TML_LOGLEVEL=0x03
+
+###############################################################################
+# Extension for Mifare reader enable
+MIFARE_READER_ENABLE=0x01
+
+###############################################################################
+# Vzw Feature enable
+VZW_FEATURE_ENABLE=0x01
+
+###############################################################################
+# File location for Firmware
+#FW_STORAGE="/vendor/firmware/libpn548_fw.so"
+
+###############################################################################
+# System clock source selection configuration
+#define CLK_SRC_XTAL 1
+#define CLK_SRC_PLL 2
+
+NXP_SYS_CLK_SRC_SEL=0x02
+
+###############################################################################
+# System clock frequency selection configuration
+#define CLK_FREQ_13MHZ 1
+#define CLK_FREQ_19_2MHZ 2
+#define CLK_FREQ_24MHZ 3
+#define CLK_FREQ_26MHZ 4
+#define CLK_FREQ_38_4MHZ 5
+#define CLK_FREQ_52MHZ 6
+
+NXP_SYS_CLK_FREQ_SEL=0x02
+
+###############################################################################
+# The timeout value to be used for clock request acknowledgment
+# min value = 0x01 to max = 0x1A
+
+NXP_SYS_CLOCK_TO_CFG=0x1A
+
+###############################################################################
+# NXP proprietary settings
+NXP_ACT_PROP_EXTN={2F, 02, 00}
+
+###############################################################################
+# NFC forum profile settings
+NXP_NFC_PROFILE_EXTN={20, 02, 05, 01, A0, 44, 01, 00}
+
+###############################################################################
+# NFCC Configuration Control
+# Allow NFCC to manage RF Config 0x01
+# Don't allow NFCC to manage RF Config 0x00
+NXP_NFC_MERGE_RF_PARAMS={20, 02, 04, 01, 85, 01, 01}
+
+###############################################################################
+# Standby enable settings
+NXP_CORE_STANDBY={2F, 00, 01, 01}
+
+###############################################################################
+# NXP TVDD configurations settings
+# Allow NFCC to configure External TVDD, There are currently three
+#configurations (1, 2 and 3) are supported, out of them only one can be
+#supported.
+
+NXP_EXT_TVDD_CFG=0x01
+
+###############################################################################
+#config1:SLALM, 3.3V for both RM and CM
+NXP_EXT_TVDD_CFG_1={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 02, 09, 00}
+
+###############################################################################
+#config2: use DCDC in CE, use Tx_Pwr_Req, set CFG2 mode, SLALM,
+#monitoring 5V from DCDC, 4.7V for both RM and CM, DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_2={20, 02, 0B, 02, A0, 66, 01, 00, A0, 0E, 03, 56, 64, 0A}
+
+###############################################################################
+#config3: use DCDC in CE, use Tx_Pwr_Req, SLALM, monitoring 5V from DCDC,
+#DCDCWaitTime=4.2ms
+NXP_EXT_TVDD_CFG_3={20, 02, 0B, 02, A0, 66, 01, 01, A0, 0E, 03, 52, 64, 0A}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_1={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_2={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_3={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_4={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_5={
+#}
+
+###############################################################################
+# NXP RF configuration ALM/PLM settings
+# This section needs to be updated with the correct values based on the platform
+#NXP_RF_CONF_BLK_6={
+#}
+
+###############################################################################
+# Core configuration extensions
+# It includes
+# Wired mode settings A0ED, A0EE
+# Tag Detector A040, A041, A043
+# Low Power mode A007
+# Clock settings A002, A003
+# PbF settings A008
+# Clock timeout settings A004
+NXP_CORE_CONF_EXTN={20, 02, 1D, 07,
+ A0, EC, 01, 01,
+ A0, ED, 01, 03,
+ A0, 5E, 01, 01,
+ A0, 12, 01, 02,
+ A0, 40, 01, 01,
+ A0, DD, 01, 2D,
+ A0, F2, 01, 01
+ }
+
+###############################################################################
+# Core configuration rf field filter settings to enable set to 01 to disable set to 00 last bit
+NXP_CORE_RF_FIELD={ 20, 02, 05, 01, A0, 62, 01, 01
+ }
+
+###############################################################################
+# To enable i2c fragmentation set i2c fragmentation enable 0x01 to disable set to 0x00
+NXP_I2C_FRAGMENTATION_ENABLED=0x00
+
+###############################################################################
+# Core configuration settings
+NXP_CORE_CONF={ 20, 02, 2B, 0D,
+ 28, 01, 00,
+ 21, 01, 00,
+ 30, 01, 08,
+ 31, 01, 03,
+ 33, 04, 01, 02, 03, 04,
+ 54, 01, 06,
+ 50, 01, 02,
+ 5B, 01, 00,
+ 60, 01, 0E,
+ 80, 01, 01,
+ 81, 01, 01,
+ 82, 01, 0E,
+ 18, 01, 01
+ }
+
+###############################################################################
+# Mifare Classic Key settings
+#NXP_CORE_MFCKEY_SETTING={20, 02, 25,04, A0, 51, 06, A0, A1, A2, A3, A4, A5,
+# A0, 52, 06, D3, F7, D3, F7, D3, F7,
+# A0, 53, 06, FF, FF, FF, FF, FF, FF,
+# A0, 54, 06, 00, 00, 00, 00, 00, 00}
+
+###############################################################################
+# Default SE Options
+# No secure element 0x00
+# eSE 0x01
+# UICC 0x02
+
+NXP_DEFAULT_SE=0x03
+
+###############################################################################
+#Enable SWP full power mode when phone is power off
+NXP_SWP_FULL_PWR_ON=0x00
+
+###############################################################################
+#### Select the CHIP ####
+#PN547C2 0x01
+#PN65T 0x02
+#PN548AD 0x03
+#PN66T 0x04
+
+NXP_NFC_CHIP=0x04
+
+###############################################################################
+# CE when Screen state is locked
+# Disable 0x00
+# Enable 0x01
+NXP_CE_ROUTE_STRICT_DISABLE=0x01
+
+###############################################################################
+#Timeout in secs to get NFCEE Discover notification
+NXP_DEFAULT_NFCEE_DISC_TIMEOUT=20
+
+NXP_DEFAULT_NFCEE_TIMEOUT=0x06
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_START_TIMEOUT=0x0A
+
+###############################################################################
+#Timeout in secs
+NXP_SWP_RD_TAG_OP_TIMEOUT=0x01
+
+###############################################################################
+#Set the default AID route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_AID_ROUTE=0x00
+
+###############################################################################
+#Set the Mifare Desfire route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_DESFIRE_ROUTE=0x02
+
+###############################################################################
+#Set the Mifare CLT route Location :
+#This settings will be used when application does not set this parameter
+# host 0x00
+# eSE 0x01
+# UICC 0x02
+DEFAULT_MIFARE_CLT_ROUTE=0x02
+
+###############################################################################
+# AID Matching platform options
+# AID_MATCHING_L 0x01
+# AID_MATCHING_K 0x02
+AID_MATCHING_PLATFORM=0x01
+
+###############################################################################
+# P61 interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LS_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 LTSM interface options
+# NFC 0x01
+# SPI 0x02
+NXP_P61_LTSM_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+#CHINA_TIANJIN_RF_SETTING
+#Enable 0x01
+#Disable 0x00
+NXP_CHINA_TIANJIN_RF_ENABLED=0x01
+
+###############################################################################
+#SWP_SWITCH_TIMEOUT_SETTING
+# Allowed range of swp timeout setting is 0x00 to 0x3C [0 - 60].
+# Timeout in milliseconds, for example
+# No Timeout 0x00
+# 10 millisecond timeout 0x0A
+NXP_SWP_SWITCH_TIMEOUT=0x0A
+
+###############################################################################
+# P61 interface options for JCOP Download
+# NFC 0x01
+# SPI 0x02
+NXP_P61_JCOP_DEFAULT_INTERFACE=0x01
+
+###############################################################################
+# P61 JCOP OS download options
+# FRAMEWORK API BY APPLICATION 0x00
+# AT BOOT_TIME 0x01
+NXP_JCOPDL_AT_BOOT_ENABLE=0x00
+
+###############################################################################
+# Loader service version
+# NFC service checks for LS version 2.0 or 2.1
+# LS2.0 0x20
+# LS2.1 0x21
+# LS2.2 0x22
+# AT NFC service intialization
+NXP_LOADER_SERVICE_VERSION=0x21
diff --git a/src/adaptation/CrcChecksum.cpp b/src/adaptation/CrcChecksum.cpp
old mode 100755
new mode 100644
diff --git a/src/gki/ulinux/gki_ulinux.c b/src/gki/ulinux/gki_ulinux.c
old mode 100755
new mode 100644
diff --git a/src/hal/include/gki_hal_target.h b/src/hal/include/gki_hal_target.h
old mode 100755
new mode 100644
diff --git a/src/hal/include/nci_defs.h b/src/hal/include/nci_defs.h
old mode 100755
new mode 100644
diff --git a/src/hal/include/nfc_hal_api.h b/src/hal/include/nfc_hal_api.h
old mode 100755
new mode 100644
diff --git a/src/hal/include/nfc_hal_target.h b/src/hal/include/nfc_hal_target.h
old mode 100755
new mode 100644
diff --git a/src/hal/include/nfc_types.h b/src/hal/include/nfc_types.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_brcm_defs.h b/src/hal/int/nfc_brcm_defs.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_int.h b/src/hal/int/nfc_hal_int.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_int_api.h b/src/hal/int/nfc_hal_int_api.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_nv_ci.h b/src/hal/int/nfc_hal_nv_ci.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_nv_co.h b/src/hal/int/nfc_hal_nv_co.h
old mode 100755
new mode 100644
diff --git a/src/hal/int/nfc_hal_post_reset.h b/src/hal/int/nfc_hal_post_reset.h
old mode 100755
new mode 100644
diff --git a/src/include/CrcChecksum.h b/src/include/CrcChecksum.h
old mode 100755
new mode 100644
diff --git a/src/nfa/ce/nfa_ce_act.c b/src/nfa/ce/nfa_ce_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/ce/nfa_ce_api.c b/src/nfa/ce/nfa_ce_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/ce/nfa_ce_main.c b/src/nfa/ce/nfa_ce_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_act.c b/src/nfa/dm/nfa_dm_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_api.c b/src/nfa/dm/nfa_dm_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_cfg.c b/src/nfa/dm/nfa_dm_cfg.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_discover.c b/src/nfa/dm/nfa_dm_discover.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_main.c b/src/nfa/dm/nfa_dm_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/dm/nfa_dm_ndef.c b/src/nfa/dm/nfa_dm_ndef.c
old mode 100755
new mode 100644
diff --git a/src/nfa/ee/nfa_ee_act.c b/src/nfa/ee/nfa_ee_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/ee/nfa_ee_api.c b/src/nfa/ee/nfa_ee_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/ee/nfa_ee_main.c b/src/nfa/ee/nfa_ee_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_act.c b/src/nfa/hci/nfa_hci_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_api.c b/src/nfa/hci/nfa_hci_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_ci.c b/src/nfa/hci/nfa_hci_ci.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_main.c b/src/nfa/hci/nfa_hci_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/hci/nfa_hci_utils.c b/src/nfa/hci/nfa_hci_utils.c
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_ce_api.h b/src/nfa/include/nfa_ce_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_cho_api.h b/src/nfa/include/nfa_cho_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_ee_api.h b/src/nfa/include/nfa_ee_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_hci_api.h b/src/nfa/include/nfa_hci_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_hci_defs.h b/src/nfa/include/nfa_hci_defs.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_mem_co.h b/src/nfa/include/nfa_mem_co.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_nv_ci.h b/src/nfa/include/nfa_nv_ci.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_nv_co.h b/src/nfa/include/nfa_nv_co.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_p2p_api.h b/src/nfa/include/nfa_p2p_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_rw_api.h b/src/nfa/include/nfa_rw_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/include/nfa_snep_api.h b/src/nfa/include/nfa_snep_api.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_ce_int.h b/src/nfa/int/nfa_ce_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_cho_int.h b/src/nfa/int/nfa_cho_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_dm_int.h b/src/nfa/int/nfa_dm_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_dta_int.h b/src/nfa/int/nfa_dta_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_ee_int.h b/src/nfa/int/nfa_ee_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_hci_int.h b/src/nfa/int/nfa_hci_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_p2p_int.h b/src/nfa/int/nfa_p2p_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_rw_int.h b/src/nfa/int/nfa_rw_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_snep_int.h b/src/nfa/int/nfa_snep_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys.h b/src/nfa/int/nfa_sys.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys_int.h b/src/nfa/int/nfa_sys_int.h
old mode 100755
new mode 100644
diff --git a/src/nfa/int/nfa_sys_ptim.h b/src/nfa/int/nfa_sys_ptim.h
old mode 100755
new mode 100644
diff --git a/src/nfa/p2p/nfa_p2p_act.c b/src/nfa/p2p/nfa_p2p_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/p2p/nfa_p2p_api.c b/src/nfa/p2p/nfa_p2p_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/rw/nfa_rw_act.c b/src/nfa/rw/nfa_rw_act.c
old mode 100755
new mode 100644
diff --git a/src/nfa/rw/nfa_rw_api.c b/src/nfa/rw/nfa_rw_api.c
old mode 100755
new mode 100644
diff --git a/src/nfa/rw/nfa_rw_main.c b/src/nfa/rw/nfa_rw_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_cback.c b/src/nfa/sys/nfa_sys_cback.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_cfg.c b/src/nfa/sys/nfa_sys_cfg.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_main.c b/src/nfa/sys/nfa_sys_main.c
old mode 100755
new mode 100644
diff --git a/src/nfa/sys/nfa_sys_ptim.c b/src/nfa/sys/nfa_sys_ptim.c
old mode 100755
new mode 100644
diff --git a/src/nfc/include/ce_api.h b/src/nfc/include/ce_api.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/nci_hmsgs.h b/src/nfc/include/nci_hmsgs.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/ndef_utils.h b/src/nfc/include/ndef_utils.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/nfc_api.h b/src/nfc/include/nfc_api.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/rw_api.h b/src/nfc/include/rw_api.h
old mode 100755
new mode 100644
diff --git a/src/nfc/include/tags_defs.h b/src/nfc/include/tags_defs.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/ce_int.h b/src/nfc/int/ce_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/llcp_int.h b/src/nfc/int/llcp_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/nfc_int.h b/src/nfc/int/nfc_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/rw_int.h b/src/nfc/int/rw_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/int/tags_int.h b/src/nfc/int/tags_int.h
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_dlc.c b/src/nfc/llcp/llcp_dlc.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_link.c b/src/nfc/llcp/llcp_link.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_main.c b/src/nfc/llcp/llcp_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_sdp.c b/src/nfc/llcp/llcp_sdp.c
old mode 100755
new mode 100644
diff --git a/src/nfc/llcp/llcp_util.c b/src/nfc/llcp/llcp_util.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nci/nci_hmsgs.c b/src/nfc/nci/nci_hmsgs.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nci/nci_hrcv.c b/src/nfc/nci/nci_hrcv.c
old mode 100755
new mode 100644
diff --git a/src/nfc/ndef/ndef_cho_utils.c b/src/nfc/ndef/ndef_cho_utils.c
old mode 100755
new mode 100644
diff --git a/src/nfc/ndef/ndef_utils.c b/src/nfc/ndef/ndef_utils.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_ee.c b/src/nfc/nfc/nfc_ee.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_ncif.c b/src/nfc/nfc/nfc_ncif.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_task.c b/src/nfc/nfc/nfc_task.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_test.c b/src/nfc/nfc/nfc_test.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_utils.c b/src/nfc/nfc/nfc_utils.c
old mode 100755
new mode 100644
diff --git a/src/nfc/nfc/nfc_vs.c b/src/nfc/nfc/nfc_vs.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/ce_main.c b/src/nfc/tags/ce_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/ce_t3t.c b/src/nfc/tags/ce_t3t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/ce_t4t.c b/src/nfc/tags/ce_t4t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_i93.c b/src/nfc/tags/rw_i93.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_main.c b/src/nfc/tags/rw_main.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t1t.c b/src/nfc/tags/rw_t1t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t1t_ndef.c b/src/nfc/tags/rw_t1t_ndef.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t2t.c b/src/nfc/tags/rw_t2t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t2t_ndef.c b/src/nfc/tags/rw_t2t_ndef.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t3t.c b/src/nfc/tags/rw_t3t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/rw_t4t.c b/src/nfc/tags/rw_t4t.c
old mode 100755
new mode 100644
diff --git a/src/nfc/tags/tags_int.c b/src/nfc/tags/tags_int.c
old mode 100755
new mode 100644