Thursday, October 15, 2015

Bluedroid Stack

Directory Structure  of Bluedroid in Android:



BLuedroid Folder Structure description:

a) audio_a2dp_hw/  -->  A set of audio interfaces for external audio module to inject their implementation of these audio interface.

b) bta/  -->  It is Bluetooth application profile layer, The btif will call bta.

c) btif/  --> All the Bluetooth JNIs will direct;ly intract with btif

d) conf/ --> Configuration files for bluedroid ( Ex. debugging level, path of snoop log)

e) embdrv/ ---> SBC encoder/decoder

f) gki/  --> Defines a tiny embedded os based on pthread, It means generic kernel interface

g) HCI/ --> Implementation for HCI ( Ex. To compose the HCI command and emit it)

h) main/ --> The core initialization function for the Bluedroid( Initialze OS/HCI etc

i) osi/ --> OS interface for gki, ( Ex. Alarm/queue/list)

j) stack/ --> the bluetooth core stack, Between BTA and HCI

k) test/ --> A test tool for bluedroid ( framework and command line test tool)

l) udrv/ --> Implementation for UIPC ( IPC)

m) utils/ --> HElper function for bludroid

n) vnd/ --> Implementation for vendor features, ( Android's BLE proprietary features)


------------------------------STACK-------------------------------------



BT IF – Bluetooth Interface layer:
Implements the HAL interfaces that are invoked by the JNI calls
Maintains the callbacks registered by JNI
JNI callbacks are invoked by the IF layer based on the updates from the BTA/Stack
 
BTA – Bluetooth Application Layer:

Implements the Bluetooth profiles 
Maintains the profiles state machines
Handles events from the Stack and sends it back to IF layer

Bluedroid Stack:
Implements all protocols

HCI Layer:
HCI layer built as a shared library (libbt-hci) and acts as an interface between the transport layer and the stack. 
Support for the HCI H4 or the SMD transport – glues the serial driver calls for instance, with the upper layers

-----------> Bluedroid component---<
Structure is split into the following parts 
Application Specific Layer
ex. contains Bluetooth APK and android Services for Profiles. 
Bluetooth Middleware components
 ex. Bluetoothheadsetservice  and JNI System Object (libbluetooth_jni) 
Bluetooth Profile Interface (BTIF)  and stack adaptation layer (BTA =>  libbt-brcm_bta system object)
Core Stack (libbt-brcm_stack) and HCI Transport interface (libbt-hci)
Kernel drivers for transport layers like Serial, USB, SDIO 
Real Physical Hardware  (SOC)


Bluedroid stack, profiles and application run in a single user space process “com.android.bluetooth”
Bluetooth code runs in the context of 4 Tasks
BTIF_TASK
BTU_TASK
A2DP_MEDIA_TASK
GKI_TIMER_TASK
Communication between the above tasks is through MESSAGE_QUEUE
// Example:
void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK services, tBTA_DM_SEARCH_CBACK *p_cback)
208{...
 bta_sys_sendmsg(p_msg);
}
571void bta_sys_sendmsg(void *p_msg)
572{
573    // There is a race condition that occurs if the stack is shut down while
574    // there is a procedure in progress that can schedule a task via this
575    // message queue. This causes |btu_bta_msg_queue| to get cleaned up before
576    // it gets used here; hence we check for NULL before using it.
577    if (btu_bta_msg_queue)
578        fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
579}

API calls from JNI are transferred to BTIF_TASK context by posting messages
JNI/HAL callbacks run in the context of BTIF_TASK
BTIF Task intern will switch the context to BTU_TASK based on the request
Profile and Protocol implementation run in the context of BTU_TASK
Bluetooth transport driver has Rx thread to read data from UART/SMD (bt_hc_worker_thread)

Tuesday, October 13, 2015

Useful macro in Bluetooth

Device Type:
    * Bluetooth device type, Unknown
     */
    public static final int DEVICE_TYPE_UNKNOWN = 0;
    /**
     * Bluetooth device type, Classic - BR/EDR devices
    */
    public static final int DEVICE_TYPE_CLASSIC = 1;
    /**
     * Bluetooth device type, Low Energy - LE-only
    */
    public static final int DEVICE_TYPE_LE = 2;
    /**
     * Bluetooth device type, Dual Mode - BR/EDR/LE
    */
    public static final int DEVICE_TYPE_DUAL = 3;
