upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
42
android/hardware/realtek/bluetooth/libbt-vendor/Android.mk
Normal file
42
android/hardware/realtek/bluetooth/libbt-vendor/Android.mk
Normal file
|
@ -0,0 +1,42 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
BDROID_DIR := $(TOP_DIR)system/bt
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
codec/msbc/sbc.c \
|
||||
src/rtk_socket.c \
|
||||
src/bt_vendor_rtk.c \
|
||||
src/hardware.c \
|
||||
src/userial_vendor.c \
|
||||
src/upio.c \
|
||||
src/bt_list.c \
|
||||
src/bt_skbuff.c \
|
||||
src/hci_h5.c \
|
||||
src/rtk_parse.c \
|
||||
src/rtk_btsnoop_net.c
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/codec/msbc \
|
||||
$(BDROID_DIR)/hci/include
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
liblog
|
||||
|
||||
ifeq ($(BOARD_HAVE_BLUETOOTH_NAME), rtl8723bs)
|
||||
LOCAL_CFLAGS += -DRTL_8723BS_BT_USED
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD_HAVE_BLUETOOTH_NAME), rtl8723bs_vq0)
|
||||
LOCAL_CFLAGS += -DRTL_8723BS_VQ0_BT_USED
|
||||
endif
|
||||
|
||||
LOCAL_MODULE := libbt-vendor
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
1762
android/hardware/realtek/bluetooth/libbt-vendor/codec/msbc/sbc.c
Normal file
1762
android/hardware/realtek/bluetooth/libbt-vendor/codec/msbc/sbc.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
*
|
||||
* Bluetooth low-complexity, subband codec (SBC) library
|
||||
*
|
||||
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
|
||||
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SBC_H
|
||||
#define __SBC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct sbc_struct {
|
||||
unsigned long flags;
|
||||
unsigned short rate;
|
||||
unsigned char channels;
|
||||
unsigned char joint;
|
||||
unsigned char blocks;
|
||||
unsigned char subbands;
|
||||
unsigned char bitpool;
|
||||
|
||||
void *data;
|
||||
int size;
|
||||
int len;
|
||||
|
||||
unsigned long duration;
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
typedef struct sbc_struct sbc_t;
|
||||
|
||||
int sbc_init(sbc_t *sbc, unsigned long flags);
|
||||
|
||||
int sbc_reinit(sbc_t *sbc, unsigned long flags);
|
||||
|
||||
|
||||
int sbc_encode(sbc_t *sbc,
|
||||
void *input,
|
||||
int input_len,
|
||||
void *output,
|
||||
int output_len,
|
||||
int *written);
|
||||
|
||||
int sbc_decode(sbc_t *sbc,
|
||||
void *input,
|
||||
int input_len,
|
||||
void *output,
|
||||
int output_len,
|
||||
int *written);
|
||||
|
||||
void sbc_finish(sbc_t *sbc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SBC_H */
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
*
|
||||
* Bluetooth low-complexity, subband codec (SBC) library
|
||||
*
|
||||
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
|
||||
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#define fabs(x) ((x) < 0 ? -(x) : (x))
|
||||
/* C does not provide an explicit arithmetic shift right but this will
|
||||
always be correct and every compiler *should* generate optimal code */
|
||||
#define ASR(val, bits) ((-2 >> 1 == -1) ? \
|
||||
((int32_t)(val)) >> (bits) : ((int32_t) (val)) / (1 << (bits)))
|
||||
#define ASR_64(val, bits) ((-2 >> 1 == -1) ? \
|
||||
((long long)(val)) >> (bits) : ((long long) (val)) / (1 << (bits)))
|
||||
|
||||
#define SCALE_PROTO4_TBL 15
|
||||
#define SCALE_ANA4_TBL 16
|
||||
#define SCALE_PROTO8_TBL 15
|
||||
#define SCALE_ANA8_TBL 16
|
||||
#define SCALE_SPROTO4_TBL 16
|
||||
#define SCALE_SPROTO8_TBL 16
|
||||
#define SCALE_NPROTO4_TBL 10
|
||||
#define SCALE_NPROTO8_TBL 12
|
||||
#define SCALE_SAMPLES 14
|
||||
#define SCALE4_STAGE1_BITS 10
|
||||
#define SCALE4_STAGE2_BITS 21
|
||||
#define SCALE4_STAGED1_BITS 18
|
||||
#define SCALE4_STAGED2_BITS 23
|
||||
#define SCALE8_STAGE1_BITS 8
|
||||
#define SCALE8_STAGE2_BITS 24
|
||||
#define SCALE8_STAGED1_BITS 18
|
||||
#define SCALE8_STAGED2_BITS 23
|
||||
|
||||
typedef int int32_t;
|
||||
typedef int32_t sbc_fixed_t;
|
||||
typedef long long sbc_extended_t;
|
||||
|
||||
#define SCALE4_STAGE1(src) ASR_64(src, SCALE4_STAGE1_BITS)
|
||||
#define SCALE4_STAGE2(src) ASR_64(src, SCALE4_STAGE2_BITS)
|
||||
#define SCALE4_STAGED1(src) ASR_64(src, SCALE4_STAGED1_BITS)
|
||||
#define SCALE4_STAGED2(src) ASR_64(src, SCALE4_STAGED2_BITS)
|
||||
#define SCALE8_STAGE1(src) ASR_64(src, SCALE8_STAGE1_BITS)
|
||||
#define SCALE8_STAGE2(src) ASR_64(src, SCALE8_STAGE2_BITS)
|
||||
#define SCALE8_STAGED1(src) ASR_64(src, SCALE8_STAGED1_BITS)
|
||||
#define SCALE8_STAGED2(src) ASR_64(src, SCALE8_STAGED2_BITS)
|
||||
|
||||
#define SBC_FIXED_0(val) { val = 0; }
|
||||
#define ADD(dst, src) { dst += src; }
|
||||
#define SUB(dst, src) { dst -= src; }
|
||||
#define MUL(dst, a, b) { dst = (sbc_extended_t) (a) * (b); }
|
||||
#define MULA(dst, a, b) { dst += (sbc_extended_t) (a) * (b); }
|
||||
#define DIV2(dst, src) { dst = ASR(src, 1); }
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
*
|
||||
* Bluetooth low-complexity, subband codec (SBC) library
|
||||
*
|
||||
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
|
||||
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
|
||||
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sbc_math.h"
|
||||
|
||||
/* A2DP specification: Appendix B, page 69 */
|
||||
static const int sbc_offset4[4][4] = {
|
||||
{ -1, 0, 0, 0 },
|
||||
{ -2, 0, 0, 1 },
|
||||
{ -2, 0, 0, 1 },
|
||||
{ -2, 0, 0, 1 }
|
||||
};
|
||||
|
||||
/* A2DP specification: Appendix B, page 69 */
|
||||
static const int sbc_offset8[4][8] = {
|
||||
{ -2, 0, 0, 0, 0, 0, 0, 1 },
|
||||
{ -3, 0, 0, 0, 0, 0, 1, 2 },
|
||||
{ -4, 0, 0, 0, 0, 0, 1, 2 },
|
||||
{ -4, 0, 0, 0, 0, 0, 1, 2 }
|
||||
};
|
||||
|
||||
#define SP4(val) ASR(val, SCALE_PROTO4_TBL)
|
||||
#define SA4(val) ASR(val, SCALE_ANA4_TBL)
|
||||
#define SP8(val) ASR(val, SCALE_PROTO8_TBL)
|
||||
#define SA8(val) ASR(val, SCALE_ANA8_TBL)
|
||||
#define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
|
||||
#define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
|
||||
#define SN4(val) ASR(val, SCALE_NPROTO4_TBL)
|
||||
#define SN8(val) ASR(val, SCALE_NPROTO8_TBL)
|
||||
|
||||
static const int32_t _sbc_proto_4[20] = {
|
||||
SP4(0x02cb3e8c), SP4(0x22b63dc0), SP4(0x002329cc), SP4(0x053b7548),
|
||||
SP4(0x31eab940), SP4(0xec1f5e60), SP4(0xff3773a8), SP4(0x0061c5a7),
|
||||
SP4(0x07646680), SP4(0x3f239480), SP4(0xf89f23a8), SP4(0x007a4737),
|
||||
SP4(0x00b32807), SP4(0x083ddc80), SP4(0x4825e480), SP4(0x0191e578),
|
||||
SP4(0x00ff11ca), SP4(0x00fb7991), SP4(0x069fdc58), SP4(0x4b584000)
|
||||
};
|
||||
|
||||
static const int32_t _anamatrix4[4] = {
|
||||
SA4(0x2d413cc0), SA4(0x3b20d780), SA4(0x40000000), SA4(0x187de2a0)
|
||||
};
|
||||
|
||||
static const int32_t _sbc_proto_8[40] = {
|
||||
SP8(0x02e5cd20), SP8(0x22d0c200), SP8(0x006bfe27), SP8(0x07808930),
|
||||
SP8(0x3f1c8800), SP8(0xf8810d70), SP8(0x002cfdc6), SP8(0x055acf28),
|
||||
SP8(0x31f566c0), SP8(0xebfe57e0), SP8(0xff27c437), SP8(0x001485cc),
|
||||
SP8(0x041c6e58), SP8(0x2a7cfa80), SP8(0xe4c4a240), SP8(0xfe359e4c),
|
||||
SP8(0x0048b1f8), SP8(0x0686ce30), SP8(0x38eec5c0), SP8(0xf2a1b9f0),
|
||||
SP8(0xffe8904a), SP8(0x0095698a), SP8(0x0824a480), SP8(0x443b3c00),
|
||||
SP8(0xfd7badc8), SP8(0x00d3e2d9), SP8(0x00c183d2), SP8(0x084e1950),
|
||||
SP8(0x4810d800), SP8(0x017f43fe), SP8(0x01056dd8), SP8(0x00e9cb9f),
|
||||
SP8(0x07d7d090), SP8(0x4a708980), SP8(0x0488fae8), SP8(0x0113bd20),
|
||||
SP8(0x0107b1a8), SP8(0x069fb3c0), SP8(0x4b3db200), SP8(0x00763f48)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_4_40m0[] = {
|
||||
SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
|
||||
SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
|
||||
SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
|
||||
SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
|
||||
SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_4_40m1[] = {
|
||||
SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
|
||||
SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
|
||||
SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
|
||||
SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
|
||||
SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_8_80m0[] = {
|
||||
SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
|
||||
SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
|
||||
SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
|
||||
SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
|
||||
SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
|
||||
SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
|
||||
SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
|
||||
SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
|
||||
SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
|
||||
SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
|
||||
};
|
||||
|
||||
static const int32_t sbc_proto_8_80m1[] = {
|
||||
SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
|
||||
SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
|
||||
SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
|
||||
SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
|
||||
SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
|
||||
SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
|
||||
SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
|
||||
SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
|
||||
SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
|
||||
SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
|
||||
};
|
||||
|
||||
static const int32_t _anamatrix8[8] = {
|
||||
SA8(0x3b20d780), SA8(0x187de2a0), SA8(0x3ec52f80), SA8(0x3536cc40),
|
||||
SA8(0x238e7680), SA8(0x0c7c5c20), SA8(0x2d413cc0), SA8(0x40000000)
|
||||
};
|
||||
|
||||
static const int32_t synmatrix4[8][4] = {
|
||||
{ SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
|
||||
{ SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
|
||||
{ SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
|
||||
{ SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
|
||||
{ SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
|
||||
{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
|
||||
{ SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
|
||||
{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
|
||||
};
|
||||
|
||||
static const int32_t synmatrix8[16][8] = {
|
||||
{ SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
|
||||
SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
|
||||
{ SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
|
||||
SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
|
||||
{ SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
|
||||
SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
|
||||
{ SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
|
||||
SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
|
||||
{ SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
|
||||
SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
|
||||
{ SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
|
||||
SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
|
||||
{ SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
|
||||
SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
|
||||
{ SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
|
||||
SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
|
||||
{ SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
|
||||
SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
|
||||
{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
|
||||
SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
|
||||
{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
|
||||
SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
|
||||
{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
|
||||
SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
|
||||
{ SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
|
||||
SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
|
||||
{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
|
||||
SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
|
||||
{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
|
||||
SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
|
||||
{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
|
||||
SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
|
||||
};
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name:
|
||||
* bt_list.h
|
||||
*
|
||||
* Abstract:
|
||||
* To implement list data structure
|
||||
*
|
||||
* Major Change History:
|
||||
* When Who What
|
||||
* --------------------------------------------------------------
|
||||
* 2010-06-04 W.Bi Created
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BT_LIST_H
|
||||
#define BT_LIST_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\file bt_list.h
|
||||
\brief Implement bluetooth list data structure. Has referred to Linux list implementation
|
||||
You could add your new list manipulation here.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
List entry structure, could be header or node.
|
||||
|
||||
Prev<-----Header---->Next
|
||||
|
||||
Every List has an additional header, and list tail will be list header's previous node.
|
||||
You can use list to form a queue or a stack data structure
|
||||
queue:
|
||||
ListAddToTail----->LIST_FOR_EACH iterate--->manipulate on the list entry
|
||||
Stack:
|
||||
ListAddToHead--- >LIST_FOR_EACH iterate--->manipulate on the list entry
|
||||
*/
|
||||
|
||||
///RT list structure definition
|
||||
typedef struct _RT_LIST_ENTRY {
|
||||
struct _RT_LIST_ENTRY *Next; ///< Entry's next element
|
||||
struct _RT_LIST_ENTRY *Prev; ///< Entry's previous element
|
||||
} RT_LIST_ENTRY, *PRT_LIST_ENTRY;
|
||||
|
||||
///List head would be another name of list entry, and it points to the list header
|
||||
typedef RT_LIST_ENTRY RT_LIST_HEAD, *PRT_LIST_HEAD;
|
||||
|
||||
/*----------------------------------------------------------------------------------
|
||||
EXTERNAL FUNCTION
|
||||
----------------------------------------------------------------------------------*/
|
||||
|
||||
///Initialize a list with its header
|
||||
void ListInitializeHeader(PRT_LIST_HEAD ListHead);
|
||||
|
||||
/**
|
||||
Add a new entry to the list.
|
||||
Insert a new entry after the specified head. This is good for implementing stacks.
|
||||
\param [IN] ListNew <RT_LIST_ENTRY> : new entry to be added
|
||||
\param [IN OUT] ListHead <RT_LIST_ENTRY> : List header after which to add new entry
|
||||
*/
|
||||
void ListAddToHead(PRT_LIST_ENTRY ListNew, PRT_LIST_HEAD ListHead);
|
||||
|
||||
/**
|
||||
Add a new entry to the list.
|
||||
Insert a new entry before the specified head. This is good for implementing queues.
|
||||
\param [IN] ListNew <RT_LIST_ENTRY> : new entry to be added
|
||||
\param [IN OUT] ListHead <RT_LIST_ENTRY> : List header before which to add new entry
|
||||
*/
|
||||
void ListAddToTail(PRT_LIST_ENTRY ListNew, PRT_LIST_HEAD ListHead);
|
||||
|
||||
/**
|
||||
Get entry in the head of the list
|
||||
\param [IN ] ListHead <RT_LIST_ENTRY> : List header
|
||||
\return entry in the head , otherwise NULL
|
||||
*/
|
||||
RT_LIST_ENTRY* ListGetTop(PRT_LIST_HEAD ListHead);
|
||||
|
||||
/**
|
||||
Get entry in the tail of the list
|
||||
\param [IN ] ListHead <RT_LIST_ENTRY> : List header
|
||||
\return entry in the tail , otherwise NULL
|
||||
*/
|
||||
RT_LIST_ENTRY*
|
||||
ListGetTail(
|
||||
PRT_LIST_HEAD ListHead
|
||||
);
|
||||
|
||||
/**
|
||||
Delete entry from the list
|
||||
Note: ListIsEmpty() on this list entry would not return true, since its state is undefined
|
||||
\param [IN] ListToDelete <RT_LIST_ENTRY> : list entry to be deleted
|
||||
*/
|
||||
void ListDeleteNode(PRT_LIST_ENTRY ListToDelete);
|
||||
|
||||
/**
|
||||
Tell whether the list is empty
|
||||
\param [IN] ListHead <RT_LIST_ENTRY> : List header of which to be test
|
||||
*/
|
||||
unsigned char ListIsEmpty(PRT_LIST_HEAD ListHead);
|
||||
|
||||
//EXTERN void ListEmpty(PRT_LIST_HEAD ListHead);
|
||||
|
||||
void
|
||||
ListAdd(
|
||||
PRT_LIST_ENTRY New,
|
||||
PRT_LIST_ENTRY Prev,
|
||||
PRT_LIST_ENTRY Next
|
||||
);
|
||||
|
||||
/*----------------------------------------------------------------------------------
|
||||
MACRO
|
||||
----------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
Macros to iterate over the list.
|
||||
\param _Iter : struct PRT_LIST_ENTRY type iterator to use as a loop cursor
|
||||
\param _ListHead : List head of which to be iterated
|
||||
*/
|
||||
#define LIST_FOR_EACH(_Iter, _ListHead) \
|
||||
for ((_Iter) = (_ListHead)->Next; (_Iter) != (_ListHead); (_Iter) = (_Iter)->Next)
|
||||
|
||||
/**
|
||||
Macros to iterate over the list safely against removal of list entry.
|
||||
If you would delete any list entry from the list while iterating the list, should use this macro
|
||||
\param _Iter : Struct PRT_LIST_ENTRY type iterator to use as a loop cursor
|
||||
\param _Temp : Another Struct PRT_LIST_ENTRY type to use as a temporary storage
|
||||
\param _ListHead : List head of which to be iterated
|
||||
*/
|
||||
#define LIST_FOR_EACH_SAFELY(_Iter, _Temp, _ListHead) \
|
||||
for ((_Iter) = (_ListHead)->Next, (_Temp) = (_Iter)->Next; (_Iter) != (_ListHead); \
|
||||
(_Iter) = (_Temp), (_Temp) = (_Iter)->Next)
|
||||
|
||||
/**
|
||||
Macros to get the struct pointer of this list entry
|
||||
You could make every RT_LIST_ENTRY at the first place of your structure to avoid the macro, which will be dangerouse.
|
||||
Copy from winnt.h.
|
||||
BUG:if offset of field in type larger than 32 bit interger, which is not likely to happen, it will error
|
||||
\param _Ptr : Struct RT_LIST_ENTRY type pointer
|
||||
\param _Type : The type of structure in which the RT_LIST_ENTRY embedded in
|
||||
\param _Field : the name of the RT_LIST_ENTRY within the struct
|
||||
*/
|
||||
#define LIST_ENTRY(_Ptr, _Type, _Field) ((_Type *)((char *)(_Ptr)-(unsigned long)(&((_Type *)0)->_Field)))
|
||||
|
||||
|
||||
#endif /*BT_LIST_H*/
|
|
@ -0,0 +1,362 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name:
|
||||
* bt_skbuff.h
|
||||
*
|
||||
* Abstract:
|
||||
* Data buffer managerment through whole bluetooth stack.
|
||||
*
|
||||
* Major Change History:
|
||||
* When Who What
|
||||
* --------------------------------------------------------------
|
||||
* 2010-06-11 W.Bi Created.
|
||||
*
|
||||
* Notes:
|
||||
* To reduce memory copy when pass data buffer to other layers,
|
||||
* RTK_BUFFER is designed referring to linux socket buffer.
|
||||
* But I still wonder its effect, since RTK_BUFFER is much bigger
|
||||
* than original data buffer.RTK_BUFFER will reduce its member if
|
||||
* it would not reach what i had expected.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef BT_SKBUFF_H
|
||||
#define BT_SKBUFF_H
|
||||
#include "bt_list.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN
|
||||
#endif
|
||||
|
||||
#ifndef IN
|
||||
#define IN
|
||||
#endif
|
||||
|
||||
#ifndef OUT
|
||||
#define OUT
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------------
|
||||
CONSTANT DEFINITION
|
||||
----------------------------------------------------------------------------------*/
|
||||
#define RTK_CONTEXT_SIZE 12
|
||||
|
||||
#define RTB_QUEUE_ID_LENGTH 64
|
||||
|
||||
/*----------------------------------------------------------------------------------
|
||||
STRUCTURE DEFINITION
|
||||
----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
Rtk buffer definition
|
||||
Head -->|<---Data--->|<-----Length------>| <---End
|
||||
_________________________________
|
||||
|_____________|___________________|
|
||||
|<-headroom->|<--RealDataBuffer-->|
|
||||
|
||||
Compared to socket buffer, there exists no tail and end pointer and tailroom as tail is rarely used in bluetooth stack
|
||||
\param List : List structure used to list same type rtk buffer and manipulate rtk buffer like list.
|
||||
\param Head : Pointer to truely allocated data buffer. It point to the headroom
|
||||
\param Data : Pointer to real data buffer.
|
||||
\param Length : currently data length
|
||||
\param HeadRoom : Record initialize headroom size.
|
||||
\param RefCount : Reference count. zero means able to be freed, otherwise somebody is handling it.
|
||||
\param Priv : Reserved for multi-device support. Record Hci pointer which will handles this packet
|
||||
\param Contest : Control buffer, put private variables here.
|
||||
*/
|
||||
typedef struct _RTK_BUFFER
|
||||
{
|
||||
RT_LIST_ENTRY List;
|
||||
uint8_t *Head;
|
||||
uint8_t *Data;
|
||||
uint8_t *Tail;
|
||||
uint8_t *End;
|
||||
uint32_t Length;
|
||||
uint32_t HeadRoom;
|
||||
// RT_U16 TailRoom;
|
||||
signed char RefCount;
|
||||
|
||||
void* Priv;
|
||||
uint8_t Context[RTK_CONTEXT_SIZE];
|
||||
}RTK_BUFFER, *PRTK_BUFFER;
|
||||
|
||||
/**
|
||||
RTK_BUFFER Control Buffer Context
|
||||
\param PacketType : HCI data types, Command/Acl/...
|
||||
\param LastFrag : Is Current Acl buffer the last fragment.(0 for no, 1 for yes)
|
||||
\param TxSeq : Current packet tx sequence
|
||||
\param Retries : Current packet retransmission times
|
||||
\param Sar : L2cap control field segmentation and reassembly bits
|
||||
*/
|
||||
struct BT_RTB_CONTEXT{
|
||||
uint8_t PacketType;
|
||||
uint16_t Handle;
|
||||
};
|
||||
|
||||
///definition to get rtk_buffer's control buffer context pointer
|
||||
#define BT_CONTEXT(_Rtb) ((struct BT_RTB_CONTEXT *)((_Rtb)->Context))
|
||||
|
||||
/**
|
||||
Since RTBs are always used into/from list, so abstract this struct and provide APIs to easy process on RTBs
|
||||
*/
|
||||
typedef struct _RTB_QUEUE_HEAD RTB_QUEUE_HEAD;
|
||||
/*----------------------------------------------------------------------------------
|
||||
EXTERNAL FUNCTION
|
||||
----------------------------------------------------------------------------------*/
|
||||
/**
|
||||
Allocate a RTK_BUFFER with specified data length and reserved headroom.
|
||||
If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value.
|
||||
\param [IN] Length <uint32_t> : current data buffer length to allcated
|
||||
\param [IN] HeadRoom <uint32_t> : if caller knows reserved head space, set it; otherwise set 0 to use default value
|
||||
\return pointer to RTK_BUFFER if succeed, null otherwise
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbAllocate(
|
||||
IN uint32_t Length,
|
||||
IN uint32_t HeadRoom
|
||||
);
|
||||
|
||||
/**
|
||||
Free specified Rtk_buffer
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : buffer to free
|
||||
*/
|
||||
void
|
||||
RtbFree(
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
increament reference count
|
||||
*/
|
||||
void
|
||||
RtbIncreaseRefCount(
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Recycle a rtk_buffer after its usage if specified rtb could
|
||||
if rtb total length is not smaller than specified rtbsize to be recycled for, it will succeeded recycling
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : buffer to recycle
|
||||
\param [IN] RtbSize <uint32_t> : size of buffer to be recycled for
|
||||
*/
|
||||
/*
|
||||
BOOLEAN
|
||||
RtbCheckRecycle(
|
||||
IN OUT RTK_BUFFER* RtkBuffer,
|
||||
IN uint32_t RtbSize
|
||||
);
|
||||
*/
|
||||
/**
|
||||
Add a specified length protocal header to the start of data buffer hold by specified rtk_buffer.
|
||||
This function extends used data area of the buffer at the buffer start.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the first byte of the extra data is returned
|
||||
*/
|
||||
uint8_t*
|
||||
RtbAddHead(
|
||||
IN OUT RTK_BUFFER* RtkBuffer,
|
||||
IN uint32_t Length
|
||||
);
|
||||
|
||||
/**
|
||||
Remove a specified length data from the start of data buffer hold by specified rtk_buffer.
|
||||
This function returns the memory to the headroom.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to remove
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the next data in the buffer is returned, usually useless
|
||||
*/
|
||||
unsigned char
|
||||
RtbRemoveHead(
|
||||
IN OUT RTK_BUFFER* RtkBuffer,
|
||||
IN uint32_t Length
|
||||
);
|
||||
|
||||
/**
|
||||
Add a specified length protocal header to the end of data buffer hold by specified rtk_buffer.
|
||||
This function extends used data area of the buffer at the buffer end.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the first byte of the extra data is returned
|
||||
*/
|
||||
EXTERN uint8_t*
|
||||
RtbAddTail(
|
||||
IN OUT RTK_BUFFER* RtkBuffer,
|
||||
IN uint32_t Length
|
||||
);
|
||||
|
||||
/**
|
||||
Remove a specified length data from the end of data buffer hold by specified rtk_buffer.
|
||||
*/
|
||||
EXTERN unsigned char
|
||||
RtbRemoveTail(
|
||||
IN OUT RTK_BUFFER * RtkBuffer,
|
||||
IN uint32_t Length
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize a rtb queue.
|
||||
\return Initilized rtb queue if succeed, otherwise NULL
|
||||
*/
|
||||
EXTERN RTB_QUEUE_HEAD*
|
||||
RtbQueueInit(
|
||||
);
|
||||
|
||||
/**
|
||||
Free a rtb queue.
|
||||
\param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
*/
|
||||
EXTERN void
|
||||
RtbQueueFree(
|
||||
RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
/**
|
||||
Queue specified RtkBuffer into a RtkQueue at list tail.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
EXTERN void
|
||||
RtbQueueTail(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Queue specified RtkBuffer into a RtkQueue at list Head.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
EXTERN void
|
||||
RtbQueueHead(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
Remove a RtkBuffer from specified rtkqueue at list tail.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return removed rtkbuffer if succeed, otherwise NULL
|
||||
*/
|
||||
EXTERN RTK_BUFFER*
|
||||
RtbDequeueTail(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
/**
|
||||
Remove a RtkBuffer from specified rtkqueue at list head.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return removed rtkbuffer if succeed, otherwise NULL
|
||||
*/
|
||||
EXTERN RTK_BUFFER*
|
||||
RtbDequeueHead(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
/**
|
||||
Get current rtb queue's length.
|
||||
\param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return current queue's length
|
||||
*/
|
||||
EXTERN signed long
|
||||
RtbGetQueueLen(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
/**
|
||||
Empty the rtkqueue.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
*/
|
||||
EXTERN void
|
||||
RtbEmptyQueue(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
/**
|
||||
Get the RtkBuffer which is the head of a RtkQueue
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return head of the RtkQueue , otherwise NULL
|
||||
*/
|
||||
EXTERN RTK_BUFFER*
|
||||
RtbTopQueue(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
/**
|
||||
Insert new Rtkbuffer in the old buffer
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] OldRtkBuffer <RTK_BUFFER*> : old rtk buffer
|
||||
\param [IN] NewRtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
EXTERN void
|
||||
RtbInsertBefore(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pOldRtkBuffer,
|
||||
IN RTK_BUFFER* pNewRtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
check whether the buffer is the last node in the queue
|
||||
*/
|
||||
EXTERN unsigned char
|
||||
RtbNodeIsLast(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pRtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
get the next buffer node after the specified buffer in the queue
|
||||
if the specified buffer is the last node in the queue , return NULL
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer
|
||||
\return node after the specified buffer
|
||||
*/
|
||||
EXTERN RTK_BUFFER*
|
||||
RtbQueueNextNode(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pRtkBuffer
|
||||
);
|
||||
|
||||
/**
|
||||
check whether queue is empty
|
||||
*/
|
||||
EXTERN bool
|
||||
RtbQueueIsEmpty(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
);
|
||||
|
||||
//annie_tmp
|
||||
EXTERN unsigned char
|
||||
RtbCheckQueueLen(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN uint8_t Len
|
||||
);
|
||||
|
||||
EXTERN void
|
||||
RtbRemoveNode(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
);
|
||||
|
||||
EXTERN RTK_BUFFER*
|
||||
RtbCloneBuffer(
|
||||
IN RTK_BUFFER* pDataBuffer
|
||||
);
|
||||
|
||||
#endif /*BT_SKBUFF_H*/
|
|
@ -0,0 +1,245 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: bt_vendor_rtk.h
|
||||
*
|
||||
* Description: A wrapper header file of bt_vendor_lib.h
|
||||
*
|
||||
* Contains definitions specific for interfacing with Realtek
|
||||
* Bluetooth chipsets
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BT_VENDOR_RTK_H
|
||||
#define BT_VENDOR_RTK_H
|
||||
|
||||
#include "bt_vendor_lib.h"
|
||||
#include "vnd_buildcfg.h"
|
||||
#include "rtk_btsnoop_net.h"
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
#define RTKBT_TRANS_H4 0x20
|
||||
#define RTKBT_TRANS_H5 0x10
|
||||
#define RTKBT_TRANS_UART 0x01
|
||||
#define RTKBT_TRANS_USB 0x20
|
||||
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#ifndef BTVND_DBG
|
||||
#define BTVND_DBG TRUE
|
||||
#endif
|
||||
|
||||
#if (BTVND_DBG == TRUE)
|
||||
#define BTVNDDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
|
||||
#else
|
||||
#define BTVNDDBG(param, ...) {}
|
||||
#endif
|
||||
|
||||
#define DOWN_FW_CFG _IOW('H', 201, int)
|
||||
#define SET_ISO_CFG _IOW('H', 202, int)
|
||||
|
||||
|
||||
/* Device port name where Bluetooth controller attached */
|
||||
#ifndef BLUETOOTH_UART_DEVICE_PORT
|
||||
#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyO1" /* maguro */
|
||||
#endif
|
||||
|
||||
/* Location of firmware patch files */
|
||||
#ifndef FW_PATCHFILE_LOCATION
|
||||
#define FW_PATCHFILE_LOCATION "/vendor/firmware/" /* maguro */
|
||||
#endif
|
||||
|
||||
#ifndef UART_TARGET_BAUD_RATE
|
||||
#define UART_TARGET_BAUD_RATE 3000000
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The Bluetooth Device Aaddress source switch:
|
||||
*
|
||||
* -FALSE- (default value)
|
||||
* Get the factory BDADDR from device's file system. Normally the BDADDR is
|
||||
* stored in the location pointed by the PROPERTY_BT_BDADDR_PATH (defined in
|
||||
* btif_common.h file) property.
|
||||
*
|
||||
* -TRUE-
|
||||
* If the Bluetooth Controller has equipped with a non-volatile memory (such
|
||||
* as BCM4330's OTP memory), the factory BDADDR can be stored in there and
|
||||
* retrieved by the stack while enabling BT.
|
||||
* !!! WARNING !!! Make sure that the OTP feature has been enabled in the
|
||||
* firmware patchram (.hcd) file.
|
||||
*/
|
||||
#ifndef USE_CONTROLLER_BDADDR
|
||||
#define USE_CONTROLLER_BDADDR TRUE //FALSE
|
||||
#endif
|
||||
|
||||
/* sleep mode
|
||||
|
||||
0: disable
|
||||
1: UART with Host wake/BT wake out of band signals
|
||||
*/
|
||||
#ifndef LPM_SLEEP_MODE
|
||||
#define LPM_SLEEP_MODE 1
|
||||
#endif
|
||||
|
||||
/* Host Stack Idle Threshold in 300ms or 25ms
|
||||
|
||||
In sleep mode 1, this is the number of firmware loops executed with no
|
||||
activity before the Host wake line is deasserted. Activity includes HCI
|
||||
traffic excluding certain sleep mode commands and the presence of SCO
|
||||
connections if the "Allow Host Sleep During SCO" flag is not set to 1.
|
||||
Each count of this parameter is roughly equivalent to 300ms or 25ms.
|
||||
*/
|
||||
#ifndef LPM_IDLE_THRESHOLD
|
||||
#define LPM_IDLE_THRESHOLD 1
|
||||
#endif
|
||||
|
||||
/* Host Controller Idle Threshold in 300ms or 25ms
|
||||
|
||||
This is the number of firmware loops executed with no activity before the
|
||||
HC is considered idle. Depending on the mode, HC may then attempt to sleep.
|
||||
Activity includes HCI traffic excluding certain sleep mode commands and
|
||||
the presence of ACL/SCO connections.
|
||||
*/
|
||||
#ifndef LPM_HC_IDLE_THRESHOLD
|
||||
#define LPM_HC_IDLE_THRESHOLD 1
|
||||
#endif
|
||||
|
||||
/* BT_WAKE Polarity - 0=Active Low, 1= Active High */
|
||||
#ifndef LPM_BT_WAKE_POLARITY
|
||||
#define LPM_BT_WAKE_POLARITY 1 /* maguro */
|
||||
#endif
|
||||
|
||||
/* HOST_WAKE Polarity - 0=Active Low, 1= Active High */
|
||||
#ifndef LPM_HOST_WAKE_POLARITY
|
||||
#define LPM_HOST_WAKE_POLARITY 1 /* maguro */
|
||||
#endif
|
||||
|
||||
/* LPM_ALLOW_HOST_SLEEP_DURING_SCO
|
||||
|
||||
When this flag is set to 0, the host is not allowed to sleep while
|
||||
an SCO is active. In sleep mode 1, the device will keep the host
|
||||
wake line asserted while an SCO is active.
|
||||
When this flag is set to 1, the host can sleep while an SCO is active.
|
||||
This flag should only be set to 1 if SCO traffic is directed to the PCM
|
||||
interface.
|
||||
*/
|
||||
#ifndef LPM_ALLOW_HOST_SLEEP_DURING_SCO
|
||||
#define LPM_ALLOW_HOST_SLEEP_DURING_SCO 1
|
||||
#endif
|
||||
|
||||
/* LPM_COMBINE_SLEEP_MODE_AND_LPM
|
||||
|
||||
In Mode 0, always set byte 7 to 0. In sleep mode 1, device always
|
||||
requires permission to sleep between scans / periodic inquiries regardless
|
||||
of the setting of this byte. In sleep mode 1, if byte is set, device must
|
||||
have "permission" to sleep during the low power modes of sniff, hold, and
|
||||
park. If byte is not set, device can sleep without permission during these
|
||||
modes. Permission to sleep in Mode 1 is obtained if the BT_WAKE signal is
|
||||
not asserted.
|
||||
*/
|
||||
#ifndef LPM_COMBINE_SLEEP_MODE_AND_LPM
|
||||
#define LPM_COMBINE_SLEEP_MODE_AND_LPM 1
|
||||
#endif
|
||||
|
||||
/* LPM_ENABLE_UART_TXD_TRI_STATE
|
||||
|
||||
When set to 0, the device will not tristate its UART TX line before going
|
||||
to sleep.
|
||||
When set to 1, the device will tristate its UART TX line before going to
|
||||
sleep.
|
||||
*/
|
||||
#ifndef LPM_ENABLE_UART_TXD_TRI_STATE
|
||||
#define LPM_ENABLE_UART_TXD_TRI_STATE 0
|
||||
#endif
|
||||
|
||||
/* LPM_PULSED_HOST_WAKE
|
||||
*/
|
||||
#ifndef LPM_PULSED_HOST_WAKE
|
||||
#define LPM_PULSED_HOST_WAKE 0
|
||||
#endif
|
||||
|
||||
/* LPM_IDLE_TIMEOUT_MULTIPLE
|
||||
|
||||
The multiple factor of host stack idle threshold in 300ms/25ms
|
||||
*/
|
||||
#ifndef LPM_IDLE_TIMEOUT_MULTIPLE
|
||||
#define LPM_IDLE_TIMEOUT_MULTIPLE 10
|
||||
#endif
|
||||
|
||||
/* BT_WAKE_VIA_USERIAL_IOCTL
|
||||
|
||||
Use userial ioctl function to control BT_WAKE signal
|
||||
*/
|
||||
#ifndef BT_WAKE_VIA_USERIAL_IOCTL
|
||||
#define BT_WAKE_VIA_USERIAL_IOCTL FALSE
|
||||
#endif
|
||||
|
||||
/* BT_WAKE_VIA_PROC
|
||||
|
||||
LPM & BT_WAKE control through PROC nodes
|
||||
*/
|
||||
#ifndef BT_WAKE_VIA_PROC
|
||||
#define BT_WAKE_VIA_PROC FALSE
|
||||
#endif
|
||||
|
||||
/* HW_END_WITH_HCI_RESET
|
||||
|
||||
Sample code implementation of sending a HCI_RESET command during the epilog
|
||||
process. It calls back to the callers after command complete of HCI_RESET
|
||||
is received.
|
||||
*/
|
||||
#ifndef HW_END_WITH_HCI_RESET
|
||||
#define HW_END_WITH_HCI_RESET FALSE
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** Extern variables and functions
|
||||
******************************************************************************/
|
||||
|
||||
extern bt_vendor_callbacks_t *bt_vendor_cbacks;
|
||||
|
||||
#endif /* BT_VENDOR_RTK_H */
|
|
@ -0,0 +1,82 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 Google, Inc.
|
||||
*
|
||||
* 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 RTK_HCI_H5_INT_H
|
||||
#define RTK_HCI_H5_INT_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bt_hci_bdroid.h"
|
||||
#include "bt_vendor_lib.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rtk_hcidefs.h"
|
||||
|
||||
//HCI Command opcodes
|
||||
#define HCI_LE_READ_BUFFER_SIZE 0x2002
|
||||
#define DATA_TYPE_H5 0x05
|
||||
|
||||
//HCI VENDOR Command opcode
|
||||
#define HCI_VSC_H5_INIT 0xFCEE
|
||||
#define HCI_VSC_UPDATE_BAUDRATE 0xFC17
|
||||
#define HCI_VSC_DOWNLOAD_FW_PATCH 0xFC20
|
||||
#define HCI_VSC_READ_ROM_VERSION 0xFC6D
|
||||
#define HCI_VSC_READ_CHIP_TYPE 0xFC61
|
||||
#define HCI_VSC_SET_WAKE_UP_DEVICE 0xFC7B
|
||||
#define HCI_VSC_BT_OFF 0xFC28
|
||||
#define HCI_READ_LMP_VERSION 0x1001
|
||||
|
||||
#define STREAM_TO_UINT16(u16, p) {u16 = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); (p) += 2;}
|
||||
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
|
||||
#define UINT32_TO_STREAM(p, u32) {*(p)++ = (uint8_t)(u32); *(p)++ = (uint8_t)((u32) >> 8); *(p)++ = (uint8_t)((u32) >> 16); *(p)++ = (uint8_t)((u32) >> 24);}
|
||||
#define STREAM_TO_UINT32(u32, p) {u32 = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + ((((uint32_t)(*((p) + 2)))) << 16) + ((((uint32_t)(*((p) + 3)))) << 24)); (p) += 4;}
|
||||
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
|
||||
|
||||
void ms_delay (uint32_t timeout);
|
||||
|
||||
|
||||
typedef enum {
|
||||
DATA_TYPE_COMMAND = 1,
|
||||
DATA_TYPE_ACL = 2,
|
||||
DATA_TYPE_SCO = 3,
|
||||
DATA_TYPE_EVENT = 4
|
||||
} serial_data_type_t;
|
||||
|
||||
|
||||
typedef struct hci_h5_callbacks_t{
|
||||
uint16_t (*h5_int_transmit_data_cb)(serial_data_type_t type, uint8_t *data, uint16_t length);
|
||||
void (*h5_data_ready_cb)(serial_data_type_t type, unsigned int total_length);
|
||||
} hci_h5_callbacks_t;
|
||||
|
||||
typedef struct hci_h5_t {
|
||||
void (*h5_int_init)(hci_h5_callbacks_t *h5_callbacks);
|
||||
void (*h5_int_cleanup)(void);
|
||||
uint16_t (*h5_send_cmd)(serial_data_type_t type, uint8_t *data, uint16_t length);
|
||||
uint8_t (*h5_send_sync_cmd)(uint16_t opcode, uint8_t *data, uint16_t length);
|
||||
uint16_t (*h5_send_acl_data)(serial_data_type_t type, uint8_t *data, uint16_t length);
|
||||
uint16_t (*h5_send_sco_data)(serial_data_type_t type, uint8_t *data, uint16_t length);
|
||||
bool (*h5_recv_msg)(uint8_t *byte, uint16_t length);
|
||||
size_t (*h5_int_read_data)(uint8_t *data_buffer, size_t max_size);
|
||||
} hci_h5_t;
|
||||
|
||||
const hci_h5_t *hci_get_h5_int_interface(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: rtk_btsnoop_net.h
|
||||
*
|
||||
* Description: A wrapper header file of bt_vendor_lib.h
|
||||
*
|
||||
* Contains definitions specific for interfacing with Realtek
|
||||
* Bluetooth chipsets
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef RTK_BTSNOOP_NET_H
|
||||
#define RTK_BTSNOOP_NET_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "hci_h5_int.h"
|
||||
#include <utils/Log.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
void rtk_btsnoop_open(void);
|
||||
void rtk_btsnoop_close(void);
|
||||
void rtk_btsnoop_capture(const HC_BT_HDR *p_buf, bool is_rcvd);
|
||||
|
||||
void rtk_btsnoop_net_open();
|
||||
void rtk_btsnoop_net_close();
|
||||
void rtk_btsnoop_net_write(serial_data_type_t type, uint8_t *data, bool is_received);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,152 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name:
|
||||
* rtk_parse.h
|
||||
*
|
||||
* Abstract:
|
||||
* Contains wifi-bt coex functions implemented by bluedroid stack
|
||||
*
|
||||
* Major Change History:
|
||||
* When Who What
|
||||
* ---------------------------------------------------------------
|
||||
* 2015-12-15 lamparten modified
|
||||
* 2014-10-23 kyle_xu modified
|
||||
*
|
||||
* Notes:
|
||||
* This is designed for wifi-bt Coex in Android 6.0.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#ifndef RTK_PARSE_H
|
||||
#define RTK_PARSE_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "bt_vendor_rtk.h"
|
||||
#include "userial_vendor.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
#define HOST_PROFILE_INFO
|
||||
|
||||
/******************************************************************************
|
||||
** Type definitions
|
||||
******************************************************************************/
|
||||
typedef unsigned char UINT8;
|
||||
#define BD_ADDR_LEN 6 /* Device address length */
|
||||
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
|
||||
typedef void* TRANSAC;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Extern variables and functions
|
||||
******************************************************************************/
|
||||
extern uint8_t coex_log_enable;
|
||||
|
||||
/******************************************************************************
|
||||
** Functions
|
||||
******************************************************************************/
|
||||
typedef struct rtk_parse_manager_t {
|
||||
|
||||
void (*rtk_parse_internal_event_intercept)(uint8_t *p);
|
||||
|
||||
void (*rtk_parse_l2cap_data)(uint8_t *p, uint8_t direction);
|
||||
|
||||
void (*rtk_parse_init)(void);
|
||||
|
||||
void (*rtk_parse_cleanup)(void);
|
||||
|
||||
void (*rtk_parse_command)(uint8_t *p);
|
||||
|
||||
void (*rtk_add_le_profile)(BD_ADDR bdaddr, uint16_t handle, uint8_t profile_map);
|
||||
|
||||
void (*rtk_delete_le_profile)(BD_ADDR bdaddr, uint16_t handle, uint8_t profile_map);
|
||||
|
||||
void (*rtk_add_le_data_count)(uint8_t data_type);
|
||||
|
||||
}rtk_parse_manager_t;
|
||||
|
||||
const rtk_parse_manager_t *rtk_parse_manager_get_interface();
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
struct sbc_frame_hdr {
|
||||
uint8_t syncword:8; /* Sync word */
|
||||
uint8_t subbands:1; /* Subbands */
|
||||
uint8_t allocation_method:1; /* Allocation method */
|
||||
uint8_t channel_mode:2; /* Channel mode */
|
||||
uint8_t blocks:2; /* Blocks */
|
||||
uint8_t sampling_frequency:2; /* Sampling frequency */
|
||||
uint8_t bitpool:8; /* Bitpool */
|
||||
uint8_t crc_check:8; /* CRC check */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* NOTE: The code is copied from pa.
|
||||
* only the bit field in 8-bit is affected by endian, not the 16-bit or 32-bit.
|
||||
* why?
|
||||
*/
|
||||
struct rtp_header {
|
||||
unsigned cc:4;
|
||||
unsigned x:1;
|
||||
unsigned p:1;
|
||||
unsigned v:2;
|
||||
|
||||
unsigned pt:7;
|
||||
unsigned m:1;
|
||||
|
||||
uint16_t sequence_number;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
uint32_t csrc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#else
|
||||
/* big endian */
|
||||
struct sbc_frame_hdr {
|
||||
uint8_t syncword:8; /* Sync word */
|
||||
uint8_t sampling_frequency:2; /* Sampling frequency */
|
||||
uint8_t blocks:2; /* Blocks */
|
||||
uint8_t channel_mode:2; /* Channel mode */
|
||||
uint8_t allocation_method:1; /* Allocation method */
|
||||
uint8_t subbands:1; /* Subbands */
|
||||
uint8_t bitpool:8; /* Bitpool */
|
||||
uint8_t crc_check:8; /* CRC check */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtp_header {
|
||||
unsigned v:2;
|
||||
unsigned p:1;
|
||||
unsigned x:1;
|
||||
unsigned cc:4;
|
||||
|
||||
unsigned m:1;
|
||||
unsigned pt:7;
|
||||
|
||||
uint16_t sequence_number;
|
||||
uint32_t timestamp;
|
||||
uint32_t ssrc;
|
||||
uint32_t csrc[0];
|
||||
} __attribute__ ((packed));
|
||||
#endif /* __LITTLE_ENDIAN */
|
||||
|
||||
#endif /*RTK_PARSE_H*/
|
|
@ -0,0 +1,73 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: userial_vendor.h
|
||||
*
|
||||
* Description: Contains vendor-specific definitions used in serial port
|
||||
* controls
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef RTK_SOCKET_H
|
||||
#define RTK_SOCKET_H
|
||||
|
||||
#include "bt_vendor_rtk.h"
|
||||
#include "userial.h"
|
||||
#include <sys/poll.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_SCO_OVER_HCI
|
||||
#define SCO_CTRL_PATH "/data/misc/bluedroid/.sco_ctrl"
|
||||
#define SCO_DATA_PATH "/data/misc/bluedroid/.sco_data"
|
||||
|
||||
typedef enum {
|
||||
SCO_CTRL_CMD_NONE,
|
||||
SCO_CTRL_CMD_CHECK_READY,
|
||||
SCO_CTRL_CMD_OUT_START,
|
||||
SCO_CTRL_CMD_IN_START,
|
||||
SCO_CTRL_CMD_OUT_STOP,
|
||||
SCO_CTRL_CMD_IN_STOP,
|
||||
SCO_CTRL_CMD_SUSPEND,
|
||||
SCO_CTRL_GET_AUDIO_CONFIG,
|
||||
SCO_CTRL_CMD_OFFLOAD_START,
|
||||
} tSCO_CTRL_CMD;
|
||||
|
||||
#define SCO_SAMPLE_RATE_8K 1
|
||||
#define SCO_SAMPLE_RATE_16K 2
|
||||
|
||||
#endif
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t Skt_Read(int fd, uint8_t *p_buf, uint32_t len);
|
||||
int Skt_Read_noblock(int fd, uint8_t *p_buf, uint32_t len);
|
||||
bool Skt_Send(int fd, uint8_t *p_buf, uint16_t msglen);
|
||||
int Skt_Send_noblock(int fd, uint8_t *p_buf, uint16_t msglen);
|
||||
#endif
|
118
android/hardware/realtek/bluetooth/libbt-vendor/include/upio.h
Normal file
118
android/hardware/realtek/bluetooth/libbt-vendor/include/upio.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: upio.h
|
||||
*
|
||||
* Description: Contains definitions used for I/O controls
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef UPIO_H
|
||||
#define UPIO_H
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
|
||||
#define UPIO_BT_POWER_OFF 0
|
||||
#define UPIO_BT_POWER_ON 1
|
||||
|
||||
/* UPIO signals */
|
||||
enum {
|
||||
UPIO_BT_WAKE = 0,
|
||||
UPIO_HOST_WAKE,
|
||||
UPIO_LPM_MODE,
|
||||
UPIO_MAX_COUNT
|
||||
};
|
||||
|
||||
/* UPIO assertion/deassertion */
|
||||
enum {
|
||||
UPIO_UNKNOWN = 0,
|
||||
UPIO_DEASSERT,
|
||||
UPIO_ASSERT
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
** Extern variables and functions
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Functions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_init
|
||||
**
|
||||
** Description Initialization
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_init(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_cleanup
|
||||
**
|
||||
** Description Clean up
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_cleanup(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_set_bluetooth_power
|
||||
**
|
||||
** Description Interact with low layer driver to set Bluetooth power
|
||||
** on/off.
|
||||
**
|
||||
** Returns 0 : SUCCESS or Not-Applicable
|
||||
** <0 : ERROR
|
||||
**
|
||||
*******************************************************************************/
|
||||
int upio_set_bluetooth_power(int on);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_set
|
||||
**
|
||||
** Description Set i/o based on polarity
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_set(uint8_t pio, uint8_t action, uint8_t polarity);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bt_wake_up_host_mode_set
|
||||
**
|
||||
** Description To enable/disable bt_wake_up_host mode.
|
||||
**
|
||||
** Returns 0 : SUCCESS or Not-Applicable
|
||||
** <0 : ERROR
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bt_wake_up_host_mode_set(uint8_t mode);
|
||||
#endif /* UPIO_H */
|
|
@ -0,0 +1,221 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: userial_vendor.h
|
||||
*
|
||||
* Description: Contains vendor-specific definitions used in serial port
|
||||
* controls
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef USERIAL_VENDOR_H
|
||||
#define USERIAL_VENDOR_H
|
||||
|
||||
#include "bt_vendor_rtk.h"
|
||||
#include "userial.h"
|
||||
#include "hci_h5_int.h"
|
||||
#include <sys/poll.h>
|
||||
#include <assert.h>
|
||||
#include "rtk_parse.h"
|
||||
#include "bt_skbuff.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
#define RTK_NO_INTR(fn) do {} while ((fn) == -1 && errno == EINTR)
|
||||
|
||||
#define RTK_GET_BOUNDARY_FLAG(handle) (((handle) >> 12) & 0x0003)
|
||||
#define RTK_START_PACKET_BOUNDARY 2
|
||||
|
||||
/**** 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)
|
||||
|
||||
|
||||
#define USERIAL_HW_FLOW_CTRL_OFF 0
|
||||
#define USERIAL_HW_FLOW_CTRL_ON 1
|
||||
|
||||
|
||||
#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
|
||||
/* These are the ioctl values used for bt_wake ioctl via UART driver. you may
|
||||
* need to redefine them on you platform!
|
||||
* Logically they need to be unique and not colide with existing uart ioctl's.
|
||||
*/
|
||||
#ifndef USERIAL_IOCTL_BT_WAKE_ASSERT
|
||||
#define USERIAL_IOCTL_BT_WAKE_ASSERT 0x8003
|
||||
#endif
|
||||
#ifndef USERIAL_IOCTL_BT_WAKE_DEASSERT
|
||||
#define USERIAL_IOCTL_BT_WAKE_DEASSERT 0x8004
|
||||
#endif
|
||||
#ifndef USERIAL_IOCTL_BT_WAKE_GET_ST
|
||||
#define USERIAL_IOCTL_BT_WAKE_GET_ST 0x8005
|
||||
#endif
|
||||
#endif // (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
|
||||
|
||||
/******************************************************************************
|
||||
** Type definitions
|
||||
******************************************************************************/
|
||||
// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
|
||||
#define COMMAND_PREAMBLE_SIZE 3
|
||||
// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
|
||||
#define ACL_PREAMBLE_SIZE 4
|
||||
// 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
|
||||
#define SCO_PREAMBLE_SIZE 3
|
||||
// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4)
|
||||
#define EVENT_PREAMBLE_SIZE 2
|
||||
|
||||
#define HCI_PACKET_TYPE_TO_INDEX(type) ((type) - 1)
|
||||
|
||||
#define COMMON_DATA_LENGTH_INDEX 3
|
||||
|
||||
#define EVENT_DATA_LENGTH_INDEX 2
|
||||
|
||||
/* Structure used to configure serial port during open */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t fmt; /* Data format */
|
||||
uint8_t baud; /* Baud rate */
|
||||
uint8_t hw_fctrl; /*hardware flowcontrol*/
|
||||
} tUSERIAL_CFG;
|
||||
|
||||
typedef enum {
|
||||
#if (BT_WAKE_VIA_USERIAL_IOCTL==TRUE)
|
||||
USERIAL_OP_ASSERT_BT_WAKE,
|
||||
USERIAL_OP_DEASSERT_BT_WAKE,
|
||||
USERIAL_OP_GET_BT_WAKE_STATE,
|
||||
#endif
|
||||
USERIAL_OP_NOP,
|
||||
} userial_vendor_ioctl_op_t;
|
||||
|
||||
enum {
|
||||
RTKBT_PACKET_IDLE,
|
||||
RTKBT_PACKET_TYPE,
|
||||
RTKBT_PACKET_HEADER,
|
||||
RTKBT_PACKET_CONTENT,
|
||||
RTKBT_PACKET_END
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
** Extern variables and functions
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Functions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function userial_vendor_init
|
||||
**
|
||||
** Description Initialize userial vendor-specific control block
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void userial_vendor_init(char *bt_device_node);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function userial_vendor_open
|
||||
**
|
||||
** Description Open the serial port with the given configuration
|
||||
**
|
||||
** Returns device fd
|
||||
**
|
||||
*******************************************************************************/
|
||||
int userial_vendor_open(tUSERIAL_CFG *p_cfg);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function userial_vendor_close
|
||||
**
|
||||
** Description Conduct vendor-specific close work
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void userial_vendor_close(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function userial_vendor_set_baud
|
||||
**
|
||||
** Description Set new baud rate
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void userial_vendor_set_baud(uint8_t userial_baud);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function userial_vendor_ioctl
|
||||
**
|
||||
** Description ioctl inteface
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void userial_vendor_ioctl(userial_vendor_ioctl_op_t op, void *p_data);
|
||||
|
||||
void userial_vendor_set_hw_fctrl(uint8_t hw_fctrl);
|
||||
|
||||
int userial_socket_open(void);
|
||||
|
||||
int userial_vendor_usb_ioctl(int operation, void* param);
|
||||
|
||||
int userial_vendor_usb_open(void);
|
||||
|
||||
#define RTK_HANDLE_EVENT
|
||||
#define RTK_HANDLE_CMD
|
||||
//#define CONFIG_SCO_OVER_HCI
|
||||
#endif /* USERIAL_VENDOR_H */
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef _VND_BUILDCFG_H
|
||||
#define _VND_BUILDCFG_H
|
||||
#define BLUETOOTH_UART_DEVICE_PORT "/dev/ttyS1"
|
||||
#define FW_PATCHFILE_LOCATION "/etc/firmware/"
|
||||
#define LPM_IDLE_TIMEOUT_MULTIPLE 5
|
||||
#define SCO_USE_I2S_INTERFACE TRUE
|
||||
#define BTVND_DBG TRUE
|
||||
#define BTHW_DBG TRUE
|
||||
#define VNDUSERIAL_DBG TRUE
|
||||
#define UPIO_DBG TRUE
|
||||
#endif
|
144
android/hardware/realtek/bluetooth/libbt-vendor/src/bt_list.c
Normal file
144
android/hardware/realtek/bluetooth/libbt-vendor/src/bt_list.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name:
|
||||
* bt_list.c
|
||||
*
|
||||
* Abstract:
|
||||
* To implement list data structure
|
||||
*
|
||||
* Major Change History:
|
||||
* When Who What
|
||||
* --------------------------------------------------------------
|
||||
* 2010-06-04 W.Bi Created
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "bt_list.h"
|
||||
|
||||
//****************************************************************************
|
||||
// Structure
|
||||
//****************************************************************************
|
||||
|
||||
|
||||
//****************************************************************************
|
||||
// FUNCTION
|
||||
//****************************************************************************
|
||||
//Initialize a list with its header
|
||||
void ListInitializeHeader(PRT_LIST_HEAD ListHead)
|
||||
{
|
||||
ListHead->Next = ListHead;
|
||||
ListHead->Prev = ListHead;
|
||||
}
|
||||
|
||||
/**
|
||||
Tell whether the list is empty
|
||||
\param [IN] ListHead <RT_LIST_ENTRY> : List header of which to be test
|
||||
*/
|
||||
unsigned char ListIsEmpty(PRT_LIST_HEAD ListHead)
|
||||
{
|
||||
return ListHead->Next == ListHead;
|
||||
}
|
||||
|
||||
/*
|
||||
Insert a new entry between two known consecutive entries.
|
||||
This is only for internal list manipulation where we know the prev&next entries already
|
||||
@New : New element to be added
|
||||
@Prev: previous element in the list
|
||||
@Next: Next element in the list
|
||||
*/
|
||||
void
|
||||
ListAdd(
|
||||
PRT_LIST_ENTRY New,
|
||||
PRT_LIST_ENTRY Prev,
|
||||
PRT_LIST_ENTRY Next
|
||||
)
|
||||
{
|
||||
Next->Prev = New;
|
||||
New->Next = Next;
|
||||
New->Prev = Prev;
|
||||
Prev->Next = New;
|
||||
}
|
||||
/**
|
||||
Add a new entry to the list.
|
||||
Insert a new entry after the specified head. This is good for implementing stacks.
|
||||
\param [IN] ListNew <RT_LIST_ENTRY> : new entry to be added
|
||||
\param [IN OUT] ListHead <RT_LIST_ENTRY> : List header after which to add new entry
|
||||
*/
|
||||
void
|
||||
ListAddToHead(
|
||||
PRT_LIST_ENTRY ListNew,
|
||||
PRT_LIST_HEAD ListHead
|
||||
)
|
||||
{
|
||||
ListAdd(ListNew, ListHead, ListHead->Next);
|
||||
}
|
||||
|
||||
/**
|
||||
Add a new entry to the list.
|
||||
Insert a new entry before the specified head. This is good for implementing queues.
|
||||
\param [IN] ListNew <RT_LIST_ENTRY> : new entry to be added
|
||||
\param [IN OUT] ListHead <RT_LIST_ENTRY> : List header before which to add new entry
|
||||
*/
|
||||
void
|
||||
ListAddToTail(
|
||||
PRT_LIST_ENTRY ListNew,
|
||||
PRT_LIST_HEAD ListHead
|
||||
)
|
||||
{
|
||||
ListAdd(ListNew, ListHead->Prev, ListHead);
|
||||
}
|
||||
|
||||
RT_LIST_ENTRY*
|
||||
ListGetTop(
|
||||
PRT_LIST_HEAD ListHead
|
||||
)
|
||||
{
|
||||
|
||||
if (ListIsEmpty(ListHead))
|
||||
return 0;
|
||||
|
||||
return ListHead->Next;
|
||||
}
|
||||
|
||||
RT_LIST_ENTRY*
|
||||
ListGetTail(
|
||||
PRT_LIST_HEAD ListHead
|
||||
)
|
||||
{
|
||||
if (ListIsEmpty(ListHead))
|
||||
return 0;
|
||||
|
||||
return ListHead->Prev;
|
||||
}
|
||||
/**
|
||||
Delete entry from the list
|
||||
Note: ListIsEmpty() on this list entry would not return true, since its state is undefined
|
||||
\param [IN] ListToDelete <RT_LIST_ENTRY> : list entry to be deleted
|
||||
*/
|
||||
void ListDeleteNode(PRT_LIST_ENTRY ListToDelete)
|
||||
{
|
||||
// if (ListToDelete->Next != NULL && ListToDelete->Prev != NULL)
|
||||
{
|
||||
ListToDelete->Next->Prev = ListToDelete->Prev;
|
||||
ListToDelete->Prev->Next = ListToDelete->Next;
|
||||
ListToDelete->Next = ListToDelete->Prev = ListToDelete;
|
||||
}
|
||||
}
|
573
android/hardware/realtek/bluetooth/libbt-vendor/src/bt_skbuff.c
Normal file
573
android/hardware/realtek/bluetooth/libbt-vendor/src/bt_skbuff.c
Normal file
|
@ -0,0 +1,573 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2016 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name:
|
||||
* bt_skbuff.c
|
||||
*
|
||||
* Abstract:
|
||||
* Data buffer managerment through whole bluetooth stack.
|
||||
*
|
||||
* Major Change History:
|
||||
* When Who What
|
||||
* --------------------------------------------------------------
|
||||
* 2010-06-11 W.Bi Created.
|
||||
*
|
||||
* Notes:
|
||||
* To reduce memory copy when pass data buffer to other layers,
|
||||
* RTK_BUFFER is designed referring to linux socket buffer.
|
||||
* But I still wonder its effect, since RTK_BUFFER is much bigger
|
||||
* than original data buffer.RTK_BUFFER will reduce its member if
|
||||
* it would not reach what i had expected.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define LOG_TAG "bt_h5"
|
||||
#undef NDEBUG
|
||||
#include <utils/Log.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#include "bt_list.h"
|
||||
#include "bt_skbuff.h"
|
||||
#include "string.h"
|
||||
#include "hci_h5_int.h"
|
||||
#define IN
|
||||
#define OUT
|
||||
|
||||
//****************************************************************************
|
||||
// CONSTANT DEFINITION
|
||||
//****************************************************************************
|
||||
///default header size
|
||||
///l2cap header(8)+hci acl(4)
|
||||
#define DEFAULT_HEADER_SIZE (8+4)
|
||||
|
||||
//RTK_BUFFER data buffer alignment
|
||||
#define RTB_ALIGN 4
|
||||
|
||||
//do alignment with RTB_ALIGN
|
||||
#define RTB_DATA_ALIGN(_Length) ((_Length + (RTB_ALIGN - 1)) & (~(RTB_ALIGN - 1)))
|
||||
|
||||
//****************************************************************************
|
||||
// STRUCTURE DEFINITION
|
||||
//****************************************************************************
|
||||
typedef struct _RTB_QUEUE_HEAD{
|
||||
RT_LIST_HEAD List;
|
||||
uint32_t QueueLen;
|
||||
pthread_mutex_t Lock;
|
||||
uint8_t Id[RTB_QUEUE_ID_LENGTH];
|
||||
}RTB_QUEUE_HEAD, *PRTB_QUEUE_HEAD;
|
||||
|
||||
//****************************************************************************
|
||||
// FUNCTION
|
||||
//****************************************************************************
|
||||
/**
|
||||
check whether queue is empty
|
||||
\return : FALSE Queue is not empty
|
||||
TRU Queue is empty
|
||||
*/
|
||||
bool
|
||||
RtbQueueIsEmpty(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
//return ListIsEmpty(&RtkQueueHead->List);
|
||||
return RtkQueueHead->QueueLen > 0 ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
Allocate a RTK_BUFFER with specified data length and reserved headroom.
|
||||
If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value.
|
||||
\param [IN] Length <uint32_t> : current data buffer length to allcated
|
||||
\param [IN] HeadRoom <uint32_t> : if caller knows reserved head space, set it; otherwise set 0 to use default value
|
||||
\return pointer to RTK_BUFFER if succeed, null otherwise
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbAllocate(
|
||||
uint32_t Length,
|
||||
uint32_t HeadRoom
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* Rtb = NULL;
|
||||
///Rtb buffer length:
|
||||
/// RTK_BUFFER 48
|
||||
/// HeadRoom HeadRomm or 12
|
||||
/// Length
|
||||
///memory size: 48 + Length + 12(default) + 8*2(header for each memory) ---> a multiple of 8
|
||||
///example: (48 + 8)+ (300 + 12 + 8) = 372
|
||||
Rtb = malloc( sizeof(RTK_BUFFER) );
|
||||
if(Rtb)
|
||||
{
|
||||
uint32_t BufferLen = HeadRoom ? (Length + HeadRoom) : (Length + DEFAULT_HEADER_SIZE);
|
||||
BufferLen = RTB_DATA_ALIGN(BufferLen);
|
||||
Rtb->Head = malloc(BufferLen);
|
||||
if(Rtb->Head)
|
||||
{
|
||||
Rtb->HeadRoom = HeadRoom ? HeadRoom : DEFAULT_HEADER_SIZE;
|
||||
Rtb->Data = Rtb->Head + Rtb->HeadRoom;
|
||||
Rtb->End = Rtb->Data;
|
||||
Rtb->Tail = Rtb->End + Length;
|
||||
Rtb->Length = 0;
|
||||
ListInitializeHeader(&Rtb->List);
|
||||
Rtb->RefCount = 1;
|
||||
return Rtb;
|
||||
}
|
||||
}
|
||||
|
||||
if (Rtb)
|
||||
{
|
||||
if (Rtb->Head)
|
||||
{
|
||||
free(Rtb->Head);
|
||||
}
|
||||
|
||||
free(Rtb);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Free specified Rtk_buffer
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : buffer to free
|
||||
*/
|
||||
void
|
||||
RtbFree(
|
||||
RTK_BUFFER* RtkBuffer
|
||||
)
|
||||
{
|
||||
if(RtkBuffer)
|
||||
{
|
||||
free(RtkBuffer->Head);
|
||||
free(RtkBuffer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Add a specified length protocal header to the start of data buffer hold by specified rtk_buffer.
|
||||
This function extends used data area of the buffer at the buffer start.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the first byte of the extra data is returned
|
||||
*/
|
||||
uint8_t*
|
||||
RtbAddHead(
|
||||
RTK_BUFFER* RtkBuffer,
|
||||
uint32_t Length
|
||||
)
|
||||
{
|
||||
|
||||
if ((uint32_t)(RtkBuffer->Data - RtkBuffer->Head) >= Length)
|
||||
{
|
||||
RtkBuffer->Data -= Length;
|
||||
RtkBuffer->Length += Length;
|
||||
RtkBuffer->HeadRoom -= Length;
|
||||
return RtkBuffer->Data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
Remove a specified length data from the start of data buffer hold by specified rtk_buffer.
|
||||
This function returns the memory to the headroom.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to remove
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the next data in the buffer is returned, usually useless
|
||||
*/
|
||||
unsigned char
|
||||
RtbRemoveHead(
|
||||
RTK_BUFFER* RtkBuffer,
|
||||
uint32_t Length
|
||||
)
|
||||
{
|
||||
|
||||
if (RtkBuffer->Length >= Length)
|
||||
{
|
||||
RtkBuffer->Data += Length;
|
||||
RtkBuffer->Length -= Length;
|
||||
RtkBuffer->HeadRoom += Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
Add a specified length protocal header to the end of data buffer hold by specified rtk_buffer.
|
||||
This function extends used data area of the buffer at the buffer end.
|
||||
\param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add
|
||||
\param [IN] Length <uint32_t> : header length
|
||||
\return Pointer to the first byte of the extra data is returned
|
||||
*/
|
||||
uint8_t*
|
||||
RtbAddTail(
|
||||
RTK_BUFFER* RtkBuffer,
|
||||
uint32_t Length
|
||||
)
|
||||
{
|
||||
|
||||
if ((uint32_t)(RtkBuffer->Tail - RtkBuffer->End) >= Length)
|
||||
{
|
||||
uint8_t* Tmp = RtkBuffer->End;
|
||||
RtkBuffer->End += Length;
|
||||
RtkBuffer->Length += Length;
|
||||
return Tmp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
RtbRemoveTail(
|
||||
IN OUT RTK_BUFFER * RtkBuffer,
|
||||
IN uint32_t Length
|
||||
)
|
||||
{
|
||||
|
||||
if ((uint32_t)(RtkBuffer->End - RtkBuffer->Data) >= Length)
|
||||
{
|
||||
RtkBuffer->End -= Length;
|
||||
RtkBuffer->Length -= Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//****************************************************************************
|
||||
// RTB list manipulation
|
||||
//****************************************************************************
|
||||
/**
|
||||
Initialize a rtb queue.
|
||||
\return Initilized rtb queue if succeed, otherwise NULL
|
||||
*/
|
||||
RTB_QUEUE_HEAD*
|
||||
RtbQueueInit(
|
||||
)
|
||||
{
|
||||
RTB_QUEUE_HEAD* RtbQueue = NULL;
|
||||
|
||||
RtbQueue = malloc(sizeof(RTB_QUEUE_HEAD));
|
||||
if(RtbQueue)
|
||||
{
|
||||
pthread_mutex_init(&RtbQueue->Lock, NULL);
|
||||
ListInitializeHeader(&RtbQueue->List);
|
||||
RtbQueue->QueueLen = 0;
|
||||
return RtbQueue;
|
||||
}
|
||||
|
||||
//error code comes here
|
||||
if (RtbQueue)
|
||||
{
|
||||
free(RtbQueue);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Free a rtb queue.
|
||||
\param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
*/
|
||||
void
|
||||
RtbQueueFree(
|
||||
RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
if (RtkQueueHead)
|
||||
{
|
||||
|
||||
|
||||
RtbEmptyQueue(RtkQueueHead);
|
||||
pthread_mutex_destroy(&RtkQueueHead->Lock);
|
||||
free(RtkQueueHead);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Queue specified RtkBuffer into a RtkQueue at list tail.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
void
|
||||
RtbQueueTail(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
)
|
||||
{
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
ListAddToTail(&RtkBuffer->List, &RtkQueueHead->List);
|
||||
RtkQueueHead->QueueLen++;
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
}
|
||||
|
||||
/**
|
||||
Queue specified RtkBuffer into a RtkQueue at list Head.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
void
|
||||
RtbQueueHead(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
)
|
||||
{
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
ListAddToHead(&RtkBuffer->List, &RtkQueueHead->List);
|
||||
RtkQueueHead->QueueLen++;
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Insert new Rtkbuffer in the old buffer
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] OldRtkBuffer <RTK_BUFFER*> : old rtk buffer
|
||||
\param [IN] NewRtkBuffer <RTK_BUFFER*> : Rtk buffer to add
|
||||
*/
|
||||
void
|
||||
RtbInsertBefore(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pOldRtkBuffer,
|
||||
IN RTK_BUFFER* pNewRtkBuffer
|
||||
)
|
||||
{
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
ListAdd(&pNewRtkBuffer->List, pOldRtkBuffer->List.Prev, &pOldRtkBuffer->List);
|
||||
RtkQueueHead->QueueLen++;
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
}
|
||||
|
||||
/**
|
||||
check whether the buffer is the last node in the queue
|
||||
*/
|
||||
unsigned char
|
||||
RtbNodeIsLast(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pRtkBuffer
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* pBuf;
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
|
||||
pBuf = (RTK_BUFFER*)RtkQueueHead->List.Prev;
|
||||
if(pBuf == pRtkBuffer)
|
||||
{
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return true;
|
||||
}
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
get the next buffer node after the specified buffer in the queue
|
||||
if the specified buffer is the last node in the queue , return NULL
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer
|
||||
\return node after the specified buffer
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbQueueNextNode(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* pRtkBuffer
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* pBuf;
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
pBuf = (RTK_BUFFER*)RtkQueueHead->List.Prev;
|
||||
if(pBuf == pRtkBuffer)
|
||||
{
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return NULL; ///< if it is already the last node in the queue , return NULL
|
||||
}
|
||||
pBuf = (RTK_BUFFER*)pRtkBuffer->List.Next;
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return pBuf; ///< return next node after this node
|
||||
}
|
||||
|
||||
/**
|
||||
Delete specified RtkBuffer from a RtkQueue.
|
||||
It don't hold spinlock itself, so caller must hold it at someplace.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to Remove
|
||||
*/
|
||||
void
|
||||
RtbRemoveNode(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead,
|
||||
IN RTK_BUFFER* RtkBuffer
|
||||
)
|
||||
{
|
||||
RtkQueueHead->QueueLen--;
|
||||
ListDeleteNode(&RtkBuffer->List);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the RtkBuffer which is the head of a RtkQueue
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return head of the RtkQueue , otherwise NULL
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbTopQueue(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* Rtb = NULL;
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
|
||||
if (RtbQueueIsEmpty(RtkQueueHead))
|
||||
{
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Rtb = (RTK_BUFFER*)RtkQueueHead->List.Next;
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
|
||||
return Rtb;
|
||||
}
|
||||
|
||||
/**
|
||||
Remove a RtkBuffer from specified rtkqueue at list tail.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return removed rtkbuffer if succeed, otherwise NULL
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbDequeueTail(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* Rtb = NULL;
|
||||
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
if (RtbQueueIsEmpty(RtkQueueHead))
|
||||
{
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return NULL;
|
||||
}
|
||||
Rtb = (RTK_BUFFER*)RtkQueueHead->List.Prev;
|
||||
RtbRemoveNode(RtkQueueHead, Rtb);
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
|
||||
return Rtb;
|
||||
}
|
||||
|
||||
/**
|
||||
Remove a RtkBuffer from specified rtkqueue at list head.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return removed rtkbuffer if succeed, otherwise NULL
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbDequeueHead(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* Rtb = NULL;
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
|
||||
if (RtbQueueIsEmpty(RtkQueueHead))
|
||||
{
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return NULL;
|
||||
}
|
||||
Rtb = (RTK_BUFFER*)RtkQueueHead->List.Next;
|
||||
RtbRemoveNode(RtkQueueHead, Rtb);
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return Rtb;
|
||||
}
|
||||
|
||||
/**
|
||||
Get current rtb queue's length.
|
||||
\param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
\return current queue's length
|
||||
*/
|
||||
signed long RtbGetQueueLen(
|
||||
IN RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
return RtkQueueHead->QueueLen;
|
||||
}
|
||||
|
||||
/**
|
||||
Empty the rtkqueue.
|
||||
\param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue
|
||||
*/
|
||||
void
|
||||
RtbEmptyQueue(
|
||||
IN OUT RTB_QUEUE_HEAD* RtkQueueHead
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* Rtb = NULL;
|
||||
pthread_mutex_lock(&RtkQueueHead->Lock);
|
||||
|
||||
while( !RtbQueueIsEmpty(RtkQueueHead))
|
||||
{
|
||||
Rtb = (RTK_BUFFER*)RtkQueueHead->List.Next;
|
||||
RtbRemoveNode(RtkQueueHead, Rtb);
|
||||
RtbFree(Rtb);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&RtkQueueHead->Lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
///Annie_tmp
|
||||
unsigned char
|
||||
RtbCheckQueueLen(IN RTB_QUEUE_HEAD* RtkQueueHead, IN uint8_t Len)
|
||||
{
|
||||
return RtkQueueHead->QueueLen < Len ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
clone buffer for upper or lower layer, because original buffer should be stored in l2cap
|
||||
\param <RTK_BUFFER* pDataBuffer: original buffer
|
||||
\return cloned buffer
|
||||
*/
|
||||
RTK_BUFFER*
|
||||
RtbCloneBuffer(
|
||||
IN RTK_BUFFER* pDataBuffer
|
||||
)
|
||||
{
|
||||
RTK_BUFFER* pNewBuffer = NULL;
|
||||
if(pDataBuffer)
|
||||
{
|
||||
pNewBuffer = RtbAllocate(pDataBuffer->Length,0);
|
||||
if(!pNewBuffer)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if(pDataBuffer->Data)
|
||||
memcpy(pNewBuffer->Data, pDataBuffer->Data, pDataBuffer->Length);
|
||||
else
|
||||
{
|
||||
RtbFree(pNewBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pNewBuffer->Length = pDataBuffer->Length;
|
||||
}
|
||||
return pNewBuffer;
|
||||
}
|
|
@ -0,0 +1,570 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: bt_vendor_rtk.c
|
||||
*
|
||||
* Description: Realtek vendor specific library implementation
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#undef NDEBUG
|
||||
#define LOG_TAG "libbt_vendor"
|
||||
#define RTKBT_RELEASE_NAME "20180321_BT_ANDROID_8.x"
|
||||
#include <utils/Log.h>
|
||||
#include "bt_vendor_rtk.h"
|
||||
#include "upio.h"
|
||||
#include "userial_vendor.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Externs
|
||||
******************************************************************************/
|
||||
extern unsigned int rtkbt_h5logfilter;
|
||||
extern unsigned int h5_log_enable;
|
||||
extern bool rtk_btsnoop_dump;
|
||||
extern bool rtk_btsnoop_net_dump;
|
||||
extern bool rtk_btsnoop_save_log;
|
||||
extern char rtk_btsnoop_path[];
|
||||
extern uint8_t coex_log_enable;
|
||||
extern void hw_config_start(char transtype);
|
||||
|
||||
#if (HW_END_WITH_HCI_RESET == TRUE)
|
||||
void hw_epilog_process(void);
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** Variables
|
||||
******************************************************************************/
|
||||
bt_vendor_callbacks_t *bt_vendor_cbacks = NULL;
|
||||
uint8_t vnd_local_bd_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
bool rtkbt_auto_restart = false;
|
||||
|
||||
/******************************************************************************
|
||||
** Local type definitions
|
||||
******************************************************************************/
|
||||
#define DEVICE_NODE_MAX_LEN 512
|
||||
#define RTKBT_CONF_FILE "/vendor/etc/bluetooth/rtkbt.conf"
|
||||
#define USB_DEVICE_DIR "/sys/bus/usb/devices"
|
||||
#define DEBUG_SCAN_USB FALSE
|
||||
|
||||
/******************************************************************************
|
||||
** Static Variables
|
||||
******************************************************************************/
|
||||
//transfer_type(4 bit) | transfer_interface(4 bit)
|
||||
char rtkbt_transtype = 0;
|
||||
static char rtkbt_device_node[DEVICE_NODE_MAX_LEN] = {0};
|
||||
|
||||
static const tUSERIAL_CFG userial_H5_cfg =
|
||||
{
|
||||
(USERIAL_DATABITS_8 | USERIAL_PARITY_EVEN | USERIAL_STOPBITS_1),
|
||||
USERIAL_BAUD_115200,
|
||||
USERIAL_HW_FLOW_CTRL_OFF
|
||||
};
|
||||
static const tUSERIAL_CFG userial_H4_cfg =
|
||||
{
|
||||
(USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1),
|
||||
USERIAL_BAUD_115200,
|
||||
USERIAL_HW_FLOW_CTRL_OFF
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Functions
|
||||
******************************************************************************/
|
||||
static int Check_Key_Value(char* path,char* key,int value){
|
||||
FILE *fp;
|
||||
char newpath[100];
|
||||
char string_get[6];
|
||||
int value_int = 0;
|
||||
memset(newpath,0,100);
|
||||
sprintf(newpath,"%s/%s",path,key);
|
||||
if((fp = fopen(newpath, "r")) != NULL){
|
||||
memset(string_get,0,6);
|
||||
if(fgets(string_get, 5, fp) != NULL)
|
||||
if(DEBUG_SCAN_USB)
|
||||
ALOGE("string_get %s =%s\n",key,string_get);
|
||||
fclose(fp);
|
||||
value_int = strtol(string_get,NULL,16);
|
||||
if(value_int == value)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Scan_Usb_Devices_For_RTK(char* path){
|
||||
char newpath[100];
|
||||
char subpath[100];
|
||||
DIR * pdir;
|
||||
DIR * newpdir;
|
||||
struct dirent * ptr;
|
||||
struct dirent * newptr;
|
||||
struct stat filestat;
|
||||
struct stat subfilestat;
|
||||
if(stat(path, &filestat) != 0){
|
||||
ALOGE("The file or path(%s) can not be get stat!\n", newpath);
|
||||
return -1;
|
||||
}
|
||||
if((filestat.st_mode & S_IFDIR) != S_IFDIR){
|
||||
ALOGE("(%s) is not be a path!\n", path);
|
||||
return -1;
|
||||
}
|
||||
pdir =opendir(path);
|
||||
/*enter sub direc*/
|
||||
while((ptr = readdir(pdir))!=NULL){
|
||||
if(strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0)
|
||||
continue;
|
||||
memset(newpath,0,100);
|
||||
sprintf(newpath,"%s/%s", path,ptr->d_name);
|
||||
if(DEBUG_SCAN_USB)
|
||||
ALOGE("The file or path(%s)\n", newpath);
|
||||
if(stat(newpath, &filestat) != 0){
|
||||
ALOGE("The file or path(%s) can not be get stat!\n", newpath);
|
||||
continue;
|
||||
}
|
||||
/* Check if it is path. */
|
||||
if((filestat.st_mode & S_IFDIR) == S_IFDIR){
|
||||
if(!Check_Key_Value(newpath,"idVendor",0x0bda))
|
||||
continue;
|
||||
newpdir =opendir(newpath);
|
||||
/*read sub directory*/
|
||||
while((newptr = readdir(newpdir))!=NULL){
|
||||
if(strcmp(newptr->d_name, ".") == 0 || strcmp(newptr->d_name, "..") == 0)
|
||||
continue;
|
||||
memset(subpath,0,100);
|
||||
sprintf(subpath,"%s/%s", newpath,newptr->d_name);
|
||||
if(DEBUG_SCAN_USB)
|
||||
ALOGE("The file or path(%s)\n", subpath);
|
||||
if(stat(subpath, &subfilestat) != 0){
|
||||
ALOGE("The file or path(%s) can not be get stat!\n", newpath);
|
||||
continue;
|
||||
}
|
||||
/* Check if it is path. */
|
||||
if((subfilestat.st_mode & S_IFDIR) == S_IFDIR){
|
||||
if(Check_Key_Value(subpath,"bInterfaceClass",0xe0) && \
|
||||
Check_Key_Value(subpath,"bInterfaceSubClass",0x01) && \
|
||||
Check_Key_Value(subpath,"bInterfaceProtocol",0x01)){
|
||||
closedir(newpdir);
|
||||
closedir(pdir);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(newpdir);
|
||||
}
|
||||
}
|
||||
closedir(pdir);
|
||||
return 0;
|
||||
}
|
||||
static char *rtk_trim(char *str) {
|
||||
while (isspace(*str))
|
||||
++str;
|
||||
|
||||
if (!*str)
|
||||
return str;
|
||||
|
||||
char *end_str = str + strlen(str) - 1;
|
||||
while (end_str > str && isspace(*end_str))
|
||||
--end_str;
|
||||
|
||||
end_str[1] = '\0';
|
||||
return str;
|
||||
}
|
||||
static void load_rtkbt_stack_conf()
|
||||
{
|
||||
char *split;
|
||||
FILE *fp = fopen(RTKBT_CONF_FILE, "rt");
|
||||
if (!fp) {
|
||||
ALOGE("%s unable to open file '%s': %s", __func__, RTKBT_CONF_FILE, strerror(errno));
|
||||
return;
|
||||
}
|
||||
int line_num = 0;
|
||||
char line[1024];
|
||||
char value[1024];
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
char *line_ptr = rtk_trim(line);
|
||||
++line_num;
|
||||
|
||||
// Skip blank and comment lines.
|
||||
if (*line_ptr == '\0' || *line_ptr == '#' || *line_ptr == '[')
|
||||
continue;
|
||||
|
||||
split = strchr(line_ptr, '=');
|
||||
if (!split) {
|
||||
ALOGE("%s no key/value separator found on line %d.", __func__, line_num);
|
||||
continue;
|
||||
}
|
||||
|
||||
*split = '\0';
|
||||
char *endptr;
|
||||
if(!strcmp(rtk_trim(line_ptr), "RtkbtLogFilter")) {
|
||||
rtkbt_h5logfilter = strtol(rtk_trim(split+1), &endptr, 0);
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "H5LogOutput")) {
|
||||
h5_log_enable = strtol(rtk_trim(split+1), &endptr, 0);
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "RtkBtsnoopDump")) {
|
||||
if(!strcmp(rtk_trim(split+1), "true"))
|
||||
rtk_btsnoop_dump = true;
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "RtkBtsnoopNetDump")) {
|
||||
if(!strcmp(rtk_trim(split+1), "true"))
|
||||
rtk_btsnoop_net_dump = true;
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "BtSnoopFileName")) {
|
||||
sprintf(rtk_btsnoop_path, "%s_rtk", rtk_trim(split+1));
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "BtSnoopSaveLog")) {
|
||||
if(!strcmp(rtk_trim(split+1), "true"))
|
||||
rtk_btsnoop_save_log = true;
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "BtCoexLogOutput")) {
|
||||
coex_log_enable = strtol(rtk_trim(split+1), &endptr, 0);
|
||||
}
|
||||
else if(!strcmp(rtk_trim(line_ptr), "RtkBtAutoRestart")) {
|
||||
if(!strcmp(rtk_trim(split+1), "true"))
|
||||
rtkbt_auto_restart = true;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
}
|
||||
|
||||
static void rtkbt_stack_conf_cleanup()
|
||||
{
|
||||
rtkbt_h5logfilter = 0;
|
||||
h5_log_enable = 0;
|
||||
rtk_btsnoop_dump = false;
|
||||
rtk_btsnoop_net_dump = false;
|
||||
}
|
||||
|
||||
static void load_rtkbt_conf()
|
||||
{
|
||||
char *split;
|
||||
memset(rtkbt_device_node, 0, sizeof(rtkbt_device_node));
|
||||
FILE *fp = fopen(RTKBT_CONF_FILE, "rt");
|
||||
if (!fp) {
|
||||
ALOGE("%s unable to open file '%s': %s", __func__, RTKBT_CONF_FILE, strerror(errno));
|
||||
strcpy(rtkbt_device_node,"/dev/rtk_btusb");
|
||||
return;
|
||||
}
|
||||
|
||||
int line_num = 0;
|
||||
char line[1024];
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
char *line_ptr = rtk_trim(line);
|
||||
++line_num;
|
||||
|
||||
// Skip blank and comment lines.
|
||||
if (*line_ptr == '\0' || *line_ptr == '#' || *line_ptr == '[')
|
||||
continue;
|
||||
|
||||
split = strchr(line_ptr, '=');
|
||||
if (!split) {
|
||||
ALOGE("%s no key/value separator found on line %d.", __func__, line_num);
|
||||
strcpy(rtkbt_device_node,"/dev/rtk_btusb");
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
*split = '\0';
|
||||
if(!strcmp(rtk_trim(line_ptr), "BtDeviceNode")) {
|
||||
strcpy(rtkbt_device_node, rtk_trim(split + 1));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
rtkbt_transtype = 0;
|
||||
if(rtkbt_device_node[0]=='?'){
|
||||
/*1.Scan_Usb_Device*/
|
||||
if(Scan_Usb_Devices_For_RTK(USB_DEVICE_DIR) == 0x01) {
|
||||
strcpy(rtkbt_device_node,"/dev/rtk_btusb");
|
||||
}
|
||||
else{
|
||||
int i = 0;
|
||||
while(rtkbt_device_node[i] != '\0'){
|
||||
rtkbt_device_node[i] = rtkbt_device_node[i+1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(split = strchr(rtkbt_device_node, ':')) {
|
||||
*split = '\0';
|
||||
if(!strcmp(rtk_trim(split + 1), "H5")) {
|
||||
rtkbt_transtype |= RTKBT_TRANS_H5;
|
||||
}
|
||||
else if(!strcmp(rtk_trim(split + 1), "H4")) {
|
||||
rtkbt_transtype |= RTKBT_TRANS_H4;
|
||||
}
|
||||
}
|
||||
else if(strcmp(rtkbt_device_node, "/dev/rtk_btusb")) {
|
||||
//default use h5
|
||||
rtkbt_transtype |= RTKBT_TRANS_H5;
|
||||
}
|
||||
|
||||
if(strcmp(rtkbt_device_node, "/dev/rtk_btusb")) {
|
||||
rtkbt_transtype |= RTKBT_TRANS_UART;
|
||||
}
|
||||
else {
|
||||
rtkbt_transtype |= RTKBT_TRANS_USB;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** BLUETOOTH VENDOR INTERFACE LIBRARY FUNCTIONS
|
||||
**
|
||||
*****************************************************************************/
|
||||
|
||||
static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
|
||||
{
|
||||
ALOGI("RTKBT_RELEASE_NAME: %s",RTKBT_RELEASE_NAME);
|
||||
ALOGI("init");
|
||||
|
||||
load_rtkbt_conf();
|
||||
load_rtkbt_stack_conf();
|
||||
if (p_cb == NULL)
|
||||
{
|
||||
ALOGE("init failed with no user callbacks!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
userial_vendor_init(rtkbt_device_node);
|
||||
|
||||
if(rtkbt_transtype & RTKBT_TRANS_UART) {
|
||||
upio_init();
|
||||
ALOGE("bt_wake_up_host_mode_set(1)");
|
||||
bt_wake_up_host_mode_set(1);
|
||||
}
|
||||
|
||||
/* store reference to user callbacks */
|
||||
bt_vendor_cbacks = (bt_vendor_callbacks_t *) p_cb;
|
||||
|
||||
/* This is handed over from the stack */
|
||||
memcpy(vnd_local_bd_addr, local_bdaddr, 6);
|
||||
|
||||
if(rtk_btsnoop_dump)
|
||||
rtk_btsnoop_open();
|
||||
if(rtk_btsnoop_net_dump)
|
||||
rtk_btsnoop_net_open();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Requested operations */
|
||||
static int op(bt_vendor_opcode_t opcode, void *param)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
//BTVNDDBG("op for %d", opcode);
|
||||
|
||||
switch(opcode)
|
||||
{
|
||||
case BT_VND_OP_POWER_CTRL:
|
||||
{
|
||||
if(rtkbt_transtype & RTKBT_TRANS_UART) {
|
||||
int *state = (int *) param;
|
||||
if (*state == BT_VND_PWR_OFF)
|
||||
{
|
||||
upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
|
||||
usleep(200000);
|
||||
BTVNDDBG("set power off and delay 200ms");
|
||||
}
|
||||
else if (*state == BT_VND_PWR_ON)
|
||||
{
|
||||
upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
|
||||
usleep(200000);
|
||||
BTVNDDBG("set power off and delay 200ms");
|
||||
upio_set_bluetooth_power(UPIO_BT_POWER_ON);
|
||||
usleep(200000);
|
||||
BTVNDDBG("set power on and delay 200ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_FW_CFG:
|
||||
{
|
||||
if(rtkbt_transtype & RTKBT_TRANS_UART) {
|
||||
hw_config_start(rtkbt_transtype);
|
||||
}
|
||||
else {
|
||||
BTVNDDBG("usb op for %d", opcode);
|
||||
ALOGE("Bt_vendor_rtk Op for BT_VND_OP_FW_CFG");
|
||||
retval = userial_vendor_usb_ioctl(DOWN_FW_CFG, NULL);
|
||||
if(retval>0){
|
||||
ALOGE("Bt_vendor_rtk Download Fw Success");
|
||||
bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
}else{
|
||||
ALOGE("Bt_vendor_rtk Download Fw failed: %s(%d)", strerror(errno), errno);
|
||||
if(rtkbt_auto_restart) {
|
||||
bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
|
||||
kill(getpid(), SIGKILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_SCO_CFG:
|
||||
{
|
||||
retval = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_USERIAL_OPEN:
|
||||
{
|
||||
if((rtkbt_transtype & RTKBT_TRANS_UART) && (rtkbt_transtype & RTKBT_TRANS_H5)) {
|
||||
int fd, idx;
|
||||
int (*fd_array)[] = (int (*)[]) param;
|
||||
if(userial_vendor_open((tUSERIAL_CFG *) &userial_H5_cfg) != -1){
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
fd = userial_socket_open();
|
||||
if (fd != -1)
|
||||
{
|
||||
for (idx=0; idx < CH_MAX; idx++)
|
||||
(*fd_array)[idx] = fd;
|
||||
}
|
||||
else
|
||||
retval = 0;
|
||||
|
||||
/* retval contains numbers of open fd of HCI channels */
|
||||
}
|
||||
else if((rtkbt_transtype & RTKBT_TRANS_UART) && (rtkbt_transtype & RTKBT_TRANS_H4)) {
|
||||
int (*fd_array)[] = (int (*)[]) param;
|
||||
int fd, idx;
|
||||
if(userial_vendor_open((tUSERIAL_CFG *) &userial_H4_cfg) != -1) {
|
||||
retval = 1;
|
||||
}
|
||||
fd = userial_socket_open();
|
||||
if (fd != -1)
|
||||
{
|
||||
for (idx=0; idx < CH_MAX; idx++)
|
||||
(*fd_array)[idx] = fd;
|
||||
}
|
||||
else
|
||||
retval = 0;
|
||||
/* retval contains numbers of open fd of HCI channels */
|
||||
}
|
||||
else {
|
||||
BTVNDDBG("USB op for %d", opcode);
|
||||
int fd, idx = 0;
|
||||
int (*fd_array)[] = (int (*)[]) param;
|
||||
for(idx = 0; idx < 10; idx++) {
|
||||
if(userial_vendor_usb_open() != -1){
|
||||
retval = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd = userial_socket_open();
|
||||
if (fd != -1)
|
||||
{
|
||||
for (idx = 0; idx < CH_MAX; idx++)
|
||||
(*fd_array)[idx] = fd;
|
||||
}
|
||||
else
|
||||
retval = 0;
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_USERIAL_CLOSE:
|
||||
{
|
||||
userial_vendor_close();
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_GET_LPM_IDLE_TIMEOUT:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_LPM_SET_MODE:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case BT_VND_OP_LPM_WAKE_SET_STATE:
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
case BT_VND_OP_EPILOG:
|
||||
{
|
||||
if(rtkbt_transtype & RTKBT_TRANS_USB) {
|
||||
if (bt_vendor_cbacks)
|
||||
{
|
||||
bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if (HW_END_WITH_HCI_RESET == FALSE)
|
||||
if (bt_vendor_cbacks)
|
||||
{
|
||||
bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS);
|
||||
}
|
||||
#else
|
||||
hw_epilog_process();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** Closes the interface */
|
||||
static void cleanup( void )
|
||||
{
|
||||
BTVNDDBG("cleanup");
|
||||
|
||||
if(rtkbt_transtype & RTKBT_TRANS_UART) {
|
||||
upio_cleanup();
|
||||
bt_wake_up_host_mode_set(0);
|
||||
}
|
||||
bt_vendor_cbacks = NULL;
|
||||
|
||||
if(rtk_btsnoop_dump)
|
||||
rtk_btsnoop_close();
|
||||
if(rtk_btsnoop_net_dump)
|
||||
rtk_btsnoop_net_close();
|
||||
rtkbt_stack_conf_cleanup();
|
||||
}
|
||||
|
||||
// Entry point of DLib
|
||||
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
|
||||
sizeof(bt_vendor_interface_t),
|
||||
init,
|
||||
op,
|
||||
cleanup
|
||||
};
|
1651
android/hardware/realtek/bluetooth/libbt-vendor/src/hardware.c
Normal file
1651
android/hardware/realtek/bluetooth/libbt-vendor/src/hardware.c
Normal file
File diff suppressed because it is too large
Load diff
2702
android/hardware/realtek/bluetooth/libbt-vendor/src/hci_h5.c
Normal file
2702
android/hardware/realtek/bluetooth/libbt-vendor/src/hci_h5.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,392 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013 Google, Inc.
|
||||
*
|
||||
* 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 "rtk_btsnoop_net"
|
||||
#include "rtk_btsnoop_net.h"
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#define DATA_DIRECT_2_ELLISY 1
|
||||
|
||||
#define HCI_COMMAND 0x01
|
||||
#define HCI_ACL_DATA_H2C 0x02
|
||||
#define HCI_ACL_DATA_C2H 0x82
|
||||
#define HCI_SCO_DATA_H2C 0x03
|
||||
#define HCI_SCO_DATA_C2H 0x83
|
||||
#define HCI_EVENT 0x84
|
||||
|
||||
#define HCI_COMMAND_PKT 0x01
|
||||
#define HCI_ACLDATA_PKT 0x02
|
||||
#define HCI_SCODATA_PKT 0x03
|
||||
#define HCI_EVENT_PKT 0x04
|
||||
|
||||
|
||||
unsigned int rtkbt_h5logfilter = 0x01;
|
||||
bool rtk_btsnoop_dump = false;
|
||||
bool rtk_btsnoop_net_dump = false;
|
||||
bool rtk_btsnoop_save_log = false;
|
||||
char rtk_btsnoop_path[1024] = {'\0'};
|
||||
static pthread_mutex_t btsnoop_log_lock;
|
||||
|
||||
|
||||
static void rtk_safe_close_(int *fd);
|
||||
static void *rtk_listen_fn_(void *context);
|
||||
|
||||
static const char *RTK_LISTEN_THREAD_NAME_ = "rtk_btsnoop_net";
|
||||
static const int RTK_LOCALHOST_ = 0xC0A80AE2; // 192.168.10.226
|
||||
static const int RTK_LISTEN_PORT_ = 8872;
|
||||
|
||||
static const int RTK_REMOTEHOST_ = 0xC0A80A03; // 192.168.10.21
|
||||
static const int RTK_REMOTE_PORT_ = 24352;
|
||||
|
||||
|
||||
static pthread_t rtk_listen_thread_;
|
||||
static bool rtk_listen_thread_valid_ = false;
|
||||
static pthread_mutex_t rtk_client_socket_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int rtk_listen_socket_ = -1;
|
||||
|
||||
// File descriptor for btsnoop file.
|
||||
static int hci_btsnoop_fd = -1;
|
||||
// Epoch in microseconds since 01/01/0000.
|
||||
static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
|
||||
|
||||
|
||||
static uint64_t rtk_btsnoop_timestamp(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
// Timestamp is in microseconds.
|
||||
uint64_t timestamp = tv.tv_sec * 1000LL * 1000LL;
|
||||
timestamp += tv.tv_usec;
|
||||
timestamp += BTSNOOP_EPOCH_DELTA;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
void rtk_btsnoop_open()
|
||||
{
|
||||
pthread_mutex_init(&btsnoop_log_lock, NULL);
|
||||
char last_log_path[PATH_MAX];
|
||||
uint64_t timestamp;
|
||||
uint32_t usec;
|
||||
uint8_t sec,hour, minus,day;
|
||||
|
||||
if (hci_btsnoop_fd != -1) {
|
||||
ALOGE("%s btsnoop log file is already open.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rtk_btsnoop_save_log) {
|
||||
timestamp = rtk_btsnoop_timestamp() - BTSNOOP_EPOCH_DELTA;
|
||||
usec = (uint32_t)(timestamp % 1000000LL);
|
||||
timestamp /= 1000000LL;
|
||||
sec = (uint8_t)(timestamp % 60LL);
|
||||
timestamp /= 60LL;
|
||||
minus = (uint8_t)(timestamp % 60LL);
|
||||
timestamp /= 60LL;
|
||||
hour = (uint8_t)(timestamp % 24LL);
|
||||
timestamp /= 24LL;
|
||||
day = (uint8_t)(timestamp % 30LL);
|
||||
timestamp /= 30LL;
|
||||
//snprintf(last_log_path, PATH_MAX, "%s.%llu", rtk_btsnoop_path, rtk_btsnoop_timestamp());
|
||||
snprintf(last_log_path, PATH_MAX, "%s.%uY-%dD-%dH-%dM-%dS-%dUS", rtk_btsnoop_path,
|
||||
(uint32_t)timestamp, day, hour, minus, sec, usec);
|
||||
if (!rename(rtk_btsnoop_path, last_log_path) && errno != ENOENT)
|
||||
ALOGE("%s unable to rename '%s' to '%s': %s", __func__, rtk_btsnoop_path, last_log_path, strerror(errno));
|
||||
}
|
||||
else {
|
||||
snprintf(last_log_path, PATH_MAX, "%s.last", rtk_btsnoop_path);
|
||||
if (!rename(rtk_btsnoop_path, last_log_path) && errno != ENOENT)
|
||||
ALOGE("%s unable to rename '%s' to '%s': %s", __func__, rtk_btsnoop_path, last_log_path, strerror(errno));
|
||||
}
|
||||
|
||||
hci_btsnoop_fd = open(rtk_btsnoop_path,
|
||||
O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||
|
||||
if (hci_btsnoop_fd == -1) {
|
||||
ALOGE("%s unable to open '%s': %s", __func__, rtk_btsnoop_path, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
write(hci_btsnoop_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
|
||||
}
|
||||
|
||||
void rtk_btsnoop_close(void) {
|
||||
pthread_mutex_destroy(&btsnoop_log_lock);
|
||||
if (hci_btsnoop_fd != -1)
|
||||
close(hci_btsnoop_fd);
|
||||
hci_btsnoop_fd = -1;
|
||||
}
|
||||
|
||||
static void rtk_btsnoop_write(const void *data, size_t length) {
|
||||
if (hci_btsnoop_fd != -1)
|
||||
write(hci_btsnoop_fd, data, length);
|
||||
}
|
||||
|
||||
static void rtk_btsnoop_write_packet(serial_data_type_t type, const uint8_t *packet, bool is_received) {
|
||||
int length_he = 0;
|
||||
int length;
|
||||
int flags;
|
||||
int drops = 0;
|
||||
pthread_mutex_lock(&btsnoop_log_lock);
|
||||
switch (type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
length_he = packet[2] + 4;
|
||||
flags = 2;
|
||||
break;
|
||||
case HCI_ACLDATA_PKT:
|
||||
length_he = (packet[3] << 8) + packet[2] + 5;
|
||||
flags = is_received;
|
||||
break;
|
||||
case HCI_SCODATA_PKT:
|
||||
length_he = packet[2] + 4;
|
||||
flags = is_received;
|
||||
break;
|
||||
case HCI_EVENT_PKT:
|
||||
length_he = packet[1] + 3;
|
||||
flags = 3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t timestamp = rtk_btsnoop_timestamp();
|
||||
uint32_t time_hi = timestamp >> 32;
|
||||
uint32_t time_lo = timestamp & 0xFFFFFFFF;
|
||||
|
||||
length = htonl(length_he);
|
||||
flags = htonl(flags);
|
||||
drops = htonl(drops);
|
||||
time_hi = htonl(time_hi);
|
||||
time_lo = htonl(time_lo);
|
||||
|
||||
rtk_btsnoop_write(&length, 4);
|
||||
rtk_btsnoop_write(&length, 4);
|
||||
rtk_btsnoop_write(&flags, 4);
|
||||
rtk_btsnoop_write(&drops, 4);
|
||||
rtk_btsnoop_write(&time_hi, 4);
|
||||
rtk_btsnoop_write(&time_lo, 4);
|
||||
rtk_btsnoop_write(&type, 1);
|
||||
rtk_btsnoop_write(packet, length_he - 1);
|
||||
pthread_mutex_unlock(&btsnoop_log_lock);
|
||||
}
|
||||
|
||||
void rtk_btsnoop_capture(const HC_BT_HDR *p_buf, bool is_rcvd) {
|
||||
const uint8_t *p = (const uint8_t *)(p_buf + 1) + p_buf->offset;
|
||||
|
||||
if (hci_btsnoop_fd == -1)
|
||||
return;
|
||||
|
||||
switch (p_buf->event & MSG_EVT_MASK) {
|
||||
case MSG_HC_TO_STACK_HCI_EVT:
|
||||
if((*(p + 3) == 0x94) && (*(p + 4) == 0xfc) && (*(p + 5) == 0x00)&&(rtkbt_h5logfilter&1)){}
|
||||
else
|
||||
rtk_btsnoop_write_packet(HCI_EVENT_PKT, p, false);
|
||||
break;
|
||||
case MSG_HC_TO_STACK_HCI_ACL:
|
||||
case MSG_STACK_TO_HC_HCI_ACL:
|
||||
rtk_btsnoop_write_packet(HCI_ACLDATA_PKT, p, is_rcvd);
|
||||
break;
|
||||
case MSG_HC_TO_STACK_HCI_SCO:
|
||||
case MSG_STACK_TO_HC_HCI_SCO:
|
||||
rtk_btsnoop_write_packet(HCI_SCODATA_PKT, p, is_rcvd);
|
||||
break;
|
||||
case MSG_STACK_TO_HC_HCI_CMD:
|
||||
if(((rtkbt_h5logfilter & 1) == 0) || (*p != 0x94) || (*(p + 1) != 0xfc))
|
||||
rtk_btsnoop_write_packet(HCI_COMMAND_PKT, p, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtk_btsnoop_net_open() {
|
||||
rtk_listen_thread_valid_ = (pthread_create(&rtk_listen_thread_, NULL, rtk_listen_fn_, NULL) == 0);
|
||||
if (!rtk_listen_thread_valid_) {
|
||||
ALOGE("%s pthread_create failed: %s", __func__, strerror(errno));
|
||||
} else {
|
||||
ALOGD("initialized");
|
||||
}
|
||||
}
|
||||
|
||||
void rtk_btsnoop_net_close() {
|
||||
if (rtk_listen_thread_valid_) {
|
||||
shutdown(rtk_listen_socket_, SHUT_RDWR);
|
||||
pthread_join(rtk_listen_thread_, NULL);
|
||||
rtk_listen_thread_valid_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void rtk_btsnoop_net_write(serial_data_type_t type, uint8_t *data, bool is_received) {
|
||||
if (rtk_listen_socket_ == -1) {
|
||||
return;
|
||||
}
|
||||
int length = 0;
|
||||
uint8_t *p = data;
|
||||
|
||||
switch (type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
if(((rtkbt_h5logfilter & 1) == 0) || (*p != 0x94) || (*(p + 1) != 0xfc))
|
||||
length = data[2] + 3;
|
||||
else
|
||||
return;
|
||||
break;
|
||||
case HCI_ACLDATA_PKT:
|
||||
length = (data[3] << 8) + data[2] + 4;
|
||||
break;
|
||||
case HCI_SCODATA_PKT:
|
||||
length = data[2] + 3;
|
||||
break;
|
||||
case HCI_EVENT_PKT:
|
||||
if((*(p + 3) == 0x94) && (*(p + 4) == 0xfc) && (*(p + 5) == 0x00)&&(rtkbt_h5logfilter&1)){return;}
|
||||
else
|
||||
length = data[1] + 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
uint8_t buffer[4126] = {0};
|
||||
//uint8_t test_buffer[] = {0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x00};
|
||||
//uint8_t test_buffer2[] = {0x01, 0x10, 0x00};
|
||||
struct sockaddr_in client_addr;
|
||||
int i = 0;
|
||||
|
||||
#if DATA_DIRECT_2_ELLISY
|
||||
uint8_t bit_rate[4] = {0x00, 0x1b, 0x37, 0x4b};
|
||||
struct tm *t;
|
||||
time_t tt;
|
||||
time(&tt);
|
||||
t = localtime(&tt);
|
||||
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
uint64_t nano_time = (t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec) * 1000 * 1000LL * 1000 + tv.tv_usec * 1000;
|
||||
uint16_t year = (t->tm_year + 1900) & 0xFFFF;
|
||||
uint8_t month = (t->tm_mon+1) & 0xFF;
|
||||
uint8_t day =
|
||||
buffer[0] = 0x02;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x01;
|
||||
buffer[3] = 0x02;
|
||||
//time
|
||||
memcpy(&buffer[4], &year, 2);
|
||||
buffer[6] = month;
|
||||
buffer[7] = day;
|
||||
memcpy(&buffer[8], &nano_time, 6);
|
||||
//bit rate
|
||||
buffer[14] = 0x80;
|
||||
memcpy(&buffer[15], bit_rate, 4);
|
||||
//type
|
||||
buffer[19] = 0x81;
|
||||
i = 20;
|
||||
#else
|
||||
memcpy(&buffer[i], &length, sizeof(int));
|
||||
i = 4;
|
||||
#endif
|
||||
switch (type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
buffer[i] = HCI_COMMAND;
|
||||
break;
|
||||
|
||||
case HCI_ACLDATA_PKT:
|
||||
if(is_received) {
|
||||
buffer[i] = HCI_ACL_DATA_C2H;
|
||||
}
|
||||
else {
|
||||
buffer[i] = HCI_ACL_DATA_H2C;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_SCODATA_PKT:
|
||||
if(is_received) {
|
||||
buffer[i] = HCI_SCO_DATA_C2H;
|
||||
}
|
||||
else {
|
||||
buffer[i] = HCI_SCO_DATA_H2C;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PKT:
|
||||
buffer[i] = HCI_EVENT;
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer[i] = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
#if DATA_DIRECT_2_ELLISY
|
||||
//buffer[i] = HCI_COMMAND;
|
||||
buffer[21] = 0x82;
|
||||
i = 22;
|
||||
#else
|
||||
i = 5;
|
||||
#endif
|
||||
memcpy(&buffer[i], data, length);
|
||||
//memcpy(&buffer[i], test_buffer2, 3);
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
client_addr.sin_family = AF_INET;
|
||||
client_addr.sin_addr.s_addr = htonl(RTK_REMOTEHOST_);
|
||||
client_addr.sin_port = htons(RTK_REMOTE_PORT_);
|
||||
pthread_mutex_lock(&rtk_client_socket_lock_);
|
||||
sendto(rtk_listen_socket_, buffer, (length+i), 0,(struct sockaddr*)&client_addr, sizeof(struct sockaddr_in));
|
||||
//sendto(rtk_listen_socket_, buffer, 25, 0,(struct sockaddr*)&client_addr, sizeof(struct sockaddr_in));
|
||||
pthread_mutex_unlock(&rtk_client_socket_lock_);
|
||||
}
|
||||
|
||||
static void *rtk_listen_fn_(void *context) {
|
||||
prctl(PR_SET_NAME, (unsigned long)RTK_LISTEN_THREAD_NAME_, 0, 0, 0);
|
||||
|
||||
rtk_listen_socket_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (rtk_listen_socket_ == -1) {
|
||||
ALOGE("%s socket creation failed: %s", __func__, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(RTK_LOCALHOST_);
|
||||
addr.sin_port = htons(RTK_LISTEN_PORT_);
|
||||
|
||||
struct sockaddr_in client_addr;
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
client_addr.sin_family = AF_INET;
|
||||
client_addr.sin_addr.s_addr = htonl(RTK_REMOTEHOST_);
|
||||
client_addr.sin_port = htons(RTK_REMOTE_PORT_);
|
||||
|
||||
if (bind(rtk_listen_socket_, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
ALOGE("%s unable to bind listen socket: %s", __func__, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
cleanup:
|
||||
rtk_safe_close_(&rtk_listen_socket_);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rtk_safe_close_(int *fd) {
|
||||
assert(fd != NULL);
|
||||
if (*fd != -1) {
|
||||
close(*fd);
|
||||
*fd = -1;
|
||||
}
|
||||
}
|
2797
android/hardware/realtek/bluetooth/libbt-vendor/src/rtk_parse.c
Normal file
2797
android/hardware/realtek/bluetooth/libbt-vendor/src/rtk_parse.c
Normal file
File diff suppressed because it is too large
Load diff
191
android/hardware/realtek/bluetooth/libbt-vendor/src/rtk_socket.c
Normal file
191
android/hardware/realtek/bluetooth/libbt-vendor/src/rtk_socket.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: userial_vendor.c
|
||||
*
|
||||
* Description: Contains vendor-specific userial functions
|
||||
*
|
||||
******************************************************************************/
|
||||
#undef NDEBUG
|
||||
#define LOG_TAG "rtk_socket"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include "userial.h"
|
||||
#include "userial_vendor.h"
|
||||
#include "rtk_socket.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Extern functions
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
** Local type definitions
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Static functions
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** functions
|
||||
******************************************************************************/
|
||||
uint32_t Skt_Read(int fd, uint8_t *p_buf, uint32_t len)
|
||||
{
|
||||
int n_read = 0;
|
||||
struct pollfd pfd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (n_read < (int)len)
|
||||
{
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
|
||||
/* make sure there is data prior to attempting read to avoid blocking
|
||||
a read for more than poll timeout */
|
||||
|
||||
int poll_ret;
|
||||
RTK_NO_INTR(poll_ret = poll(&pfd, 1, 100));
|
||||
if (poll_ret == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (poll_ret < 0) {
|
||||
ALOGE("%s(): poll() failed: return %d errno %d (%s)",
|
||||
__func__, poll_ret, errno, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (pfd.revents & (POLLHUP|POLLNVAL) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t n;
|
||||
RTK_NO_INTR(n = recv(fd, p_buf + n_read, len - n_read, 0));
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
ALOGE("Skt_Read : channel detached remotely");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
ALOGE("Skt_Read : read failed (%s)", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
n_read += n;
|
||||
|
||||
}
|
||||
|
||||
return n_read;
|
||||
}
|
||||
|
||||
int Skt_Read_noblock(int fd, uint8_t *p_buf, uint32_t len)
|
||||
{
|
||||
int n_read = 0;
|
||||
struct pollfd pfd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
ALOGE("UIPC_Read_noblock closed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN|POLLHUP;
|
||||
|
||||
if (poll(&pfd, 1, 0) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pfd.revents & (POLLHUP|POLLNVAL) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
n_read = recv(fd, p_buf, len, MSG_DONTWAIT|MSG_NOSIGNAL);
|
||||
|
||||
return n_read;
|
||||
}
|
||||
|
||||
bool Skt_Send(int fd, uint8_t *p_buf, uint16_t msglen)
|
||||
{
|
||||
ssize_t ret;
|
||||
RTK_NO_INTR(ret = write(fd, p_buf, msglen));
|
||||
if (ret < 0) {
|
||||
ALOGE("failed to write (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int Skt_Send_noblock(int fd, uint8_t *p_buf, uint16_t msglen)
|
||||
{
|
||||
int res = 0;
|
||||
struct pollfd pfd;
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLOUT|POLLHUP;
|
||||
if (poll(&pfd, 1, 0) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pfd.revents & (POLLHUP|POLLNVAL) )
|
||||
{
|
||||
ALOGE("poll : channel detached remotely");
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = send(fd, p_buf, msglen, MSG_DONTWAIT);
|
||||
if (res < 0)
|
||||
{
|
||||
ALOGE("failed to write (%s)", strerror(errno));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** Static variables
|
||||
******************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** Helper Functions
|
||||
*****************************************************************************/
|
||||
|
||||
|
532
android/hardware/realtek/bluetooth/libbt-vendor/src/upio.c
Normal file
532
android/hardware/realtek/bluetooth/libbt-vendor/src/upio.c
Normal file
|
@ -0,0 +1,532 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012 Realtek 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Filename: upio.c
|
||||
*
|
||||
* Description: Contains I/O functions, like
|
||||
* rfkill control
|
||||
* BT_WAKE/HOST_WAKE control
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#define LOG_TAG "bt_upio"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <cutils/properties.h>
|
||||
#include "bt_vendor_rtk.h"
|
||||
#include "upio.h"
|
||||
#include "userial_vendor.h"
|
||||
|
||||
/******************************************************************************
|
||||
** Constants & Macros
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef UPIO_DBG
|
||||
#define UPIO_DBG FALSE
|
||||
#endif
|
||||
|
||||
#if (UPIO_DBG == TRUE)
|
||||
#define UPIODBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
|
||||
#else
|
||||
#define UPIODBG(param, ...) {}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** Local type definitions
|
||||
******************************************************************************/
|
||||
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
|
||||
/* proc fs node for enable/disable lpm mode */
|
||||
#ifndef VENDOR_LPM_PROC_NODE
|
||||
#define VENDOR_LPM_PROC_NODE "/proc/bluetooth/sleep/lpm"
|
||||
#endif
|
||||
|
||||
/* proc fs node for notifying write request */
|
||||
#ifndef VENDOR_BTWRITE_PROC_NODE
|
||||
#define VENDOR_BTWRITE_PROC_NODE "/proc/bluetooth/sleep/btwrite"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximum btwrite assertion holding time without consecutive btwrite kicking.
|
||||
* This value is correlative(shorter) to the in-activity timeout period set in
|
||||
* the bluesleep LPM code. The current value used in bluesleep is 10sec.
|
||||
*/
|
||||
#ifndef PROC_BTWRITE_TIMER_TIMEOUT_MS
|
||||
#define PROC_BTWRITE_TIMER_TIMEOUT_MS 8000
|
||||
#endif
|
||||
|
||||
/* lpm proc control block */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t btwrite_active;
|
||||
uint8_t timer_created;
|
||||
timer_t timer_id;
|
||||
uint32_t timeout_ms;
|
||||
} vnd_lpm_proc_cb_t;
|
||||
|
||||
static vnd_lpm_proc_cb_t lpm_proc_cb;
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** Static variables
|
||||
******************************************************************************/
|
||||
|
||||
static uint8_t upio_state[UPIO_MAX_COUNT];
|
||||
static int rfkill_id = -1;
|
||||
static int bt_emul_enable = 0;
|
||||
static char *rfkill_state_path = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
** Static functions
|
||||
******************************************************************************/
|
||||
|
||||
/* for friendly debugging outpout string */
|
||||
static char *lpm_mode[] = {
|
||||
"UNKNOWN",
|
||||
"disabled",
|
||||
"enabled"
|
||||
};
|
||||
|
||||
static char *lpm_state[] = {
|
||||
"UNKNOWN",
|
||||
"de-asserted",
|
||||
"asserted"
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Bluetooth On/Off Static Functions
|
||||
*****************************************************************************/
|
||||
static int is_emulator_context(void)
|
||||
{
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
|
||||
property_get("ro.kernel.qemu", value, "0");
|
||||
UPIODBG("is_emulator_context : %s", value);
|
||||
if (strcmp(value, "1") == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_rfkill_disabled(void)
|
||||
{
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
|
||||
property_get("ro.rfkilldisabled", value, "0");
|
||||
UPIODBG("is_rfkill_disabled ? [%s]", value);
|
||||
|
||||
if (strcmp(value, "1") == 0) {
|
||||
return UPIO_BT_POWER_ON;
|
||||
}
|
||||
|
||||
return UPIO_BT_POWER_OFF;
|
||||
}
|
||||
|
||||
static int init_rfkill()
|
||||
{
|
||||
char path[64];
|
||||
char buf[16];
|
||||
int fd, sz, id;
|
||||
|
||||
if (is_rfkill_disabled())
|
||||
return -1;
|
||||
|
||||
for (id = 0; ; id++)
|
||||
{
|
||||
snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \
|
||||
path, strerror(errno), errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sz = read(fd, &buf, sizeof(buf));
|
||||
close(fd);
|
||||
|
||||
if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)
|
||||
{
|
||||
rfkill_id = id;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_wake_up_host_mode_set(uint8_t mode)
|
||||
{
|
||||
char path[64];
|
||||
char buffer = '0';
|
||||
int sz;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
ALOGE("bt_wake_up_host_mode_set");
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/bluetooth/sleep/lpm");
|
||||
ALOGE("bt_wake_up_host_mode_set path:%s", path);
|
||||
|
||||
fd = open(path, O_WRONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
ALOGE("bt_wake_up_host_mode_set fd:%d = open(path, O_RDWR): open(%s) failed: %s (%d)\n", \
|
||||
fd, path, strerror(errno), errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ALOGE("bt_wake_up_host_mode_set fd:%d = open(path, O_RDWR): open(%s) success\n", \
|
||||
fd, path);
|
||||
|
||||
if(mode == 1)
|
||||
{
|
||||
buffer = '1';
|
||||
} else {
|
||||
buffer = '0';
|
||||
}
|
||||
|
||||
ALOGE("bt_wake_up_host_mode_set buffer:%d", buffer);
|
||||
sz = write(fd, &buffer, 1);
|
||||
|
||||
if (sz < 0) {
|
||||
ALOGE("bt_wake_up_host_mode_set : write(%s) failed: %s (%d)",
|
||||
rfkill_state_path, strerror(errno),errno);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** LPM Static Functions
|
||||
*****************************************************************************/
|
||||
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function proc_btwrite_timeout
|
||||
**
|
||||
** Description Timeout thread of proc/.../btwrite assertion holding timer
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void proc_btwrite_timeout(union sigval arg)
|
||||
{
|
||||
UPIODBG("..%s..", __FUNCTION__);
|
||||
lpm_proc_cb.btwrite_active = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** UPIO Interface Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_init
|
||||
**
|
||||
** Description Initialization
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_init(void)
|
||||
{
|
||||
memset(upio_state, UPIO_UNKNOWN, UPIO_MAX_COUNT);
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
memset(&lpm_proc_cb, 0, sizeof(vnd_lpm_proc_cb_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_cleanup
|
||||
**
|
||||
** Description Clean up
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_cleanup(void)
|
||||
{
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
if (lpm_proc_cb.timer_created == TRUE)
|
||||
timer_delete(lpm_proc_cb.timer_id);
|
||||
|
||||
lpm_proc_cb.timer_created = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_set_bluetooth_power
|
||||
**
|
||||
** Description Interact with low layer driver to set Bluetooth power
|
||||
** on/off.
|
||||
**
|
||||
** Returns 0 : SUCCESS or Not-Applicable
|
||||
** <0 : ERROR
|
||||
**
|
||||
*******************************************************************************/
|
||||
int upio_set_bluetooth_power(int on)
|
||||
{
|
||||
int sz;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
char buffer = '0';
|
||||
|
||||
switch(on)
|
||||
{
|
||||
case UPIO_BT_POWER_OFF:
|
||||
buffer = '0';
|
||||
break;
|
||||
|
||||
case UPIO_BT_POWER_ON:
|
||||
buffer = '1';
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_emulator_context())
|
||||
{
|
||||
/* if new value is same as current, return -1 */
|
||||
if (bt_emul_enable == on)
|
||||
return ret;
|
||||
|
||||
UPIODBG("set_bluetooth_power [emul] %d", on);
|
||||
|
||||
bt_emul_enable = on;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if we have rfkill interface */
|
||||
if (is_rfkill_disabled())
|
||||
return 0;
|
||||
|
||||
if (rfkill_id == -1)
|
||||
{
|
||||
if (init_rfkill())
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = open(rfkill_state_path, O_WRONLY);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",
|
||||
rfkill_state_path, strerror(errno), errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sz = write(fd, &buffer, 1);
|
||||
|
||||
if (sz < 0) {
|
||||
ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",
|
||||
rfkill_state_path, strerror(errno),errno);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function upio_set
|
||||
**
|
||||
** Description Set i/o based on polarity
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
|
||||
{
|
||||
int rc;
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
int fd = -1;
|
||||
char buffer;
|
||||
#endif
|
||||
|
||||
switch (pio)
|
||||
{
|
||||
case UPIO_LPM_MODE:
|
||||
if (upio_state[UPIO_LPM_MODE] == action)
|
||||
{
|
||||
UPIODBG("LPM is %s already", lpm_mode[action]);
|
||||
return;
|
||||
}
|
||||
|
||||
upio_state[UPIO_LPM_MODE] = action;
|
||||
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
fd = open(VENDOR_LPM_PROC_NODE, O_WRONLY);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
ALOGE("upio_set : open(%s) for write failed: %s (%d)",
|
||||
VENDOR_LPM_PROC_NODE, strerror(errno), errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == UPIO_ASSERT)
|
||||
{
|
||||
buffer = '1';
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = '0';
|
||||
|
||||
// delete btwrite assertion holding timer
|
||||
if (lpm_proc_cb.timer_created == TRUE)
|
||||
{
|
||||
timer_delete(lpm_proc_cb.timer_id);
|
||||
lpm_proc_cb.timer_created = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (write(fd, &buffer, 1) < 0)
|
||||
{
|
||||
ALOGE("upio_set : write(%s) failed: %s (%d)",
|
||||
VENDOR_LPM_PROC_NODE, strerror(errno),errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (action == UPIO_ASSERT)
|
||||
{
|
||||
// create btwrite assertion holding timer
|
||||
if (lpm_proc_cb.timer_created == FALSE)
|
||||
{
|
||||
int status;
|
||||
struct sigevent se;
|
||||
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = &lpm_proc_cb.timer_id;
|
||||
se.sigev_notify_function = proc_btwrite_timeout;
|
||||
se.sigev_notify_attributes = NULL;
|
||||
|
||||
status = timer_create(CLOCK_MONOTONIC, &se,
|
||||
&lpm_proc_cb.timer_id);
|
||||
|
||||
if (status == 0)
|
||||
lpm_proc_cb.timer_created = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case UPIO_BT_WAKE:
|
||||
if (upio_state[UPIO_BT_WAKE] == action)
|
||||
{
|
||||
UPIODBG("BT_WAKE is %s already", lpm_state[action]);
|
||||
|
||||
#if (BT_WAKE_VIA_PROC == TRUE)
|
||||
if (lpm_proc_cb.btwrite_active == TRUE)
|
||||
/*
|
||||
* The proc btwrite node could have not been updated for
|
||||
* certain time already due to heavy downstream path flow.
|
||||
* In this case, we want to explicity touch proc btwrite
|
||||
* node to keep the bt_wake assertion in the LPM kernel
|
||||
* driver. The current kernel bluesleep LPM code starts
|
||||
* a 10sec internal in-activity timeout timer before it
|
||||
* attempts to deassert BT_WAKE line.
|
||||
*/
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
upio_state[UPIO_BT_WAKE] = action;
|
||||
|
||||
#if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE)
|
||||
|
||||
userial_vendor_ioctl( ( (action==UPIO_ASSERT) ? \
|
||||
USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE),\
|
||||
NULL);
|
||||
|
||||
#elif (BT_WAKE_VIA_PROC == TRUE)
|
||||
|
||||
/*
|
||||
* Kick proc btwrite node only at UPIO_ASSERT
|
||||
*/
|
||||
if (action == UPIO_DEASSERT)
|
||||
return;
|
||||
|
||||
fd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
ALOGE("upio_set : open(%s) for write failed: %s (%d)",
|
||||
VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = '1';
|
||||
|
||||
if (write(fd, &buffer, 1) < 0)
|
||||
{
|
||||
ALOGE("upio_set : write(%s) failed: %s (%d)",
|
||||
VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
lpm_proc_cb.btwrite_active = TRUE;
|
||||
|
||||
if (lpm_proc_cb.timer_created == TRUE)
|
||||
{
|
||||
struct itimerspec ts;
|
||||
|
||||
ts.it_value.tv_sec = PROC_BTWRITE_TIMER_TIMEOUT_MS/1000;
|
||||
ts.it_value.tv_nsec = 1000*(PROC_BTWRITE_TIMER_TIMEOUT_MS%1000);
|
||||
ts.it_interval.tv_sec = 0;
|
||||
ts.it_interval.tv_nsec = 0;
|
||||
|
||||
timer_settime(lpm_proc_cb.timer_id, 0, &ts, 0);
|
||||
}
|
||||
}
|
||||
|
||||
UPIODBG("proc btwrite assertion");
|
||||
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case UPIO_HOST_WAKE:
|
||||
UPIODBG("upio_set: UPIO_HOST_WAKE");
|
||||
break;
|
||||
}
|
||||
}
|
1955
android/hardware/realtek/bluetooth/libbt-vendor/src/userial_vendor.c
Normal file
1955
android/hardware/realtek/bluetooth/libbt-vendor/src/userial_vendor.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue