关键词:bluedroid  initNative enableNative BTIF_TASK  BTU_TASKbt_hc_work_thread set_power  preload  GKI
作者:xubin341719(欢迎转载。请注明作者,请尊重版权。谢谢。)
欢迎指正错误,共同学习、共同进步!!

一、   蓝牙开启流程概述,例如以下图所看到的:init、enable

和一般的函数调用同样。android上层通过APP-->Native-->JNI-->bluetoothinterface-->bluetooth HCIinterface。

HCI interface中实现了init、set_power、preload对应函数
init、enable函数主要实现的功能:
(1)、创建:btif_task/BTIF_TASK
(2)、初始化BTE
(3)、创建:btu_task/BTU_TASK
(4)、初始化HCI、串口相关,启动HCI工作主线程:bt_hc_callback。芯片上电、RF參数初始化、蓝牙地址名称相关设定;
(5)、创建:bt_hc_worker_thread蓝牙工作主线程,发送接收命令;
(6)、初始化蓝牙协议栈;
二、initNative函数的的实现
        这部分主要启动对应sock、协议栈初始化、启动btif_task,监听处理蓝牙接口相关的状态消息。实现流程例如以下所看到的。

 1、应用部分函数调用(从adatper開始)
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\ AdapterService.java

    public void onCreate() {
super.onCreate();
if (DBG) debugLog("onCreate");
mBinder = new AdapterServiceBinder(this);
mAdapterProperties = new AdapterProperties(this);
mAdapterStateMachine = AdapterState.make(this, mAdapterProperties);
mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties);
initNative();//调用initNative函数;
mNativeAvailable=true;
mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
//Load the name and address
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
}
private native boolean initNative();

2、JNI函数的实现,这部分跟其它JNI实现同样。
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp

static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void *) classInitNative},
{"initNative", "()Z", (void *) initNative},//Native函数实现
…………
}

packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
initNative函数的详细实现。通过bt_interface_t结构体,调用到C中的init函数实现。同一时候传入sBluetoothCallbacks回调函数结构体。这个函数结构体比較重要,底层的状态变化都是通过这个回调函数结构体中的函数实现。

static const bt_interface_t *sBluetoothInterface = NULL;
static bool initNative(JNIEnv* env, jobject obj) {
sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
if (sBluetoothInterface) {
int ret = sBluetoothInterface->init(&sBluetoothCallbacks);//调用到C的对应接口函数
if (ret != BT_STATUS_SUCCESS) {//假设出错,错误处理;
ALOGE("Error while setting the callbacks \n");
sBluetoothInterface = NULL;
return JNI_FALSE;
}
if ( (sBluetoothSocketInterface = (btsock_interface_t *)
sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
ALOGE("Error getting socket interface");
}
return JNI_TRUE;
}
return JNI_FALSE;
}

3、JNI调用C中函数实现
C语言实现了上层调用的函数。终于实现了JAVA调用C函数的动作。

这是android系统对kernel操作的详细步骤。

假设是刚開始学习的人,建议把这部分内容搞清楚,整个android系统对底层的操作都是通过这样的方法实现。
external\bluetooth\bluedroid\btif\src\bluetooth.c

static const bt_interface_t bluetoothInterface = {//蓝牙接口函数对应的函数
sizeof(bluetoothInterface),
init,//C函数中对init函数的实现;
enable,
disable,
cleanup,
get_adapter_properties,
get_adapter_property,
set_adapter_property,
get_remote_device_properties,
get_remote_device_property,
set_remote_device_property,
get_remote_service_record,
get_remote_services,
start_discovery,
cancel_discovery,
create_bond,
remove_bond,
cancel_bond,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send,
#if BLE_INCLUDED == TRUE
le_test_mode,
#else
NULL,
#endif
config_hci_snoop_log
};

4、蓝牙接口函数中Init函数实现过程
external\bluetooth\bluedroid\btif\src\bluetooth.c

static int init(bt_callbacks_t* callbacks )
{
ALOGI("init");
/* sanity check */
if (interface_ready() == TRUE)//检查接口函数是否准备好;
return BT_STATUS_DONE;
/* store reference to user callbacks */
bt_hal_cbacks = callbacks;//把对应的回调函数,保存。这个很重要,刚開始看代码是忽略这部分。我们单独一节解说这部分回调函数的实现和作用;
/* add checks for individual callbacks ? */
bt_utils_init();//工具集初始化,初始化一个相互排斥锁。
/* init btif */
btif_init_bluetooth();//初始化蓝牙接口bluetoothinterface
return BT_STATUS_SUCCESS;
}

5、蓝牙接口初始化详细实现,btif_init_bluetooth创建BTIF任务。准备蓝牙开启相关调度程序。
详细实现流程例如以下所看到的。我们以下对代码做详解。主要完毕了:
(1)、bt_config.xml文件里的蓝牙名称等处理;
(2)、GKI初始化,这部分后面单一节做详细分析。
(3)、BlueHCLibInterface初始化。实现power\preload\等函数,BlueDreoid  log等级设定;
(4)、BTIF_TASK线程创建。这个部分也比較重要。

external\bluetooth\bluedroid\btif\src\btif_core.c

bt_status_t btif_init_bluetooth()
{
UINT8 status;
btif_config_init();//创建sock线程。初始化初始化/data/misc/bluedroid/
bt_config.xml中相关数据。
bte_main_boot_entry();//(1)、BTE芯片协议栈入口API,蓝牙协议栈/芯片初始化,GKI init;
/* As part of the init, fetch the local BD ADDR */
memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));//取蓝牙地址写入相关文件。
btif_fetch_local_bdaddr(&btif_local_bd_addr);
/* start btif task */
status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));
//(2)、Creates BTIF task and prepares BT scheduler for startup 创建蓝牙任务接口,为开启做调度准备
if (status != GKI_SUCCESS)
return BT_STATUS_FAIL;
return BT_STATUS_SUCCESS;
}