/**
     * A bond attempt succeeded
     * @hide
     */
    public static final int BOND_SUCCESS = 0;
   /**
     * A bond attempt failed because pins did not match, or remote device did
     * not respond to pin request in time
     * @hide
     */
    public static final int UNBOND_REASON_AUTH_FAILED = 1;

    /**
     * A bond attempt failed because the other side explicitly rejected
     * bonding
     * @hide
     */
    public static final int UNBOND_REASON_AUTH_REJECTED = 2;

   /**
     * A bond attempt failed because we canceled the bonding process
     * @hide
     */
    public static final int UNBOND_REASON_AUTH_CANCELED = 3;

    /**
     * A bond attempt failed because we could not contact the remote device
     * @hide
     */
    public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;

    /**
     * A bond attempt failed because a discovery is in progress
     * @hide
     */
    public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;

    /**
     * A bond attempt failed because of authentication timeout
     * @hide
    */
    public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;

    /**
     * A bond attempt failed because of repeated attempts
     * @hide
     */
    public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;

    /**
     * A bond attempt failed because we received an Authentication Cancel
     * by remote end
     * @hide
     */
    public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;

/**
479     * The user will be prompted to enter a pin or
480     * an app will enter a pin for user.
481     */
482    public static final int PAIRING_VARIANT_PIN = 0;

    public static final int PAIRING_VARIANT_PASSKEY = 1;
489
490    /**
491     * The user will be prompted to confirm the passkey displayed on the screen or
492     * an app will confirm the passkey for the user.
493     */
494    public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
495
496    /**
497     * The user will be prompted to accept or deny the incoming pairing request
498     * @hide
499     */
500    public static final int PAIRING_VARIANT_CONSENT = 3;
501
502    /**
503     * The user will be prompted to enter the passkey displayed on remote device
504     * This is used for Bluetooth 2.1 pairing.
505     * @hide
506     */
507    public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
508
509    /**
510     * The user will be prompted to enter the PIN displayed on remote device.
511     * This is used for Bluetooth 2.0 pairing.
512     * @hide
513     */
514    public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;

Inquiry in Bluetooth after turn on BT

BT inquiry:

We are going to start form the scanning or inquiring the device, once the BT is turned ON.


/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java:
This function is get called from the top right cornor where we are doing the refresh.
public boolean onOptionsItemSelected(MenuItem item) --> startScanning();

// this will get called when BT is totaly turned ON.
 public void onBluetoothStateChanged(int bluetoothState)--> startScanning();

// This function will get called when any device is getting bonded once the bonding complete then below content will
get updated.
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) --> startScanning();

 /packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java
startScanning()--> mAdapter.startDiscovery()

/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
 : Start the remote device discovery process. The discovery process usually involves an inquiry scan of about 12 seconds, followed by a page
scan of each new device to retrieve its Bluetooth name.
It is asynchronous call, it will return immediately. Register for #ACTION_DISCOVERY_STARTED and ACTION_DISCOVERY_FINISHED intents to determin exactly when the disocvery starts and completes.
Register for BluetoothDevice#ACTION_FOUND to be notified as remote bluetooth devices are found.

NOTE: Discovery is not managed by th eActivity, but is run as a system service, so an application should always call BluetoothAdapter#cancelDiscovery().
Device discovery will only find remote device that are currently discoverable.
 mService.startDiscovery();

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

startDiscovery() --> startDiscoveryNative();

 /packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp

startDiscoveryNative(JNIEnv* env, jobject obj) --> start_discovery();

/hardware/libhardware/include/hardware/bluetooth.h[HAL LAYER]

int (*start_discovery)(void);

/external/bluetooth/bluedroid/btif/src/bluetooth.c [STACK LAYER NOW ONWARDS]

static int start_discovery(void)--> btif_dm_start_discovery();

/external/bluetooth/bluedroid/btif/src/btif_dm.c

btif_dm_start_discovery-->   BTA_DmSearch(&inq_params, services, bte_search_devices_evt);

/external/bluetooth/bluedroid/bta/dm/bta_dm_api.c
// This function searches for peer bluetooth devices.It performs an inquiry and gets the rremote name for devices.

BTA_DmSearch()


/external/bluetooth/bluedroid/bta/dm/bta_dm_act.c
//Start an inquiry
bta_dm_search_start() --> BTM_StartInquiry()

/external/bluetooth/bluedroid/stack/btm/btm_inq.c
// for start the inquiry:
BTM_StartInquiry(), p_results_cb  -- is the pointer to callback with inquiry result.

NOTE: Inquiry having 3 second timeout waiting for response.

------------------- after inquiry complete sending data to application side------------------
/external/bluetooth/bluedroid/btif/src/btif_dm.c
//Switches context from BTE to BTIF for DM search events
bte_search_devices_evt()---> btif_dm_search_devices_evt()

/external/bluetooth/bluedroid/btif/src/btif_dm.c
btif_dm_search_devices_evt()-->
  HAL_CBACK(bt_hal_cbacks, device_found_cb,num_properties, properties);

  /hardware/libhardware/include/hardware/bluetooth.h[HAL layer]
device_found_callback device_found_cb;

/packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
device_found_callback () -->devicePropertyChangedCallback()

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/JniCallbacks.java

devicePropertyChangedCallback () -->  mRemoteDevices.devicePropertyChangedCallback(address, types, val);


/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.java

devicePropertyChangedCallback() -->

