allwinner4.0.4:
SystemServer.java:
if (SystemProperties.get("ro.kernel.qemu").equals("1") || SystemProperties.get("ro.bluetooth.disable").equals("1")) { Slog.i(TAG, "No Bluetooh Service (emulator)"); } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { Slog.i(TAG, "No Bluetooth Service (factory test)"); } else { Slog.i(TAG, "Bluetooth Service"); bluetooth = new BluetoothService(context); ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth); bluetooth.initAfterRegistration(); bluetoothA2dp = new BluetoothA2dpService(context, bluetooth); ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE, bluetoothA2dp); bluetooth.initAfterA2dpRegistration(); int airplaneModeOn = Settings.System.getInt(mContentResolver, Settings.System.AIRPLANE_MODE_ON, 0); int bluetoothOn = Settings.Secure.getInt(mContentResolver, Settings.Secure.BLUETOOTH_ON, 0); if (airplaneModeOn == 0 && bluetoothOn != 0) { bluetooth.enable(); } }
public synchronized boolean enable(boolean saveSetting) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); // Airplane mode can prevent Bluetooth radio from being turned on. if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) { return false; } mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON, saveSetting); return true; }
初始化时候状态是在PowerOff,所以进入PowerOff中:
private class PowerOff extends State { @Override public void enter() { if (DBG) log("Enter PowerOff: " + getCurrentMessage().what); } @Override public boolean processMessage(Message message) { log("PowerOff process message: " + message.what); boolean retValue = HANDLED; switch(message.what) { case USER_TURN_ON: // starts turning on BT module, broadcast this out broadcastState(BluetoothAdapter.STATE_TURNING_ON); transitionTo(mWarmUp); if (prepareBluetooth()) { // this is user request, save the setting if ((Boolean) message.obj) { persistSwitchSetting(true); } // We will continue turn the BT on all the way to the BluetoothOn state deferMessage(obtainMessage(TURN_ON_CONTINUE)); } else { Log.e(TAG, "failed to prepare bluetooth, abort turning on"); transitionTo(mPowerOff); broadcastState(BluetoothAdapter.STATE_OFF); } break; ..................................... }
可以看到,蓝牙状态机接收到USER_TURN_ON后,首先广播蓝牙适配器处于STATE_TURNING_ON状态,蓝牙适配器状态有四种:
state_off(10),state_turning_on(11),state_on(12),state_turning_off(14)
接下来看prepareBluetooth()函数:
private boolean prepareBluetooth() { if (mBluetoothService.enableNative() != 0) { return false; } // try to start event loop, give 2 attempts int retryCount = 2; boolean eventLoopStarted = false; while ((retryCount-- > 0) && !eventLoopStarted) { mEventLoop.start(); // it may take a moment for the other thread to do its // thing. Check periodically for a while. int pollCount = 5; while ((pollCount-- > 0) && !eventLoopStarted) { if (mEventLoop.isEventLoopRunning()) { eventLoopStarted = true; break; } try { Thread.sleep(100); } catch (InterruptedException e) { log("prepareBluetooth sleep interrupted: " + pollCount); break; } } } if (!eventLoopStarted) { mBluetoothService.disableNative(); return false; } ............................. }
static jint enableNative(JNIEnv *env, jobject object) { #ifdef HAVE_BLUETOOTH LOGV("%s", __FUNCTION__); return bt_enable(); #endif return -1; }
int bt_enable() { LOGV(__FUNCTION__); int ret = -1; int hci_sock = -1; int attempt; LOGI("bt_enable()"); #ifndef BOARD_HAVE_BLUETOOTH_CSR //if (set_bluetooth_power(1) < 0) goto out; #else LOGI("Starting bccmd command"); if (property_set("ctl.start", "bccmd") < 0) { LOGE("Fail to bccmd"); goto out; } sleep(5); #endif #if defined(SW_BOARD_HAVE_BLUETOOTH_RTK) usleep(1000000); // 1 seconds #endif LOGI("Starting hciattach daemon"); if (property_set("ctl.start", "hciattach") < 0) { LOGE("Failed to start hciattach"); #ifndef BOARD_HAVE_BLUETOOTH_CSR //set_bluetooth_power(0); #endif goto out; } // Try for 10 seconds, this can only succeed once hciattach has sent the // firmware and then turned on hci device via HCIUARTSETPROTO ioctl for (attempt = 1000; attempt > 0; attempt--) { hci_sock = create_hci_sock(); if (hci_sock < 0) goto out; ret = ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID); LOGI("bt_enable: ret: %d, errno: %d", ret, errno); if (!ret) { break; } else if (errno == EALREADY) { LOGW("Bluetoothd already started, unexpectedly!"); break; } close(hci_sock); usleep(100000); // 100 ms retry delay } if (attempt == 0) { LOGE("%s: Timeout waiting for HCI device to come up, error- %d, ", __FUNCTION__, ret); if (property_set("ctl.stop", "hciattach") < 0) { LOGE("Error stopping hciattach"); } #ifndef BOARD_HAVE_BLUETOOTH_CSR //set_bluetooth_power(0); #endif goto out; } LOGI("Starting bluetoothd deamon"); if (property_set("ctl.start", "bluetoothd") < 0) { LOGE("Failed to start bluetoothd"); #ifndef BOARD_HAVE_BLUETOOTH_CSR //set_bluetooth_power(0); #endif goto out; } #ifdef BOARD_HAVE_BLUETOOTH_CSR if (property_set("ctl.start", BTFILTER_NAME) < 0) { LOGE("Failed to start abtfilt"); goto out; } usleep(1000); #endif ret = 0; out: if (hci_sock >= 0) close(hci_sock); return ret; }
接着property_set("ctl.start", "hciattach")启动HCI服务,然后create_hci_sock来创建socket,这样就可以和HCI服务通讯了
接下来ioctl,参数是HCIDEVUP,就进入了驱动linux-3.0/net/bluetooth/hci_sock.c中:
static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { ................................. case HCIDEVUP: if (!capable(CAP_NET_ADMIN)) return -EACCES; return hci_dev_open(arg); ..................................... }调用hci_dev_open(arg), 这个函数的效果就好比我们在终端下面使用蓝牙调试工具hciconfig
int hci_dev_open(__u16 dev) { struct hci_dev *hdev; int ret = 0; hdev = hci_dev_get(dev); if (!hdev) return -ENODEV; ............................. if (hdev->open(hdev)) { ret = -EIO; goto done; } ..................................... }这里得到一个hci_dev设备,然后调用他的open,其实就是我们注册蓝牙驱动时候的回调函数,会调用我们蓝牙驱动的open
mBluetoothService在enableNative()函数主要功能就是通过一系列代码来打开蓝牙设备。如果设备驱动代码没有问题的话,我们enableNative()返回的将会是true。在实际调试蓝牙设备时候,我们可以通过在linux或者android的终端下面使用自带的工具命令(hciconfig),执行:
# hciconfig –a如果驱动能够和设备绑定的话,我们就会看到蓝牙设备的一些比较重要信息,如:蓝牙的物理地址,总线类型,协议类型等/* package */ void start() { if (!isEventLoopRunningNative()) { if (DBG) log("Starting Event Loop thread"); startEventLoopNative(); } }
这里的函数很长,主要是创建socket,创建一个专门读取数据的线程,将bluz挂在dbus上,最后一轮询的方式读取数据,有数据来了的话根据数据的类型做相应的处理
分析完prepareBluetooth,如果没有问题,就用persistSwitchSetting将状态Settings.Secure.BLUETOOTH_ON写到数据库中保存起来
状态机在前面transitionTo(mWarmUp),已经切换到了mWarmUp模式,并且发送了deferMessage(obtainMessage(TURN_ON_CONTINUE)),所以进入WarmUp状态:
未完,参考http://www.cnblogs.com/chenbin7/archive/2012/09/05/2670652.html