(1)、BTE芯片协议栈入口API。蓝牙协议栈/芯片初始化。GKI init。
external\bluetooth\bluedroid\main\bte_main.c

void bte_main_boot_entry(void)
{
/* initialize OS */
GKI_init();//1)、GKI初始化。仅仅在初始化的时候调用一次。 bte_main_in_hw_init();//2)、初始化结构体static bt_hc_interface_t *bt_hc_if=NULL; bte_load_conf(BTE_STACK_CONF_FILE);//3)、初始化bluedroid调试信息等级; #if (BTTRC_INCLUDED == TRUE)//相关信息打印初始化。
/* Initialize trace feature */
BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM);
#endif
}

1)、GKI初始化。仅仅在初始化的时候调用一次
參考相互排斥锁:http://blog.csdn.net/kingmax26/article/details/5338065  。
external\bluetooth\bluedroid\gki\ulinux\gki_ulinux.c

void GKI_init(void)
{
pthread_mutexattr_t attr;
tGKI_OS *p_os; memset (&gki_cb, 0, sizeof (gki_cb)); gki_buffer_init();//1))、GKI 缓冲、缓冲池初始化;
gki_timers_init();//2))、GKI定时器初始化。
gki_cb.com.OSTicks = (UINT32) times(0); pthread_mutexattr_init(&attr);//3))、初始化pthread_mutexattr_t结构; #ifndef __CYGWIN__
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);//4))、设置相互排斥锁类型
#endif
p_os = &gki_cb.os;
pthread_mutex_init(&p_os->GKI_mutex, &attr);//5))、初始化相互排斥量GKI_mutex;
/* pthread_mutex_init(&GKI_sched_mutex, NULL); */
#if (GKI_DEBUG == TRUE)
pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);// 6))、初始化相互排斥量GKI_trace_mutex;
#endif
/* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
/* pthread_cond_init (&thread_delay_cond, NULL); */ /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
* this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
pthread_mutex_init(&p_os->gki_timer_mutex, NULL);7))、初始化相互排斥量gki_timer_mutex。
#ifndef NO_GKI_RUN_RETURN
pthread_cond_init(&p_os->gki_timer_cond, NULL);
#endif
}

2)、初始化结构体static bt_hc_interface_t *bt_hc_if=NULL;
bte_main_in_hw_init();
给bt_hc_if赋值:

static const bt_hc_interface_t bluetoothHCLibInterface = {
sizeof(bt_hc_interface_t),
init,//HCI LIB中init函数的实现;
set_power,
lpm,
preload,
postload,
transmit_buf,
set_rxflow,
logging,
cleanup
};

3)、初始化bluedroid调试信息等级
    bte_load_conf(BTE_STACK_CONF_FILE);
解析bt_stack.conf文件里的配置信息。
(2)、创建蓝牙任务接口。为开启做调度准备Creates BTIF task and prepares BT scheduler for startup  

  status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));

6、btif_task进程相关处理函数
external\bluetooth\bluedroid\btif\src\btif_dm.c
btif_task 等待接收bta_sys_sendmsg发送的对应的状态做对应处理。

static void btif_task(UINT32 params)
{
………………
for(;;)
{
/* wait for specified events */
event = GKI_wait(0xFFFF, 0);//GKI进程间通信后面单开一节介绍;
if (event == BT_EVT_TRIGGER_STACK_INIT)//协议栈初始化完毕;
…………
if (event == BT_EVT_HARDWARE_INIT_FAIL)//硬件初始化错误
…………
if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))//收到关闭信息。
…………
if(event & TASK_MBOX_1_EVT_MASK)
…………
}
}