Bonding in Bluetooth ( Pairing )


Bonding in BT:

Once the device is get displayed on the device, after the inquiry then we will proceed
for the bonding. Then below function will get called when the user start then bonding procedure from device.


/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
//
private void pair() ---> mCachedDevice.startPairing()

/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
mDevice.createBond()

/frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
// Start the bonding (pairing) process with the remote device. It is asynchronous call, it will return immediately.
Register for #ACTION_BOND_STATE_CHANGED intentes to be notified when the bonding process
completes, and its result.
public boolean createBond()

/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
// It will send event to BondStateMachine.CREATE_BOND
public boolean createBond(BluetoothDevice device, int transport)

1. /packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
[createBond()]--> mAdapterService.createBondNative(addr, transport):from here the call will go to the native. to create the bond.--> createBondNative();
2. same file : BONDING_STATE_CHANGE--> go for weather the current state is bonded, none, bonding.

 /packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
sBluetoothInterface->create_bond()

3. /packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterProperties.java
onBondStateChanged()->  This function sahll be invoked from BondStateMachine whenever th bond sate changes.

4. /hardware/libhardware/include/hardware/bluetooth.h [HAL layer]
int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport);

5. /system/bt/btif/src/bluetooth.c
static int create_bond(const bt_bdaddr_t *bd_addr, int transport)

6. /system/bt/btif/src/btif_dm.c
// It will post event #BTIF_DM_CB_CREATE_BOND.
bt_status_t btif_dm_create_bond(const bt_bdaddr_t *bd_addr, int transport)
// and the call will come to here
 btif_dm_cb_create_bond(&create_bond_cb->bdaddr, create_bond_cb->transport);
BTA_DmBondByTransport()
btif_hh_connect(bd_addr); // only for the HID device other wise for BR_EDR above call.

NOTE:
1. When the call will go to [btif_dm_cb_create_bond], it will call [bond_state_changed] and then
call will go to the application layer i.e bond state is changed not , from "bond_none" to bonding.


7. /system/bt/bta/dm/bta_dm_api.c
// It will initiates a bonding procedure with a peer device. and post the event: BTA_DM_API_BOND_EVT
BTA_DmBondByTransport() or BTA_DmBond()

8. /system/bt/bta/dm/bta_dm_act.c
void bta_dm_bond (tBTA_DM_MSG *p_data)

9. /system/bt/stack/btm/btm_sec.c[this file contain regarding securitypairing SSP adn link key]
// It perform bonding with peer device. If the connection is already up, but not secure, pairing
is attempted. If already paired BTM_SUCCESS is returned.
BTM_SecBondByTransport()--> btm_sec_bond_by_transport()
btm_sec_bond_by_transport --->This is bond function that will start either SSP or SMP
//This function is cllled to perform bonding with peer device. If connection is already up, but not secure,
pairing is attempted. If already paired BTM_SUCCESS is returned.
BTM_SecBond() --> btm_sec_bond_by_transport

btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
// IF the device matches with stored paring address reset the paring state to idle.
btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE);


10. /external/bluetooth/bluedroid/stack/btm/btm_sec.c

// This is bond function that will start either SSP or SMP.
btm_sec_bond_by_transport()

Bluetooth Turning ON

Once Phone Bootup is complete, then BT initilization will be go...com.android.bluetooth and com.btservice.AdapterService will get started.

1. Device supporting profile is get added to config.(like, a2dp, hid, pan,map,etc)
2. Register IBluetoothManagerCallback.
3. Init Bluedroid, Load bt_stack.conf and Start BTIF.
4. BluetoothServiceConnection
5. getAdapterPropertiesNative --> get_adapter_properties(at the time of init)
6. Adapterpropertychangedcallback with Set_adapter_property: address, Name.

*********************************************************************
User action: Enable BT(Tuning ON):
once the user turn on BT, the state will go from 10 to 11(turning on )
then it will start all the profile services (hidservice, a2dpservice...),then call will go for the enable BT to JNI-->HAL-->BTIF-->BTE-->HCI--> vendor specific--> UART.
btif will wait for th trigger to init chip and stack. This trigger will be received by btu_task once the UART is opened and ready.


Call flow of BT ON from the APP side:

1. /packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
call-->  mLocalAdapter.setBluetoothEnabled(isChecked);
2. /packages/apps/Settings/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java
call--> mAdapter.enable();
3.[BluetoothAdapter.java] return mManagerService.enable();
NOTE: 1. Show toast message : BT is not allowed in Airplane Mode.
4. [LocalBluetoothAdapter.java]private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
6. Once BT came to TURN ON then it will initilize or update the local profile objects.(a2dp or handsfree profile)
   call -->  updateLocalProfiles();
7. notifyAdapterStateChange()[AdapterState.java]--> This is responsible for the state change managment.

Qualcomm Short Term

  113 is the SL. 1st Target by mid July.

Total Pageviews