Android BlueDroid(二):BlueDroid蓝牙开启过程init的更多相关文章

  1. Android BlueDroid(三):BlueDroid蓝牙开启过程enable

    关键词:bluedroid  enableNative BTIF_TASK  BTU_TASK bt_hc_work_thread set_power  preload GKI作者:xubin3417 ...

  2. ZT Android 4.2 BT系统之蓝牙关闭过程全跟踪

    Android 4.2 BT系统之蓝牙关闭过程全跟踪 分类: android 2013-08-03 00:34 2252人阅读 评论(10) 收藏 举报 代码位置:       frameworks/ ...

  3. 基于Android Classic Bluetooth的蓝牙聊天软件

    代码地址如下:http://www.demodashi.com/demo/12133.html BluetoothChat 基于Android Classic Bluetooth的蓝牙聊天软件,目前仅 ...

  4. Android世界第一个activity启动过程

    Android世界第一个activity启动过程 第一次使用Markdown,感觉不错. Android系统从按下开机键一直到launcher的出现,是一个如何的过程,中间都做出了什么操作呢.带着这些 ...

  5. Android应用程序内部启动Activity过程(startActivity)的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...

  6. 【转】android camera(二):摄像头工作原理、s5PV310 摄像头接口(CAMIF)

    关键词:android  camera CMM 模组 camera参数  CAMIF平台信息:内核:linux系统:android 平台:S5PV310(samsung exynos 4210) 作者 ...

  7. Android进阶(二十)AndroidAPP开发问题汇总(四)

    · Android进阶(二十)AndroidAPP开发问题汇总(四) android:layout_width和android:width的区别 基中的android:layout_width和and ...

  8. Android 6.0 Kotlin 蓝牙BLE扫描(改为指定时间没有发现新设备后停止扫描使用interface)

    package com.arci.myapplication import android.os.Bundleimport android.support.design.widget.Snackbar ...

  9. Android 6.0 Kotlin 蓝牙扫描

    package com.arci.myapplication import android.app.Activityimport android.os.Bundleimport android.sup ...

随机推荐

  1. 【codeforces 505D】Mr. Kitayuta's Technology

    [题目链接]:http://codeforces.com/problemset/problem/505/D [题意] 让你构造一张有向图; n个点; 以及所要求的m对联通关系(xi,yi) 即要求这张 ...

  2. 《Objective-C高级编程:iOS与OS X多线程和内存管理》读后感

    拿到这本书的第一感觉是非常薄,可是内容就如同序里面所说,这不是一本面向刚開始学习的人的书,比較有深度,对C/C++全然不熟悉的话非常多东西会看不明确. 尽管此书在技术点上仅仅谈到了ARC.Blocks ...

  3. 在IDEA中代码自动提示第一个字母大小写必须匹配的解决

    在IDEA中代码自动提示第一个字母大小写必须匹配的解决 学习了:http://blog.csdn.net/babys/article/details/41775715 setting>Edito ...

  4. DSAPI多功能组件编程应用-DS提示气泡

    首先下载DSAPI.dll.并在项目中引用. 该功能包括在DSAPI1.0.1.1及更高版本号,DLL请到本人资源里查找. Private Sub Button1_Click(sender As Ob ...

  5. 晋IT分享成长沙龙集锦

    第一期"晋IT"分享成长沙龙于2014年7月19日圆满结束.下面是相关内容整理和第二期预告. 各位伙伴认真的介绍自己,介绍自己的业务,分析自己眼下存在的问题,大家一起探讨,真诚出谋 ...

  6. Non-ASCII character &#39;\xe8&#39; in file xxx.py on line 8, but no encoding declared

    使用网上某个python程序.编译时报错: File "xxx.py", line 8         SyntaxError: Non-ASCII character '\xe8 ...

  7. hdu1276(士兵队列训练问题) java集合水过

    点击打开链接 有人说这题属于栈或者队列,个人认为说集合应该比較准确点. Problem Description 某部队进行新兵队列训练,将新兵从一開始按顺序依次编号.并排成一行横队,训练的规则例如以下 ...

  8. [JZOJ 5852] [NOIP2018提高组模拟9.6] 相交 解题报告 (倍增+LCA)

    题目链接: http://172.16.0.132/senior/#main/show/5852 题目: 题目大意: 多组询问,每次询问树上两条链是否相交 题解: 两条链相交并且仅当某一条链的两个端点 ...

  9. .net core 实现npoi导出

    Nuget 安装 NPOI 2.4.1 工作时间写着测试玩玩 public void ExportDataToExcel() { var workbook = new HSSFWorkbook(); ...

  10. PHP简介 变量 输出

    一.PHP概念 Hypertext Preprocessor 超文本预处理器,是一种开源脚本语言,语法吸收了C语言,Java,Perl的特点,用于web开发领域, PHP是将程序嵌入到Html文档中执 ...