当前位置:   article > 正文

Bluedroid: 蓝牙协议栈源码剖析_btu和bta

btu和bta

https://www.cnblogs.com/blogs-of-lxl/p/7010061.html

一、 基础知识介绍

1.缩略语

BTIF: Bluetooth Interface 

BTU : Bluetooth Upper Layer 

BTM: Bluetooth Manager 

BTE: Bluetooth embedded system 

BTA :Blueetooth application layer 

CO: call out\CI: call in 

HF : Handsfree Profile 

HH: HID Host Profile 

HL: Health Device Profile

V:audio\vidio 

ag: audio gateway

r: audio/video registration 

gattc: GATT client 

BLE: Bluetooth Low Energy

整个bluedroid可以分为两大模块:BTIF,BTE

BTIF:提供bluedroid对外的接口

BTE:bluedroid的内部处理,又细分为BTA,BTU,BTM和HCI

BTA:bluedroid中各profile的逻辑实现和处理

BTU:承接BTA与HCI

BTM:蓝牙配对与链路管理

HCI:读取或写入数据到蓝牙hw

二、代码分析(写hidraw节点数据流程):

1.初始化:

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

复制代码

  1. static const bt_interface_t bluetoothInterface = {
  2. sizeof(bluetoothInterface),
  3. init,
  4. enable,
  5. disable,
  6. cleanup,
  7. get_adapter_properties,
  8. get_adapter_property,
  9. set_adapter_property,
  10. get_remote_device_properties,
  11. get_remote_device_property,
  12. set_remote_device_property,
  13. get_remote_service_record,
  14. get_remote_services,
  15. start_discovery,
  16. cancel_discovery,
  17. create_bond,
  18. remove_bond,
  19. cancel_bond,
  20. get_connection_state,
  21. pin_reply,
  22. ssp_reply,
  23. get_profile_interface, //根据profile获得对应的接口
  24. dut_mode_configure,
  25. dut_mode_send,
  26. #if BLE_INCLUDED == TRUE
  27. le_test_mode,
  28. #else
  29. NULL,
  30. #endif
  31. config_hci_snoop_log,
  32. set_os_callouts,
  33. read_energy_info,
  34. };
  35. ......
  36. if (is_profile(profile_id, BT_PROFILE_HIDHOST_ID))
  37.         return btif_hh_get_interface(); //获得HID Host Profile 

复制代码

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

复制代码

  1. static const bthh_interface_t bthhInterface = {
  2. sizeof(bthhInterface),
  3. init,
  4. connect,
  5. disconnect,
  6. virtual_unplug,
  7. set_info,
  8. get_protocol,
  9. set_protocol,
  10. // get_idle_time,
  11. // set_idle_time,
  12. get_report,
  13. set_report,
  14. send_data,
  15. cleanup,
  16. };

复制代码

init函数里注册传入的回调函数:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_hh_init
  4. **
  5. ** Description initializes the hh interface
  6. **
  7. ** Returns bt_status_t
  8. **
  9. *******************************************************************************/
  10. static bt_status_t init( bthh_callbacks_t* callbacks )
  11. {
  12. UINT32 i;
  13. BTIF_TRACE_EVENT("%s", __FUNCTION__);
  14. bt_hh_callbacks = callbacks;
  15. memset(&btif_hh_cb, 0, sizeof(btif_hh_cb));
  16. for (i = 0; i < BTIF_HH_MAX_HID; i++){
  17. btif_hh_cb.devices[i].dev_status = BTHH_CONN_STATE_UNKNOWN;
  18. }
  19. /* Invoke the enable service API to the core to set the appropriate service_id */
  20. btif_enable_service(BTA_HID_SERVICE_ID);
  21. return BT_STATUS_SUCCESS;
  22. }

复制代码

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

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_enable_service
  4. **
  5. ** Description Enables the service 'service_ID' to the service_mask.
  6. ** Upon BT enable, BTIF core shall invoke the BTA APIs to
  7. ** enable the profiles
  8. **
  9. ** Returns bt_status_t
  10. **
  11. *******************************************************************************/
  12. bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id)
  13. {
  14. tBTA_SERVICE_ID *p_id = &service_id;
  15. /* If BT is enabled, we need to switch to BTIF context and trigger the
  16. * enable for that profile
  17. *
  18. * Otherwise, we just set the flag. On BT_Enable, the DM will trigger
  19. * enable for the profiles that have been enabled */
  20. btif_enabled_services |= (1 << service_id);
  21. BTIF_TRACE_DEBUG("%s: current services:0x%x", __FUNCTION__, btif_enabled_services);
  22. if (btif_is_enabled())
  23. { //注册回调,发送消息
  24. btif_transfer_context(btif_dm_execute_service_request,
  25. BTIF_DM_ENABLE_SERVICE,
  26. (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL);
  27. }
  28. return BT_STATUS_SUCCESS;
  29. }

复制代码

 

2.创建线程和准备启动调度:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_init_bluetooth
  4. **
  5. ** Description Creates BTIF task and prepares BT scheduler for startup
  6. **
  7. ** Returns bt_status_t
  8. **
  9. *******************************************************************************/
  10. bt_status_t btif_init_bluetooth()
  11. {
  12. UINT8 status;
  13. btif_config_init();
  14. bte_main_boot_entry();
  15. /* As part of the init, fetch the local BD ADDR */
  16. memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));
  17. btif_fetch_local_bdaddr(&btif_local_bd_addr);
  18. /* start btif task */
  19. status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
  20. (UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
  21. sizeof(btif_task_stack));
  22. if (status != GKI_SUCCESS)
  23. return BT_STATUS_FAIL;
  24. return BT_STATUS_SUCCESS;
  25. }

复制代码

处理线程函数:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_task
  4. **
  5. ** Description BTIF task handler managing all messages being passed
  6. ** Bluetooth HAL and BTA.
  7. **
  8. ** Returns void
  9. **
  10. *******************************************************************************/
  11. static void btif_task(UINT32 params)
  12. {
  13. UINT16 event;
  14. BT_HDR *p_msg;
  15. UNUSED(params);
  16. BTIF_TRACE_DEBUG("btif task starting");
  17. btif_associate_evt();
  18. for(;;)
  19. {
  20. /* wait for specified events */
  21. event = GKI_wait(0xFFFF, 0);
  22. /*
  23. * Wait for the trigger to init chip and stack. This trigger will
  24. * be received by btu_task once the UART is opened and ready
  25. */
  26. if (event == BT_EVT_TRIGGER_STACK_INIT)
  27. {
  28. BTIF_TRACE_DEBUG("btif_task: received trigger stack init event");
  29. #if (BLE_INCLUDED == TRUE)
  30. btif_dm_load_ble_local_keys();
  31. #endif
  32. BTA_EnableBluetooth(bte_dm_evt);
  33. }
  34. /*
  35. * Failed to initialize controller hardware, reset state and bring
  36. * down all threads
  37. */
  38. if (event == BT_EVT_HARDWARE_INIT_FAIL)
  39. {
  40. BTIF_TRACE_DEBUG("btif_task: hardware init failed");
  41. bte_main_disable();
  42. btif_queue_release();
  43. GKI_task_self_cleanup(BTIF_TASK);
  44. bte_main_shutdown();
  45. btif_dut_mode = 0;
  46. btif_core_state = BTIF_CORE_STATE_DISABLED;
  47. HAL_CBACK(bt_hal_cbacks,adapter_state_changed_cb,BT_STATE_OFF);
  48. break;
  49. }
  50. if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
  51. break;
  52. if(event & TASK_MBOX_1_EVT_MASK)
  53. {
  54. while((p_msg = GKI_read_mbox(BTU_BTIF_MBOX)) != NULL) //读取消息
  55. {
  56. BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event);
  57. switch (p_msg->event)
  58. {
  59. case BT_EVT_CONTEXT_SWITCH_EVT:
  60. btif_context_switched(p_msg); //传递消息给注册的回调函数
  61. break;
  62. default:
  63. BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);
  64. break;
  65. }
  66. GKI_freebuf(p_msg);
  67. }
  68. }
  69. }
  70. btif_disassociate_evt();
  71. BTIF_TRACE_DEBUG("btif task exiting");
  72. }

复制代码

之前先开启了蓝牙服务:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function BTA_EnableBluetooth
  4. **
  5. ** Description Enables bluetooth service. This function must be
  6. ** called before any other functions in the BTA API are called.
  7. **
  8. **
  9. ** Returns tBTA_STATUS
  10. **
  11. *******************************************************************************/
  12. tBTA_STATUS BTA_EnableBluetooth(tBTA_DM_SEC_CBACK *p_cback)
  13. {
  14. tBTA_DM_API_ENABLE *p_msg;
  15. /* Bluetooth disabling is in progress */
  16. if (bta_dm_cb.disabling)
  17. return BTA_FAILURE;
  18. memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
  19. bta_sys_register (BTA_ID_DM, &bta_dm_reg );
  20. bta_sys_register (BTA_ID_DM_SEARCH, &bta_dm_search_reg );
  21. /* if UUID list is not provided as static data */
  22. bta_sys_eir_register(bta_dm_eir_update_uuid);
  23. if ((p_msg = (tBTA_DM_API_ENABLE *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE))) != NULL)
  24. {
  25. p_msg->hdr.event = BTA_DM_API_ENABLE_EVT;
  26. p_msg->p_sec_cback = p_cback;
  27. bta_sys_sendmsg(p_msg);
  28. return BTA_SUCCESS;
  29. }
  30. return BTA_FAILURE;
  31. }

复制代码

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

根据消息请求对应服务:

复制代码

  1. void btif_dm_execute_service_request(UINT16 event, char *p_param)
  2. {
  3. BOOLEAN b_enable = FALSE;
  4. bt_status_t status;
  5. if (event == BTIF_DM_ENABLE_SERVICE)
  6. {
  7. b_enable = TRUE;
  8. }
  9. status = btif_in_execute_service_request(*((tBTA_SERVICE_ID*)p_param), b_enable); //执行服务请求
  10. if (status == BT_STATUS_SUCCESS)
  11. {
  12. bt_property_t property;
  13. bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
  14. /* Now send the UUID_PROPERTY_CHANGED event to the upper layer */
  15. BTIF_STORAGE_FILL_PROPERTY(&property, BT_PROPERTY_UUIDS,
  16. sizeof(local_uuids), local_uuids);
  17. btif_storage_get_adapter_property(&property);
  18. HAL_CBACK(bt_hal_cbacks, adapter_properties_cb,
  19. BT_STATUS_SUCCESS, 1, &property);
  20. }
  21. return;
  22. }

复制代码

执行A2DP/HID/HFP等服务

复制代码

  1. bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
  2. BOOLEAN b_enable)
  3. {
  4. /* Check the service_ID and invoke the profile's BT state changed API */
  5. switch (service_id)
  6. {
  7. case BTA_HFP_SERVICE_ID:
  8. case BTA_HSP_SERVICE_ID:
  9. {
  10. btif_hf_execute_service(b_enable);
  11. }break;
  12. case BTA_A2DP_SERVICE_ID:
  13. {
  14. btif_av_execute_service(b_enable);
  15. }break;
  16. case BTA_HID_SERVICE_ID:
  17. {
  18. btif_hh_execute_service(b_enable);
  19. }break;
  20. case BTA_HFP_HS_SERVICE_ID:
  21. {
  22. btif_hf_client_execute_service(b_enable);
  23. }break;
  24. case BTA_MAP_SERVICE_ID:
  25. {
  26. btif_mce_execute_service(b_enable);
  27. }break;
  28. default:
  29. BTIF_TRACE_ERROR("%s: Unknown service being enabled", __FUNCTION__);
  30. return BT_STATUS_FAIL;
  31. }
  32. return BT_STATUS_SUCCESS;
  33. }

复制代码

 

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

启动/关闭 HID服务

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_hh_execute_service
  4. **
  5. ** Description Initializes/Shuts down the service
  6. **
  7. ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
  8. **
  9. *******************************************************************************/
  10. bt_status_t btif_hh_execute_service(BOOLEAN b_enable)
  11. {
  12. if (b_enable)
  13. {
  14. /* Enable and register with BTA-HH */
  15. BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt);
  16. }
  17. else {
  18. /* Disable HH */
  19. BTA_HhDisable();
  20. }
  21. return BT_STATUS_SUCCESS;
  22. }

复制代码

external\bluetooth\bluedroid\bta\hh\bta_hh_api.c

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function BTA_HhEnable
  4. **
  5. ** Description Enable the HID host. This function must be called before
  6. ** any other functions in the HID host API are called. When the
  7. ** enable operation is complete the callback function will be
  8. ** called with BTA_HH_ENABLE_EVT.
  9. **
  10. **
  11. ** Returns void
  12. **
  13. *******************************************************************************/
  14. void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
  15. {
  16. tBTA_HH_API_ENABLE *p_buf;
  17. /* register with BTA system manager */
  18. bta_sys_register(BTA_ID_HH, &bta_hh_reg); //注册主处理函数
  19. APPL_TRACE_ERROR("Calling BTA_HhEnable");
  20. p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));
  21. if (p_buf != NULL)
  22. {
  23. memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
  24. p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
  25. p_buf->p_cback = p_cback;
  26. p_buf->sec_mask = sec_mask;
  27. bta_sys_sendmsg(p_buf);
  28. }
  29. }

复制代码


external\bluetooth\bluedroid\btif\co\bta_hh_co.c

HID Host Profile 部分初始化,创建HID事件监听线程:btif_hh_poll_event_thread

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_co_open
  4. **
  5. ** Description When connection is opened, this call-out function is executed
  6. ** by HH to do platform specific initialization.
  7. **
  8. ** Returns void.
  9. *******************************************************************************/
  10. void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_mask,
  11. UINT8 app_id)
  12. {
  13. UINT32 i;
  14. btif_hh_device_t *p_dev = NULL;
  15. if (dev_handle == BTA_HH_INVALID_HANDLE) {
  16. APPL_TRACE_WARNING("%s: Oops, dev_handle (%d) is invalid...", __FUNCTION__, dev_handle);
  17. return;
  18. }
  19. for (i = 0; i < BTIF_HH_MAX_HID; i++) {
  20. p_dev = &btif_hh_cb.devices[i];
  21. if (p_dev->dev_status != BTHH_CONN_STATE_UNKNOWN && p_dev->dev_handle == dev_handle) {
  22. // We found a device with the same handle. Must be a device reconnected.
  23. APPL_TRACE_WARNING("%s: Found an existing device with the same handle "
  24. "dev_status = %d",__FUNCTION__,
  25. p_dev->dev_status);
  26. APPL_TRACE_WARNING("%s: bd_addr = [%02X:%02X:%02X:%02X:%02X:]", __FUNCTION__,
  27. p_dev->bd_addr.address[0], p_dev->bd_addr.address[1], p_dev->bd_addr.address[2],
  28. p_dev->bd_addr.address[3], p_dev->bd_addr.address[4]);
  29. APPL_TRACE_WARNING("%s: attr_mask = 0x%04x, sub_class = 0x%02x, app_id = %d",
  30. __FUNCTION__, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id);
  31. if(p_dev->fd<0) {
  32. p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
  33. if (p_dev->fd < 0){
  34. APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
  35. __FUNCTION__,strerror(errno));
  36. }else
  37. APPL_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
  38. }
  39. p_dev->hh_keep_polling = 1;
  40. p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
  41. break;
  42. }
  43. p_dev = NULL;
  44. }
  45. if (p_dev == NULL) {
  46. // Did not find a device reconnection case. Find an empty slot now.
  47. for (i = 0; i < BTIF_HH_MAX_HID; i++) {
  48. if (btif_hh_cb.devices[i].dev_status == BTHH_CONN_STATE_UNKNOWN) {
  49. p_dev = &btif_hh_cb.devices[i];
  50. p_dev->dev_handle = dev_handle;
  51. p_dev->attr_mask = attr_mask;
  52. p_dev->sub_class = sub_class;
  53. p_dev->app_id = app_id;
  54. p_dev->local_vup = FALSE;
  55. btif_hh_cb.device_num++;
  56. // This is a new device,open the uhid driver now.
  57. p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
  58. if (p_dev->fd < 0){
  59. APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
  60. __FUNCTION__,strerror(errno));
  61. }else{
  62. APPL_TRACE_DEBUG("%s: uhid fd = %d", __FUNCTION__, p_dev->fd);
  63. p_dev->hh_keep_polling = 1;
  64. p_dev->hh_poll_thread_id = create_thread(btif_hh_poll_event_thread, p_dev);
  65. }
  66. break;
  67. }
  68. }
  69. }
  70. if (p_dev == NULL) {
  71. APPL_TRACE_ERROR("%s: Error: too many HID devices are connected", __FUNCTION__);
  72. return;
  73. }
  74. p_dev->dev_status = BTHH_CONN_STATE_CONNECTED;
  75. APPL_TRACE_DEBUG("%s: Return device status %d", __FUNCTION__, p_dev->dev_status);
  76. }

复制代码


poll监听HID驱动的事件:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_hh_poll_event_thread
  4. **
  5. ** Description the polling thread which polls for event from UHID driver
  6. **
  7. ** Returns void
  8. **
  9. *******************************************************************************/
  10. static void *btif_hh_poll_event_thread(void *arg)
  11. {
  12. btif_hh_device_t *p_dev = arg;
  13. APPL_TRACE_DEBUG("%s: Thread created fd = %d", __FUNCTION__, p_dev->fd);
  14. struct pollfd pfds[1];
  15. int ret;
  16. pfds[0].fd = p_dev->fd;
  17. pfds[0].events = POLLIN;
  18. while(p_dev->hh_keep_polling){
  19. ret = poll(pfds, 1, 50);
  20. if (ret < 0) {
  21. APPL_TRACE_ERROR("%s: Cannot poll for fds: %s\n", __FUNCTION__, strerror(errno));
  22. break;
  23. }
  24. if (pfds[0].revents & POLLIN) {
  25. APPL_TRACE_DEBUG("btif_hh_poll_event_thread: POLLIN");
  26. ret = uhid_event(p_dev);
  27. if (ret){
  28. break;
  29. }
  30. }
  31. }
  32. p_dev->hh_poll_thread_id = -1;
  33. return 0;
  34. }

复制代码

 解析HID驱动的事件:

复制代码

  1. /* Internal function to parse the events received from UHID driver*/
  2. static int uhid_event(btif_hh_device_t *p_dev)
  3. {
  4. struct uhid_event ev;
  5. ssize_t ret;
  6. memset(&ev, 0, sizeof(ev));
  7. if(!p_dev)
  8. {
  9. APPL_TRACE_ERROR("%s: Device not found",__FUNCTION__)
  10. return -1;
  11. }
  12. ret = read(p_dev->fd, &ev, sizeof(ev));
  13. if (ret == 0) {
  14. APPL_TRACE_ERROR("%s: Read HUP on uhid-cdev %s", __FUNCTION__,
  15. strerror(errno));
  16. return -EFAULT;
  17. } else if (ret < 0) {
  18. APPL_TRACE_ERROR("%s:Cannot read uhid-cdev: %s", __FUNCTION__,
  19. strerror(errno));
  20. return -errno;
  21. } else if (ret != sizeof(ev)) {
  22. APPL_TRACE_ERROR("%s:Invalid size read from uhid-dev: %ld != %lu",
  23. __FUNCTION__, ret, sizeof(ev));
  24. return -EFAULT;
  25. }
  26. switch (ev.type) {
  27. case UHID_START:
  28. APPL_TRACE_DEBUG("UHID_START from uhid-dev\n");
  29. break;
  30. case UHID_STOP:
  31. APPL_TRACE_DEBUG("UHID_STOP from uhid-dev\n");
  32. break;
  33. case UHID_OPEN:
  34. APPL_TRACE_DEBUG("UHID_OPEN from uhid-dev\n");
  35. break;
  36. case UHID_CLOSE:
  37. APPL_TRACE_DEBUG("UHID_CLOSE from uhid-dev\n");
  38. break;
  39. case UHID_OUTPUT:
  40. APPL_TRACE_DEBUG("UHID_OUTPUT: Report type = %d, report_size = %d"
  41. ,ev.u.output.rtype, ev.u.output.size);
  42. //Send SET_REPORT with feature report if the report type in output event is FEATURE
  43. if(ev.u.output.rtype == UHID_FEATURE_REPORT)
  44. btif_hh_setreport(p_dev,BTHH_FEATURE_REPORT,ev.u.output.size,ev.u.output.data);
  45. else if(ev.u.output.rtype == UHID_OUTPUT_REPORT)
  46. btif_hh_setreport(p_dev,BTHH_OUTPUT_REPORT,ev.u.output.size,ev.u.output.data);
  47. else
  48. btif_hh_setreport(p_dev,BTHH_INPUT_REPORT,ev.u.output.size,ev.u.output.data);
  49. break;
  50. case UHID_OUTPUT_EV:
  51. APPL_TRACE_DEBUG("UHID_OUTPUT_EV from uhid-dev\n");
  52. break;
  53. case UHID_FEATURE:
  54. APPL_TRACE_DEBUG("UHID_FEATURE from uhid-dev\n");
  55. break;
  56. case UHID_FEATURE_ANSWER:
  57. APPL_TRACE_DEBUG("UHID_FEATURE_ANSWER from uhid-dev\n");
  58. break;
  59. default:
  60. APPL_TRACE_DEBUG("Invalid event from uhid-dev: %u\n", ev.type);
  61. }
  62. return 0;
  63. }

复制代码

 --->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btif_btif_hh_setreport
  4. **
  5. ** Description setreport initiated from the BTIF thread context
  6. **
  7. ** Returns void
  8. **
  9. *******************************************************************************/
  10. #define COMMAND_PATCH
  11. void btif_hh_setreport(btif_hh_device_t *p_dev, bthh_report_type_t r_type, UINT16 size,
  12. UINT8* report)
  13. {
  14. BT_HDR* p_buf = create_pbuf(size, report);
  15. if (p_buf == NULL) {
  16. APPL_TRACE_ERROR("%s: Error, failed to allocate RPT buffer, size = %d", __FUNCTION__, size);
  17. return;
  18. }
  19. #ifdef COMMAND_PATCH
  20. if(report[0] != 0x5B) /*判断report id!=0x5B,执行默认的request,需要response*/
  21. BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
  22. else{ /*判断report id==0x5B,发送command,不需要response*/
  23. BD_ADDR* bda = (BD_ADDR*)&p_dev->bd_addr;
  24. BTIF_TRACE_DEBUG("Send Command Size %",size);
  25. p_buf->layer_specific = BTA_HH_RPTT_OUTPUT;
  26. BTA_HhSendData(p_dev->dev_handle,*bda,p_buf);
  27. }
  28. #else
  29. BTA_HhSetReport(p_dev->dev_handle, r_type, p_buf);
  30. #endif
  31. }

复制代码

发送数据到HID设备:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function BTA_HhSendData
  4. **
  5. ** Description This function send DATA transaction to HID device.
  6. **
  7. ** Parameter dev_handle: device handle
  8. ** dev_bda: remote device address
  9. ** p_data: data to be sent in the DATA transaction; or
  10. ** the data to be write into the Output Report of a LE HID
  11. ** device. The report is identified the report ID which is
  12. ** the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
  13. ** p_data->layer_specific needs to be set to the report type,
  14. ** it can be OUTPUT report, or FEATURE report.
  15. **
  16. ** Returns void
  17. **
  18. *******************************************************************************/
  19. void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
  20. {
  21. UNUSED(dev_bda);
  22. #if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
  23. if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT)
  24. {
  25. APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
  26. return;
  27. }
  28. #endif
  29. bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
  30. }

复制代码

 -->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_snd_write_dev
  4. **
  5. *******************************************************************************/
  6. static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
  7. UINT16 data, UINT8 rpt_id, BT_HDR *p_data)
  8. {
  9. tBTA_HH_CMD_DATA *p_buf;
  10. UINT16 len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
  11. if ((p_buf = (tBTA_HH_CMD_DATA *)GKI_getbuf(len))!= NULL)
  12. {
  13. memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
  14. p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
  15. p_buf->hdr.layer_specific = (UINT16) dev_handle;
  16. p_buf->t_type = t_type;
  17. p_buf->data = data;
  18. p_buf->param = param;
  19. p_buf->p_data = p_data;
  20. p_buf->rpt_id = rpt_id;
  21. bta_sys_sendmsg(p_buf); //发送数据到hid处理进程
  22. }
  23. }

复制代码

 

external\bluetooth\bluedroid\bta\hh\bta_hh_main.c

BTA_HhEnable时注册的HID主处理函数进行数据接收和处理:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_hdl_event
  4. **
  5. ** Description HID host main event handling function.
  6. **
  7. **
  8. ** Returns void
  9. **
  10. *******************************************************************************/
  11. BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
  12. {
  13. UINT8 index = BTA_HH_IDX_INVALID;
  14. tBTA_HH_DEV_CB *p_cb = NULL;
  15. switch (p_msg->event)
  16. {
  17. case BTA_HH_API_ENABLE_EVT:
  18. bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
  19. break;
  20. case BTA_HH_API_DISABLE_EVT:
  21. bta_hh_api_disable();
  22. break;
  23. case BTA_HH_DISC_CMPL_EVT: /* disable complete */
  24. bta_hh_disc_cmpl();
  25. break;
  26. default:
  27. /* all events processed in state machine need to find corresponding
  28. CB before proceed */
  29. if (p_msg->event == BTA_HH_API_OPEN_EVT)
  30. {
  31. index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
  32. }
  33. else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT)
  34. {
  35. /* if add device */
  36. if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT)
  37. {
  38. index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
  39. }
  40. else /* else remove device by handle */
  41. {
  42. index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
  43. // btla-specific ++
  44. /* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
  45. * then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
  46. * cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
  47. * So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
  48. * force the index to be IDX_INVALID
  49. */
  50. if ((index != BTA_HH_IDX_INVALID) &&
  51. (bta_hh_cb.kdev[index].in_use == FALSE)) {
  52. index = BTA_HH_IDX_INVALID;
  53. }
  54. // btla-specific --
  55. }
  56. }
  57. else if (p_msg->event == BTA_HH_INT_OPEN_EVT)
  58. {
  59. index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
  60. }
  61. else
  62. index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
  63. if (index != BTA_HH_IDX_INVALID)
  64. p_cb = &bta_hh_cb.kdev[index];
  65. #if BTA_HH_DEBUG
  66. APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
  67. #endif
  68. bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg); //状态机处理函数
  69. }
  70. return (TRUE);
  71. }

复制代码

HID状态机事件处理函数

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_sm_execute
  4. **
  5. ** Description State machine event handling function for HID Host
  6. **
  7. **
  8. ** Returns void
  9. **
  10. *******************************************************************************/
  11. void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA * p_data)
  12. {
  13. tBTA_HH_ST_TBL state_table;
  14. UINT8 action;
  15. tBTA_HH cback_data;
  16. tBTA_HH_EVT cback_event = 0;
  17. #if BTA_HH_DEBUG == TRUE
  18. tBTA_HH_STATE in_state ;
  19. UINT16 debug_event = event;
  20. #endif
  21. memset(&cback_data, 0, sizeof(tBTA_HH));
  22. /* handle exception, no valid control block was found */
  23. if (!p_cb)
  24. {
  25. /* BTA HH enabled already? otherwise ignore the event although it's bad*/
  26. if (bta_hh_cb.p_cback != NULL)
  27. {
  28. switch (event)
  29. {
  30. /* no control block available for new connection */
  31. case BTA_HH_API_OPEN_EVT:
  32. cback_event = BTA_HH_OPEN_EVT;
  33. /* build cback data */
  34. bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
  35. cback_data.conn.status = BTA_HH_ERR_DB_FULL;
  36. cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
  37. break;
  38. /* DB full, BTA_HhAddDev */
  39. case BTA_HH_API_MAINT_DEV_EVT:
  40. cback_event = p_data->api_maintdev.sub_event;
  41. if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT)
  42. {
  43. bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
  44. cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
  45. cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
  46. }
  47. else
  48. {
  49. cback_data.dev_info.status = BTA_HH_ERR_HDL;
  50. cback_data.dev_info.handle = (UINT8)p_data->api_maintdev.hdr.layer_specific;
  51. }
  52. break;
  53. case BTA_HH_API_WRITE_DEV_EVT:
  54. cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
  55. BTA_HH_FST_TRANS_CB_EVT;
  56. if (p_data->api_sndcmd.p_data != NULL)
  57. {
  58. GKI_freebuf(p_data->api_sndcmd.p_data);
  59. }
  60. if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
  61. p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
  62. p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE)
  63. {
  64. cback_data.dev_status.status = BTA_HH_ERR_HDL;
  65. cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
  66. }
  67. else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
  68. p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
  69. {
  70. cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
  71. cback_data.hs_data.status = BTA_HH_ERR_HDL;
  72. /* hs_data.rsp_data will be all zero, which is not valid value */
  73. }
  74. else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
  75. p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
  76. {
  77. cback_data.status = BTA_HH_ERR_HDL;
  78. cback_event = BTA_HH_VC_UNPLUG_EVT;
  79. }
  80. else
  81. cback_event = 0;
  82. break;
  83. case BTA_HH_API_CLOSE_EVT:
  84. cback_event = BTA_HH_CLOSE_EVT;
  85. cback_data.dev_status.status = BTA_HH_ERR_HDL;
  86. cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
  87. break;
  88. default:
  89. /* invalid handle, call bad API event */
  90. APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
  91. /* Free the callback buffer now */
  92. if (p_data != NULL && p_data->hid_cback.p_data != NULL)
  93. {
  94. GKI_freebuf(p_data->hid_cback.p_data);
  95. p_data->hid_cback.p_data = NULL;
  96. }
  97. break;
  98. }
  99. if (cback_event)
  100. (* bta_hh_cb.p_cback)(cback_event, &cback_data);
  101. }
  102. }
  103. /* corresponding CB is found, go to state machine */
  104. else
  105. {
  106. #if BTA_HH_DEBUG == TRUE
  107. in_state = p_cb->state;
  108. APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
  109. in_state, bta_hh_state_code(in_state),
  110. bta_hh_evt_code(debug_event));
  111. #endif
  112. if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST))
  113. {
  114. APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
  115. p_cb->state,event);
  116. return;
  117. }
  118. state_table = bta_hh_st_tbl[p_cb->state - 1];
  119. event &= 0xff;
  120. p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
  121. if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE)
  122. {
  123. (*bta_hh_action[action])(p_cb, p_data); //各事件处理函数列表,写节点为action(8)-> bta_hh_write_dev_act
  124. }
  125. #if BTA_HH_DEBUG == TRUE
  126. if (in_state != p_cb->state)
  127. {
  128. APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
  129. bta_hh_state_code(in_state),
  130. bta_hh_state_code(p_cb->state),
  131. bta_hh_evt_code(debug_event));
  132. }
  133. #endif
  134. }
  135. return;
  136. }

复制代码

--->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_write_dev_act
  4. **
  5. ** Description Write device action. can be SET/GET/DATA transaction.
  6. **
  7. ** Returns void
  8. **
  9. *******************************************************************************/
  10. void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
  11. {
  12. tBTA_HH_CBDATA cbdata = {BTA_HH_OK, 0};
  13. UINT16 event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
  14. BTA_HH_FST_TRANS_CB_EVT;
  15. #if BTA_HH_LE_INCLUDED == TRUE
  16. if (p_cb->is_le_device){
  17.     //调用到这里t_type为10(HID_TRANS_DATA)即开始通过 BTA_HhSendData 函数发送数据方式:
  18. APPL_TRACE_DEBUG("bta_hh_le_write_dev_act : p_data->api_sndcmd.t_type = %d ",p_data->api_sndcmd.t_type);
  19. bta_hh_le_write_dev_act(p_cb, p_data);
  20. }
  21. else
  22. #endif
  23. {
  24. cbdata.handle = p_cb->hid_handle;
  25. /* match up BTE/BTA report/boot mode def */
  26. if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL)
  27. {
  28. p_data->api_sndcmd.param = ( p_data->api_sndcmd.param == BTA_HH_PROTO_RPT_MODE) ?\
  29. HID_PAR_PROTOCOL_REPORT :HID_PAR_PROTOCOL_BOOT_MODE;
  30. }
  31. if (HID_HostWriteDev (p_cb->hid_handle,
  32. p_data->api_sndcmd.t_type,
  33. p_data->api_sndcmd.param,
  34. p_data->api_sndcmd.data,
  35. p_data->api_sndcmd.rpt_id,
  36. p_data->api_sndcmd.p_data) != HID_SUCCESS)
  37. {
  38. APPL_TRACE_ERROR("HID_HostWriteDev Error ");
  39. cbdata.status = BTA_HH_ERR;
  40. if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL &&
  41. p_data->api_sndcmd.t_type != HID_TRANS_DATA)
  42. (* bta_hh_cb.p_cback)(event, (tBTA_HH *)&cbdata);
  43. else if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
  44. (* bta_hh_cb.p_cback)(BTA_HH_VC_UNPLUG_EVT, (tBTA_HH *)&cbdata);
  45. }
  46. else
  47. {
  48. switch(p_data->api_sndcmd.t_type)
  49. {
  50. case HID_TRANS_SET_PROTOCOL:
  51. /* fall through */
  52. case HID_TRANS_GET_REPORT:
  53. /* fall through */
  54. case HID_TRANS_SET_REPORT:
  55. /* fall through */
  56. case HID_TRANS_GET_PROTOCOL:
  57. /* fall through */
  58. case HID_TRANS_GET_IDLE:
  59. /* fall through */
  60. case HID_TRANS_SET_IDLE:/* set w4_handsk event name for callback function use */
  61. p_cb->w4_evt = event;
  62. break;
  63. case HID_TRANS_DATA: /* output report */
  64. /* fall through */
  65. case HID_TRANS_CONTROL:
  66. /* no handshake event will be generated */
  67. /* if VC_UNPLUG is issued, set flag */
  68. if (p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG)
  69. p_cb->vp = TRUE;
  70. break;
  71. /* currently not expected */
  72. case HID_TRANS_DATAC:
  73. default:
  74. APPL_TRACE_DEBUG("bta_hh_write_dev_act:: cmd type = %d",
  75. p_data->api_sndcmd.t_type);
  76. break;
  77. }
  78. /* if not control type transaction, notify PM for energy control */
  79. if (p_data->api_sndcmd.t_type != HID_TRANS_CONTROL)
  80. {
  81. /* inform PM for mode change */
  82. bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
  83. bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr);
  84. }
  85. else if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND)
  86. {
  87. bta_sys_sco_close(BTA_ID_HH, p_cb->app_id, p_cb->addr);
  88. }
  89. else if (p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND)
  90. {
  91. bta_sys_busy(BTA_ID_HH, p_cb->app_id, p_cb->addr);
  92. }
  93. }
  94. }
  95. return;
  96. }

复制代码

--->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_le_write_dev_act
  4. **
  5. ** Description Write LE device action. can be SET/GET/DATA transaction.
  6. **
  7. ** Returns void
  8. **
  9. *******************************************************************************/
  10. void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data)
  11. {
  12. switch(p_data->api_sndcmd.t_type) //上面打印结果是10,即对应:HID_TRANS_DATA
  13. {
  14. case HID_TRANS_SET_PROTOCOL:
  15. p_cb->w4_evt = BTA_HH_SET_PROTO_EVT;
  16. bta_hh_le_set_protocol_mode(p_cb, p_data->api_sndcmd.param);
  17. break;
  18. case HID_TRANS_GET_PROTOCOL:
  19. bta_hh_le_get_protocol_mode(p_cb);
  20. break;
  21. case HID_TRANS_GET_REPORT:
  22. bta_hh_le_get_rpt(p_cb,
  23. BTA_HH_LE_SRVC_DEF,
  24. p_data->api_sndcmd.param,
  25. p_data->api_sndcmd.rpt_id);
  26. break;
  27. case HID_TRANS_SET_REPORT:
  28. bta_hh_le_write_rpt(p_cb,
  29. BTA_HH_LE_SRVC_DEF,
  30. BTA_GATTC_TYPE_WRITE,
  31. p_data->api_sndcmd.param,
  32. p_data->api_sndcmd.p_data,
  33. BTA_HH_SET_RPT_EVT);
  34. break;
  35. case HID_TRANS_DATA: /* output report */
  36. bta_hh_le_write_rpt(p_cb,
  37. BTA_HH_LE_SRVC_DEF,
  38. BTA_GATTC_TYPE_WRITE_NO_RSP,
  39. p_data->api_sndcmd.param,
  40. p_data->api_sndcmd.p_data,
  41. BTA_HH_DATA_EVT);
  42. break;
  43. case HID_TRANS_CONTROL:
  44. /* no handshake event will be generated */
  45. /* if VC_UNPLUG is issued, set flag */
  46. if (p_data->api_sndcmd.param == BTA_HH_CTRL_SUSPEND ||
  47. p_data->api_sndcmd.param == BTA_HH_CTRL_EXIT_SUSPEND)
  48. {
  49. bta_hh_le_suspend(p_cb, p_data->api_sndcmd.param);
  50. }
  51. break;
  52. default:
  53. APPL_TRACE_ERROR("%s unsupported transaction for BLE HID device: %d",
  54. __func__, p_data->api_sndcmd.t_type);
  55. break;
  56. }
  57. }

复制代码

-->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_hh_le_write_rpt
  4. **
  5. ** Description SET_REPORT/or DATA output on a LE HID Report
  6. **
  7. ** Returns void
  8. **
  9. *******************************************************************************/
  10. void bta_hh_le_write_rpt(tBTA_HH_DEV_CB *p_cb, UINT8 srvc_inst,
  11. tBTA_GATTC_WRITE_TYPE write_type,
  12. tBTA_HH_RPT_TYPE r_type,
  13. BT_HDR *p_buf, UINT16 w4_evt )
  14. {
  15. tBTA_HH_LE_RPT *p_rpt;
  16. tBTA_GATTC_CHAR_ID char_id;
  17. UINT8 *p_value, rpt_id;
  18. if (p_buf == NULL || p_buf->len == 0)
  19. {
  20. APPL_TRACE_ERROR("bta_hh_le_write_rpt: Illegal data");
  21. return;
  22. }
  23. /* strip report ID from the data */
  24. p_value = (UINT8 *)(p_buf + 1) + p_buf->offset;
  25. STREAM_TO_UINT8(rpt_id, p_value);
  26. p_buf->len -= 1;
  27. p_rpt = bta_hh_le_find_rpt_by_idtype(p_cb->hid_srvc[srvc_inst].report, p_cb->mode, r_type, rpt_id);
  28. if (p_rpt == NULL)
  29. {
  30. APPL_TRACE_ERROR("bta_hh_le_write_rpt: no matching report 0x%02x",rpt_id);
  31. GKI_freebuf(p_buf);
  32. return;
  33. }
  34. APPL_TRACE_ERROR("bta_hh_le_write_rpt: ReportID: 0x%02x Data Len: %d", rpt_id, p_buf->len);
  35. p_cb->w4_evt = w4_evt;
  36. bta_hh_le_fill_16bits_srvc_id(TRUE, srvc_inst, UUID_SERVCLASS_LE_HID, &char_id.srvc_id);
  37. bta_hh_le_fill_16bits_char_id(p_rpt->inst_id, p_rpt->uuid, &char_id.char_id);
  38. LOG_DEBUG("%s: BTA_GATTC_WriteCharValue::", __FUNCTION__);
  39. BTA_GATTC_WriteCharValue(p_cb->conn_id,
  40. &char_id,
  41. write_type, /* default to use write request */ //之前reportid 0x5b的patch使 write_type为BTA_GATTC_TYPE_WRITE_NO_RSP
  42. p_buf->len,
  43. p_value,
  44. BTA_GATT_AUTH_REQ_NONE);
  45. }

复制代码

-->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function BTA_GATTC_WriteCharValue
  4. **
  5. ** Description This function is called to write characteristic value.
  6. **
  7. ** Parameters conn_id - connection ID.
  8. ** p_char_id - characteristic ID to write.
  9. ** write_type - type of write.
  10. ** len: length of the data to be written.
  11. ** p_value - the value to be written.
  12. **
  13. ** Returns None
  14. **
  15. *******************************************************************************/
  16. void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
  17. tBTA_GATTC_CHAR_ID *p_char_id,
  18. tBTA_GATTC_WRITE_TYPE write_type,
  19. UINT16 len,
  20. UINT8 *p_value,
  21. tBTA_GATT_AUTH_REQ auth_req)
  22. {
  23. tBTA_GATTC_API_WRITE *p_buf;
  24. if ((p_buf = (tBTA_GATTC_API_WRITE *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTC_API_WRITE) + len))) != NULL)
  25. {
  26. memset(p_buf, 0, sizeof(tBTA_GATTC_API_WRITE) + len);
  27. p_buf->hdr.event = BTA_GATTC_API_WRITE_EVT;
  28. p_buf->hdr.layer_specific = conn_id;
  29. p_buf->auth_req = auth_req;
  30. memcpy(&p_buf->srvc_id, &p_char_id->srvc_id, sizeof(tBTA_GATT_SRVC_ID));
  31. memcpy(&p_buf->char_id, &p_char_id->char_id, sizeof(tBTA_GATT_ID));
  32. APPL_TRACE_DEBUG("BTA_GATTC_WriteCharValue : write_type=%d",write_type);
  33. p_buf->write_type = write_type;
  34. p_buf->len = len;
  35. if (p_value && len > 0)
  36. {
  37. p_buf->p_value = (UINT8 *)(p_buf + 1);
  38. memcpy(p_buf->p_value, p_value, len);
  39. }
  40. bta_sys_sendmsg(p_buf); //设置数据类型后发送到gatt层
  41. }
  42. return;
  43. }

复制代码

 

应用层传下来的消息到GATT层:

external\bluetooth\bluedroid\stack\btu\btu_task.c

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function btu_task
  4. **
  5. ** Description This is the main task of the Bluetooth Upper Layers unit.
  6. ** It sits in a loop waiting for messages, and dispatches them
  7. ** to the appropiate handlers.
  8. **
  9. ** Returns should never return
  10. **
  11. *******************************************************************************/
  12. BTU_API UINT32 btu_task (UINT32 param)
  13. {
  14. UINT16 event;
  15. BT_HDR *p_msg;
  16. UINT8 i;
  17. UINT16 mask;
  18. BOOLEAN handled;
  19. UNUSED(param);
  20. #if (defined(HCISU_H4_INCLUDED) && HCISU_H4_INCLUDED == TRUE)
  21. /* wait an event that HCISU is ready */
  22. BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
  23. "btu_task pending for preload complete event");
  24. for (;;)
  25. {
  26. event = GKI_wait (0xFFFF, 0);
  27. if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))
  28. {
  29. /* indicates BT ENABLE abort */
  30. BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
  31. "btu_task start abort!");
  32. return (0);
  33. }
  34. else if (event & BT_EVT_PRELOAD_CMPL)
  35. {
  36. break;
  37. }
  38. else
  39. {
  40. BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_WARNING,
  41. "btu_task ignore evt %04x while pending for preload complete",
  42. event);
  43. }
  44. }
  45. BT_TRACE(TRACE_LAYER_BTU, TRACE_TYPE_API,
  46. "btu_task received preload complete event");
  47. #endif
  48. /* Initialize the mandatory core stack control blocks
  49. (BTU, BTM, L2CAP, and SDP)
  50. */
  51. btu_init_core();
  52. /* Initialize any optional stack components */
  53. BTE_InitStack();
  54. #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
  55. bta_sys_init();
  56. #endif
  57. /* Initialise platform trace levels at this point as BTE_InitStack() and bta_sys_init()
  58. * reset the control blocks and preset the trace level with XXX_INITIAL_TRACE_LEVEL
  59. */
  60. #if ( BT_USE_TRACES==TRUE )
  61. BTE_InitTraceLevels();
  62. #endif
  63. /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
  64. GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
  65. prctl(PR_SET_NAME, (unsigned long)"BTU TASK", 0, 0, 0);
  66. raise_priority_a2dp(TASK_HIGH_BTU);
  67. /* Wait for, and process, events */
  68. for (;;)
  69. {
  70. event = GKI_wait (0xFFFF, 0);
  71. if (event & TASK_MBOX_0_EVT_MASK)
  72. {
  73. /* Process all messages in the queue */
  74. while ((p_msg = (BT_HDR *) GKI_read_mbox (BTU_HCI_RCV_MBOX)) != NULL)
  75. {
  76. /* Determine the input message type. */
  77. switch (p_msg->event & BT_EVT_MASK)
  78. {
  79. case BT_EVT_TO_BTU_HCI_ACL:
  80. /* All Acl Data goes to L2CAP */
  81. l2c_rcv_acl_data (p_msg);
  82. break;
  83. case BT_EVT_TO_BTU_L2C_SEG_XMIT:
  84. /* L2CAP segment transmit complete */
  85. l2c_link_segments_xmitted (p_msg);
  86. break;
  87. case BT_EVT_TO_BTU_HCI_SCO:
  88. #if BTM_SCO_INCLUDED == TRUE
  89. btm_route_sco_data (p_msg);
  90. break;
  91. #endif
  92. case BT_EVT_TO_BTU_HCI_EVT:
  93. btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
  94. GKI_freebuf(p_msg);
  95. #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
  96. /* If host receives events which it doesn't response to, */
  97. /* host should start idle timer to enter sleep mode. */
  98. btu_check_bt_sleep ();
  99. #endif
  100. break;
  101. case BT_EVT_TO_BTU_HCI_CMD:
  102. btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
  103. break;
  104. #if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
  105. #if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
  106. case BT_EVT_TO_OBX_SR_MSG:
  107. obx_sr_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
  108. GKI_freebuf (p_msg);
  109. break;
  110. case BT_EVT_TO_OBX_SR_L2C_MSG:
  111. obx_sr_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
  112. GKI_freebuf (p_msg);
  113. break;
  114. #endif
  115. #if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
  116. case BT_EVT_TO_OBX_CL_MSG:
  117. obx_cl_proc_evt((tOBX_PORT_EVT *)(p_msg + 1));
  118. GKI_freebuf (p_msg);
  119. break;
  120. case BT_EVT_TO_OBX_CL_L2C_MSG:
  121. obx_cl_proc_l2c_evt((tOBX_L2C_EVT_MSG *)(p_msg + 1));
  122. GKI_freebuf (p_msg);
  123. break;
  124. #endif
  125. #if (defined(BIP_INCLUDED) && BIP_INCLUDED == TRUE)
  126. case BT_EVT_TO_BIP_CMDS :
  127. bip_proc_btu_event(p_msg);
  128. GKI_freebuf (p_msg);
  129. break;
  130. #endif /* BIP */
  131. #if (BPP_SND_INCLUDED == TRUE || BPP_INCLUDED == TRUE)
  132. case BT_EVT_TO_BPP_PR_CMDS:
  133. bpp_pr_proc_event(p_msg);
  134. GKI_freebuf (p_msg);
  135. break;
  136. case BT_EVT_TO_BPP_SND_CMDS:
  137. bpp_snd_proc_event(p_msg);
  138. GKI_freebuf (p_msg);
  139. break;
  140. #endif /* BPP */
  141. #endif /* OBX */
  142. #if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
  143. case BT_EVT_TO_BTU_SAP :
  144. sap_proc_btu_event(p_msg);
  145. GKI_freebuf (p_msg);
  146. break;
  147. #endif /* SAP */
  148. #if (defined(GAP_CONN_INCLUDED) && GAP_CONN_INCLUDED == TRUE && GAP_CONN_POST_EVT_INCLUDED == TRUE)
  149. case BT_EVT_TO_GAP_MSG :
  150. gap_proc_btu_event(p_msg);
  151. GKI_freebuf (p_msg);
  152. break;
  153. #endif
  154. case BT_EVT_TO_START_TIMER :
  155. /* Start free running 1 second timer for list management */
  156. GKI_start_timer (TIMER_0, GKI_SECS_TO_TICKS (1), TRUE);
  157. GKI_freebuf (p_msg);
  158. break;
  159. case BT_EVT_TO_STOP_TIMER:
  160. if (GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
  161. GKI_stop_timer(TIMER_0);
  162. }
  163. GKI_freebuf (p_msg);
  164. break;
  165. case BT_EVT_TO_START_TIMER_ONESHOT:
  166. if (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
  167. TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
  168. // Start non-repeating timer.
  169. GKI_start_timer(TIMER_3, tle->ticks, FALSE);
  170. } else {
  171. BTM_TRACE_WARNING("Oneshot timer queue empty when received start request");
  172. }
  173. GKI_freebuf(p_msg);
  174. break;
  175. case BT_EVT_TO_STOP_TIMER_ONESHOT:
  176. if (GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
  177. GKI_stop_timer(TIMER_3);
  178. } else {
  179. BTM_TRACE_WARNING("Oneshot timer queue not empty when received stop request");
  180. }
  181. GKI_freebuf (p_msg);
  182. break;
  183. #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
  184. case BT_EVT_TO_START_QUICK_TIMER :
  185. GKI_start_timer (TIMER_2, QUICK_TIMER_TICKS, TRUE);
  186. GKI_freebuf (p_msg);
  187. break;
  188. #endif
  189. default:
  190. i = 0;
  191. mask = (UINT16) (p_msg->event & BT_EVT_MASK);
  192. handled = FALSE;
  193. for (; !handled && i < BTU_MAX_REG_EVENT; i++)
  194. {
  195. if (btu_cb.event_reg[i].event_cb == NULL)
  196. continue;
  197. if (mask == btu_cb.event_reg[i].event_range)
  198. {
  199. if (btu_cb.event_reg[i].event_cb)
  200. {
  201. btu_cb.event_reg[i].event_cb(p_msg);
  202. handled = TRUE;
  203. }
  204. }
  205. }
  206. if (handled == FALSE)
  207. GKI_freebuf (p_msg);
  208. break;
  209. }
  210. }
  211. }
  212. if (event & TIMER_0_EVT_MASK) {
  213. GKI_update_timer_list (&btu_cb.timer_queue, 1);
  214. while (!GKI_timer_queue_is_empty(&btu_cb.timer_queue)) {
  215. TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue);
  216. if (p_tle->ticks != 0)
  217. break;
  218. GKI_remove_from_timer_list(&btu_cb.timer_queue, p_tle);
  219. switch (p_tle->event) {
  220. case BTU_TTYPE_BTM_DEV_CTL:
  221. btm_dev_timeout(p_tle);
  222. break;
  223. case BTU_TTYPE_BTM_ACL:
  224. btm_acl_timeout(p_tle);
  225. break;
  226. case BTU_TTYPE_L2CAP_LINK:
  227. case BTU_TTYPE_L2CAP_CHNL:
  228. case BTU_TTYPE_L2CAP_HOLD:
  229. case BTU_TTYPE_L2CAP_INFO:
  230. case BTU_TTYPE_L2CAP_FCR_ACK:
  231. l2c_process_timeout (p_tle);
  232. break;
  233. case BTU_TTYPE_SDP:
  234. sdp_conn_timeout ((tCONN_CB *)p_tle->param);
  235. break;
  236. case BTU_TTYPE_BTM_RMT_NAME:
  237. btm_inq_rmt_name_failed();
  238. break;
  239. #if (defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE)
  240. case BTU_TTYPE_RFCOMM_MFC:
  241. case BTU_TTYPE_RFCOMM_PORT:
  242. rfcomm_process_timeout (p_tle);
  243. break;
  244. #endif /* If defined(RFCOMM_INCLUDED) && RFCOMM_INCLUDED == TRUE */
  245. #if ((defined(BNEP_INCLUDED) && BNEP_INCLUDED == TRUE))
  246. case BTU_TTYPE_BNEP:
  247. bnep_process_timeout(p_tle);
  248. break;
  249. #endif
  250. #if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
  251. case BTU_TTYPE_AVDT_CCB_RET:
  252. case BTU_TTYPE_AVDT_CCB_RSP:
  253. case BTU_TTYPE_AVDT_CCB_IDLE:
  254. case BTU_TTYPE_AVDT_SCB_TC:
  255. avdt_process_timeout(p_tle);
  256. break;
  257. #endif
  258. #if (defined(OBX_INCLUDED) && OBX_INCLUDED == TRUE)
  259. #if (defined(OBX_CLIENT_INCLUDED) && OBX_CLIENT_INCLUDED == TRUE)
  260. case BTU_TTYPE_OBX_CLIENT_TO:
  261. obx_cl_timeout(p_tle);
  262. break;
  263. #endif
  264. #if (defined(OBX_SERVER_INCLUDED) && OBX_SERVER_INCLUDED == TRUE)
  265. case BTU_TTYPE_OBX_SERVER_TO:
  266. obx_sr_timeout(p_tle);
  267. break;
  268. case BTU_TTYPE_OBX_SVR_SESS_TO:
  269. obx_sr_sess_timeout(p_tle);
  270. break;
  271. #endif
  272. #endif
  273. #if (defined(SAP_SERVER_INCLUDED) && SAP_SERVER_INCLUDED == TRUE)
  274. case BTU_TTYPE_SAP_TO:
  275. sap_process_timeout(p_tle);
  276. break;
  277. #endif
  278. case BTU_TTYPE_BTU_CMD_CMPL:
  279. btu_hcif_cmd_timeout((UINT8)(p_tle->event - BTU_TTYPE_BTU_CMD_CMPL));
  280. break;
  281. #if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
  282. case BTU_TTYPE_HID_HOST_REPAGE_TO :
  283. hidh_proc_repage_timeout(p_tle);
  284. break;
  285. #endif
  286. #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
  287. case BTU_TTYPE_BLE_INQUIRY:
  288. case BTU_TTYPE_BLE_GAP_LIM_DISC:
  289. case BTU_TTYPE_BLE_GAP_FAST_ADV:
  290. case BTU_TTYPE_BLE_OBSERVE:
  291. btm_ble_timeout(p_tle);
  292. break;
  293. case BTU_TTYPE_ATT_WAIT_FOR_RSP:
  294. gatt_rsp_timeout(p_tle);
  295. break;
  296. case BTU_TTYPE_ATT_WAIT_FOR_IND_ACK:
  297. gatt_ind_ack_timeout(p_tle);
  298. break;
  299. #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE)
  300. case BTU_TTYPE_SMP_PAIRING_CMD:
  301. smp_rsp_timeout(p_tle);
  302. break;
  303. #endif
  304. #endif
  305. #if (MCA_INCLUDED == TRUE)
  306. case BTU_TTYPE_MCA_CCB_RSP:
  307. mca_process_timeout(p_tle);
  308. break;
  309. #endif
  310. case BTU_TTYPE_USER_FUNC:
  311. {
  312. tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
  313. (*p_uf)(p_tle);
  314. }
  315. break;
  316. default:
  317. i = 0;
  318. handled = FALSE;
  319. for (; !handled && i < BTU_MAX_REG_TIMER; i++)
  320. {
  321. if (btu_cb.timer_reg[i].timer_cb == NULL)
  322. continue;
  323. if (btu_cb.timer_reg[i].p_tle == p_tle)
  324. {
  325. btu_cb.timer_reg[i].timer_cb(p_tle);
  326. handled = TRUE;
  327. }
  328. }
  329. break;
  330. }
  331. }
  332. /* if timer list is empty stop periodic GKI timer */
  333. if (btu_cb.timer_queue.p_first == NULL)
  334. {
  335. GKI_stop_timer(TIMER_0);
  336. }
  337. }
  338. #if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
  339. if (event & TIMER_2_EVT_MASK)
  340. {
  341. btu_process_quick_timer_evt();
  342. }
  343. #endif
  344. #if (RPC_INCLUDED == TRUE)
  345. /* if RPC message queue event */
  346. if (event & RPCGEN_MSG_EVT)
  347. {
  348. if ((p_msg = (BT_HDR *) GKI_read_mbox(RPCGEN_MSG_MBOX)) != NULL)
  349. RPCT_RpcgenMsg(p_msg); /* handle RPC message queue */
  350. }
  351. #endif
  352. #if (defined(BTU_BTA_INCLUDED) && BTU_BTA_INCLUDED == TRUE)
  353. if (event & TASK_MBOX_2_EVT_MASK)
  354. {
  355. while ((p_msg = (BT_HDR *) GKI_read_mbox(TASK_MBOX_2)) != NULL)
  356. {
  357. bta_sys_event(p_msg); //处理上层传来的消息
  358. }
  359. }
  360. if (event & TIMER_1_EVT_MASK)
  361. {
  362. bta_sys_timer_update();
  363. }
  364. #endif
  365. if (event & TIMER_3_EVT_MASK) {
  366. BTM_TRACE_API("Received oneshot timer event complete");
  367. if (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
  368. TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
  369. INT32 ticks_since_last_update = GKI_timer_ticks_getinitial(GKI_timer_getfirst(&btu_cb.timer_queue_oneshot));
  370. GKI_update_timer_list(&btu_cb.timer_queue_oneshot, ticks_since_last_update);
  371. }
  372. while (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
  373. TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
  374. if (p_tle->ticks != 0)
  375. break;
  376. GKI_remove_from_timer_list(&btu_cb.timer_queue_oneshot, p_tle);
  377. switch (p_tle->event) {
  378. #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
  379. case BTU_TTYPE_BLE_RANDOM_ADDR:
  380. btm_ble_timeout(p_tle);
  381. break;
  382. #endif
  383. case BTU_TTYPE_USER_FUNC:
  384. {
  385. tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param;
  386. (*p_uf)(p_tle);
  387. }
  388. break;
  389. default:
  390. // FAIL
  391. BTM_TRACE_WARNING("Received unexpected oneshot timer event:0x%x\n",
  392. p_tle->event);
  393. break;
  394. }
  395. }
  396. /* Update GKI timer with new tick value from first timer. */
  397. if (!GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) {
  398. TIMER_LIST_ENT *p_tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
  399. if (p_tle->ticks > 0)
  400. GKI_start_timer(TIMER_3, p_tle->ticks, FALSE);
  401. } else {
  402. GKI_stop_timer(TIMER_3);
  403. }
  404. }
  405. if (event & EVENT_MASK(APPL_EVT_7))
  406. break;
  407. }
  408. return(0);
  409. }

复制代码

 应用层注册的回调函数被调用:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_sys_event
  4. **
  5. ** Description BTA event handler; called from task event handler.
  6. **
  7. **
  8. ** Returns void
  9. **
  10. *******************************************************************************/
  11. BTA_API void bta_sys_event(BT_HDR *p_msg)
  12. {
  13. UINT8 id;
  14. BOOLEAN freebuf = TRUE;
  15. APPL_TRACE_EVENT("BTA got event 0x%x", p_msg->event); //event = BTA_HH_API_WRITE_DEV_EVT                        
  16. /* get subsystem id from event */
  17. id = (UINT8) (p_msg->event >> 8);
  18. /* verify id and call subsystem event handler */
  19. if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL))
  20. {
  21. freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg); //Id为0x17,即BTA_ID_HH,回调函数为bta_hh_hdl_event,前面已分析
  22.                                    //Id为0x1f,即为BTA_ID_GATTC,回调函数为bta_gattc_hdl_event,继续往后看
  23. }    
  24. else
  25. {
  26. APPL_TRACE_WARNING("BTA got unregistered event id %d", id);
  27. }
  28. if (freebuf)
  29. {
  30. GKI_freebuf(p_msg);
  31. }
  32. }

复制代码

gatt client事件处理函数:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_gattc_hdl_event
  4. **
  5. ** Description GATT client main event handling function.
  6. **
  7. **
  8. ** Returns BOOLEAN
  9. **
  10. *******************************************************************************/
  11. BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
  12. {
  13. tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
  14. tBTA_GATTC_CLCB *p_clcb = NULL;
  15. tBTA_GATTC_RCB *p_clreg;
  16. BOOLEAN rt = TRUE;
  17. #if BTA_GATT_DEBUG == TRUE
  18. APPL_TRACE_DEBUG("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
  19. #endif
  20. switch (p_msg->event)
  21. {
  22. case BTA_GATTC_API_DISABLE_EVT:
  23. bta_gattc_disable(p_cb);
  24. break;
  25. case BTA_GATTC_API_REG_EVT:
  26. bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
  27. break;
  28. case BTA_GATTC_INT_START_IF_EVT:
  29. bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
  30. break;
  31. case BTA_GATTC_API_DEREG_EVT:
  32. p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if);
  33. bta_gattc_deregister(p_cb, p_clreg);
  34. break;
  35. case BTA_GATTC_API_OPEN_EVT:
  36. bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg);
  37. break;
  38. case BTA_GATTC_API_CANCEL_OPEN_EVT:
  39. bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg);
  40. break;
  41. case BTA_GATTC_API_REFRESH_EVT:
  42. bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
  43. break;
  44. #if BLE_INCLUDED == TRUE
  45. case BTA_GATTC_API_LISTEN_EVT:
  46. bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
  47. break;
  48. case BTA_GATTC_API_BROADCAST_EVT:
  49. bta_gattc_broadcast(p_cb, (tBTA_GATTC_DATA *) p_msg);
  50. break;
  51. #endif
  52. case BTA_GATTC_ENC_CMPL_EVT:
  53. bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
  54. break;
  55. default:
  56. if (p_msg->event == BTA_GATTC_INT_CONN_EVT)
  57. p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
  58. else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT)
  59. p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg);
  60. else
  61. p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);
  62. if (p_clcb != NULL)
  63. {
  64. rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg); //事件处理
  65. }
  66. else
  67. {
  68. APPL_TRACE_DEBUG("Ignore unknown conn ID: %d", p_msg->layer_specific);
  69. }
  70. break;
  71. }
  72. return rt;
  73. }

复制代码

gatt client事件处理状态机

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_gattc_sm_execute
  4. **
  5. ** Description State machine event handling function for GATTC
  6. **
  7. **
  8. ** Returns BOOLEAN : TRUE if queued client request buffer can be immediately released
  9. ** else FALSE
  10. **
  11. *******************************************************************************/
  12. BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
  13. {
  14. tBTA_GATTC_ST_TBL state_table;
  15. UINT8 action;
  16. int i;
  17. BOOLEAN rt = TRUE;
  18. #if BTA_GATT_DEBUG == TRUE
  19. tBTA_GATTC_STATE in_state = p_clcb->state;
  20. UINT16 in_event = event;
  21. APPL_TRACE_DEBUG("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
  22. gattc_state_code(in_state),
  23. in_event,
  24. gattc_evt_code(in_event));
  25. #endif
  26. /* look up the state table for the current state */
  27. state_table = bta_gattc_st_tbl[p_clcb->state];
  28. event &= 0x00FF;
  29. /* set next state */
  30. p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE];
  31. /* execute action functions */
  32. for (i = 0; i < BTA_GATTC_ACTIONS; i++)
  33. {
  34. if ((action = state_table[event][i]) != BTA_GATTC_IGNORE)
  35. {
  36. (*bta_gattc_action[action])(p_clcb, p_data); //执行bta_gattc_write,
  37. if (p_clcb->p_q_cmd == p_data) {
  38. /* buffer is queued, don't free in the bta dispatcher.
  39. * we free it ourselves when a completion event is received.
  40. */
  41. rt = FALSE;
  42. }
  43. }
  44. else
  45. {
  46. break;
  47. }
  48. }
  49. #if BTA_GATT_DEBUG == TRUE
  50. if (in_state != p_clcb->state)
  51. {
  52. APPL_TRACE_DEBUG("GATTC [%d] State Change: [%s] -> [%s] after Event [%s]",p_clcb->bta_conn_id,
  53. gattc_state_code(in_state),
  54. gattc_state_code(p_clcb->state),
  55. gattc_evt_code(in_event));
  56. }
  57. #endif
  58. return rt;
  59. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bta_gattc_write
  4. **
  5. ** Description Write an attribute
  6. **
  7. ** Returns None.
  8. **
  9. *******************************************************************************/
  10. void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
  11. {
  12. UINT16 handle = 0;
  13. tGATT_VALUE attr = {0};
  14. tBTA_GATTC_OP_CMPL op_cmpl;
  15. tBTA_GATT_STATUS status = BTA_GATT_OK;
  16. if (bta_gattc_enqueue(p_clcb, p_data))
  17. {
  18. if ((handle = bta_gattc_id2handle(p_clcb->p_srcb,
  19. &p_data->api_write.srvc_id,
  20. &p_data->api_write.char_id,
  21. p_data->api_write.p_descr_type)) == 0)
  22. {
  23. status = BTA_GATT_ERROR;
  24. }
  25. else
  26. {
  27. attr.handle= handle;
  28. attr.offset = p_data->api_write.offset;
  29. attr.len = p_data->api_write.len;
  30. attr.auth_req = p_data->api_write.auth_req;
  31. if (p_data->api_write.p_value)
  32. memcpy(attr.value, p_data->api_write.p_value, p_data->api_write.len);
  33. status = GATTC_Write(p_clcb->bta_conn_id, p_data->api_write.write_type, &attr);
  34. }
  35. /* write fail */
  36. if (status != BTA_GATT_OK)
  37. {
  38. memset(&op_cmpl, 0, sizeof(tBTA_GATTC_OP_CMPL));
  39. op_cmpl.status = status;
  40. op_cmpl.op_code = GATTC_OPTYPE_WRITE;
  41. op_cmpl.p_cmpl = NULL;
  42. bta_gattc_sm_execute(p_clcb, BTA_GATTC_OP_CMPL_EVT, (tBTA_GATTC_DATA *)&op_cmpl);
  43. }
  44. }
  45. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function GATTC_Write
  4. **
  5. ** Description This function is called to write the value of an attribute to
  6. ** the server.
  7. **
  8. ** Parameters conn_id: connection identifier.
  9. ** type - attribute write type.
  10. ** p_write - write operation parameters.
  11. **
  12. ** Returns GATT_SUCCESS if command started successfully.
  13. **
  14. *******************************************************************************/
  15. tGATT_STATUS GATTC_Write (UINT16 conn_id, tGATT_WRITE_TYPE type, tGATT_VALUE *p_write)
  16. {
  17. tGATT_STATUS status = GATT_SUCCESS;
  18. tGATT_CLCB *p_clcb;
  19. tGATT_VALUE *p;
  20. tGATT_IF gatt_if=GATT_GET_GATT_IF(conn_id);
  21. UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id);
  22. tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx);
  23. tGATT_REG *p_reg = gatt_get_regcb(gatt_if);
  24. if ( (p_tcb == NULL) || (p_reg==NULL) || (p_write == NULL) ||
  25. ((type != GATT_WRITE) && (type != GATT_WRITE_PREPARE) && (type != GATT_WRITE_NO_RSP)) )
  26. {
  27. GATT_TRACE_ERROR("GATT_Write Illegal param: conn_id %d, type 0%d,", conn_id, type);
  28. return GATT_ILLEGAL_PARAMETER;
  29. }
  30. if (gatt_is_clcb_allocated(conn_id))
  31. {
  32. GATT_TRACE_ERROR("GATTC_Write GATT_BUSY conn_id = %d", conn_id);
  33. return GATT_BUSY;
  34. }
  35. if ((p_clcb = gatt_clcb_alloc(conn_id)) != NULL )
  36. {
  37. p_clcb->operation = GATTC_OPTYPE_WRITE;
  38. p_clcb->op_subtype = type;
  39. p_clcb->auth_req = p_write->auth_req;
  40. if (( p_clcb->p_attr_buf = (UINT8 *)GKI_getbuf((UINT16)sizeof(tGATT_VALUE))) != NULL)
  41. {
  42. memcpy(p_clcb->p_attr_buf, (void *)p_write, sizeof(tGATT_VALUE));
  43. p = (tGATT_VALUE *)p_clcb->p_attr_buf;
  44. if (type == GATT_WRITE_PREPARE)
  45. {
  46. p_clcb->start_offset = p_write->offset;
  47. p->offset = 0;
  48. }
  49. if (gatt_security_check_start(p_clcb) == FALSE)
  50. {
  51. status = GATT_NO_RESOURCES;
  52. }
  53. }
  54. else
  55. {
  56. status = GATT_NO_RESOURCES;
  57. }
  58. if (status == GATT_NO_RESOURCES)
  59. gatt_clcb_dealloc(p_clcb);
  60. }
  61. else
  62. {
  63. status = GATT_NO_RESOURCES;
  64. }
  65. return status;
  66. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function gatt_check_enc_req
  4. **
  5. ** Description check link security.
  6. **
  7. ** Returns TRUE if encrypted, otherwise FALSE.
  8. **
  9. *******************************************************************************/
  10. BOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb)
  11. {
  12. tGATT_TCB *p_tcb = p_clcb->p_tcb;
  13. tGATT_SEC_ACTION gatt_sec_act;
  14. tBTM_BLE_SEC_ACT btm_ble_sec_act;
  15. BOOLEAN status = TRUE;
  16. tBTM_STATUS btm_status;
  17. tGATT_SEC_ACTION sec_act_old = gatt_get_sec_act(p_tcb);
  18. gatt_sec_act = gatt_determine_sec_act(p_clcb);
  19. if (sec_act_old == GATT_SEC_NONE)
  20. gatt_set_sec_act(p_tcb, gatt_sec_act);
  21. switch (gatt_sec_act )
  22. {
  23. case GATT_SEC_SIGN_DATA:
  24. GATT_TRACE_DEBUG("gatt_security_check_start: Do data signing");
  25. gatt_sign_data(p_clcb);
  26. break;
  27. case GATT_SEC_ENCRYPT:
  28. case GATT_SEC_ENCRYPT_NO_MITM:
  29. case GATT_SEC_ENCRYPT_MITM:
  30. if (sec_act_old < GATT_SEC_ENCRYPT)
  31. {
  32. GATT_TRACE_DEBUG("gatt_security_check_start: Encrypt now or key upgreade first");
  33. gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
  34. btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport , gatt_enc_cmpl_cback, &btm_ble_sec_act);
  35. if ( (btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED))
  36. {
  37. GATT_TRACE_ERROR("gatt_security_check_start BTM_SetEncryption failed btm_status=%d", btm_status);
  38. status = FALSE;
  39. }
  40. }
  41. if (status)
  42. gatt_add_pending_enc_channel_clcb (p_tcb, p_clcb);
  43. break;
  44. case GATT_SEC_ENC_PENDING:
  45. gatt_add_pending_enc_channel_clcb (p_tcb, p_clcb);
  46. /* wait for link encrypotion to finish */
  47. break;
  48. default:
  49. gatt_sec_check_complete(TRUE, p_clcb, gatt_sec_act);
  50. break;
  51. }
  52. if (status == FALSE)
  53. {
  54. gatt_set_sec_act(p_tcb, GATT_SEC_NONE);
  55. gatt_set_ch_state(p_tcb, GATT_CH_OPEN);
  56. }
  57. return status;
  58. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function gatt_sec_check_complete
  4. **
  5. ** Description security check complete and proceed to data sending action.
  6. **
  7. ** Returns void.
  8. **
  9. *******************************************************************************/
  10. void gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB *p_clcb, UINT8 sec_act)
  11. {
  12. if (p_clcb && p_clcb->p_tcb && GKI_queue_is_empty(&p_clcb->p_tcb->pending_enc_clcb))
  13. gatt_set_sec_act(p_clcb->p_tcb, GATT_SEC_NONE);
  14. if (!sec_check_ok)
  15. {
  16. gatt_end_operation(p_clcb, GATT_AUTH_FAIL, NULL);
  17. }
  18. else if (p_clcb->operation == GATTC_OPTYPE_WRITE)
  19. {
  20. gatt_act_write(p_clcb, sec_act);
  21. }
  22. else if (p_clcb->operation == GATTC_OPTYPE_READ)
  23. {
  24. gatt_act_read(p_clcb, p_clcb->counter);
  25. }
  26. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function gatt_act_write
  4. **
  5. ** Description GATT write operation.
  6. **
  7. ** Returns void.
  8. **
  9. *******************************************************************************/
  10. void gatt_act_write (tGATT_CLCB *p_clcb, UINT8 sec_act)
  11. {
  12. tGATT_TCB *p_tcb = p_clcb->p_tcb;
  13. UINT8 rt = GATT_SUCCESS, op_code = 0;
  14. tGATT_VALUE *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf;
  15. if (p_attr)
  16. {
  17. switch (p_clcb->op_subtype)
  18. {
  19. case GATT_WRITE_NO_RSP:
  20. p_clcb->s_handle = p_attr->handle;
  21. op_code = (sec_act == GATT_SEC_SIGN_DATA) ? GATT_SIGN_CMD_WRITE : GATT_CMD_WRITE;
  22. rt = gatt_send_write_msg(p_tcb,
  23. p_clcb->clcb_idx,
  24. op_code,
  25. p_attr->handle,
  26. p_attr->len,
  27. 0,
  28. p_attr->value);
  29. break;
  30. case GATT_WRITE:
  31. if (p_attr->len <= (p_tcb->payload_size - GATT_HDR_SIZE))
  32. {
  33. p_clcb->s_handle = p_attr->handle;
  34. rt = gatt_send_write_msg(p_tcb,
  35. p_clcb->clcb_idx,
  36. GATT_REQ_WRITE,
  37. p_attr->handle,
  38. p_attr->len,
  39. 0,
  40. p_attr->value);
  41. }
  42. else /* prepare write for long attribute */
  43. {
  44. gatt_send_prepare_write(p_tcb, p_clcb);
  45. }
  46. break;
  47. case GATT_WRITE_PREPARE:
  48. gatt_send_prepare_write(p_tcb, p_clcb);
  49. break;
  50. default:
  51. rt = GATT_INTERNAL_ERROR;
  52. GATT_TRACE_ERROR("Unknown write type: %d", p_clcb->op_subtype);
  53. break;
  54. }
  55. }
  56. else
  57. rt = GATT_INTERNAL_ERROR;
  58. if ((rt != GATT_SUCCESS && rt != GATT_CMD_STARTED && rt != GATT_CONGESTED)
  59. || (rt != GATT_CMD_STARTED && p_clcb->op_subtype == GATT_WRITE_NO_RSP))
  60. {
  61. if (rt != GATT_SUCCESS)
  62. {
  63. GATT_TRACE_ERROR("gatt_act_write() failed op_code=0x%x", op_code);
  64. }
  65. gatt_end_operation(p_clcb, rt, NULL);
  66. }
  67. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function gatt_send_write_msg
  4. **
  5. ** Description This real function send out the ATT message for write.
  6. **
  7. ** Returns status code
  8. **
  9. *******************************************************************************/
  10. UINT8 gatt_send_write_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
  11. UINT16 handle, UINT16 len,
  12. UINT16 offset, UINT8 *p_data)
  13. {
  14. tGATT_CL_MSG msg;
  15. msg.attr_value.handle = handle;
  16. msg.attr_value.len = len;
  17. msg.attr_value.offset = offset;
  18. memcpy (msg.attr_value.value, p_data, len);
  19. /* write by handle */
  20. return attp_send_cl_msg(p_tcb, clcb_idx, op_code, &msg);
  21. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function attp_send_cl_msg
  4. **
  5. ** Description This function sends the client request or confirmation message
  6. ** to server.
  7. **
  8. ** Parameter p_tcb: pointer to the connectino control block.
  9. ** clcb_idx: clcb index
  10. ** op_code: message op code.
  11. ** p_msg: pointer to message parameters structure.
  12. **
  13. ** Returns GATT_SUCCESS if sucessfully sent; otherwise error code.
  14. **
  15. **
  16. *******************************************************************************/
  17. tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, tGATT_CL_MSG *p_msg)
  18. {
  19. tGATT_STATUS status = GATT_NO_RESOURCES;
  20. BT_HDR *p_cmd = NULL;
  21. UINT16 offset = 0, handle;
  22. if (p_tcb != NULL)
  23. {
  24. switch (op_code)
  25. {
  26. case GATT_REQ_MTU:
  27. if (p_msg->mtu <= GATT_MAX_MTU_SIZE)
  28. {
  29. p_tcb->payload_size = p_msg->mtu;
  30. p_cmd = attp_build_mtu_cmd(GATT_REQ_MTU, p_msg->mtu);
  31. }
  32. else
  33. status = GATT_ILLEGAL_PARAMETER;
  34. break;
  35. case GATT_REQ_FIND_INFO:
  36. case GATT_REQ_READ_BY_TYPE:
  37. case GATT_REQ_READ_BY_GRP_TYPE:
  38. if (GATT_HANDLE_IS_VALID (p_msg->browse.s_handle) &&
  39. GATT_HANDLE_IS_VALID (p_msg->browse.e_handle) &&
  40. p_msg->browse.s_handle <= p_msg->browse.e_handle)
  41. {
  42. p_cmd = attp_build_browse_cmd(op_code,
  43. p_msg->browse.s_handle,
  44. p_msg->browse.e_handle,
  45. p_msg->browse.uuid);
  46. }
  47. else
  48. status = GATT_ILLEGAL_PARAMETER;
  49. break;
  50. case GATT_REQ_READ_BLOB:
  51. offset = p_msg->read_blob.offset;
  52. /* fall through */
  53. case GATT_REQ_READ:
  54. handle = (op_code == GATT_REQ_READ) ? p_msg->handle: p_msg->read_blob.handle;
  55. /* handle checking */
  56. if (GATT_HANDLE_IS_VALID (handle))
  57. {
  58. p_cmd = attp_build_handle_cmd(op_code, handle, offset);
  59. }
  60. else
  61. status = GATT_ILLEGAL_PARAMETER;
  62. break;
  63. case GATT_HANDLE_VALUE_CONF:
  64. p_cmd = attp_build_opcode_cmd(op_code);
  65. break;
  66. case GATT_REQ_PREPARE_WRITE:
  67. offset = p_msg->attr_value.offset;
  68. /* fall through */
  69. case GATT_REQ_WRITE:
  70. case GATT_CMD_WRITE:
  71. case GATT_SIGN_CMD_WRITE:
  72. if (GATT_HANDLE_IS_VALID (p_msg->attr_value.handle))
  73. {
  74.          //先调用这里
  75. p_cmd = attp_build_value_cmd (p_tcb->payload_size,
  76. op_code, p_msg->attr_value.handle,
  77. offset,
  78. p_msg->attr_value.len,
  79. p_msg->attr_value.value);
  80. }
  81. else
  82. status = GATT_ILLEGAL_PARAMETER;
  83. break;
  84. case GATT_REQ_EXEC_WRITE:
  85. p_cmd = attp_build_exec_write_cmd(op_code, p_msg->exec_write);
  86. break;
  87. case GATT_REQ_FIND_TYPE_VALUE:
  88. p_cmd = attp_build_read_by_type_value_cmd(p_tcb->payload_size, &p_msg->find_type_value);
  89. break;
  90. case GATT_REQ_READ_MULTI:
  91. p_cmd = attp_build_read_multi_cmd(p_tcb->payload_size,
  92. p_msg->read_multi.num_handles,
  93. p_msg->read_multi.handles);
  94. break;
  95. default:
  96. break;
  97. }
  98.      //再调用这里
  99. if (p_cmd != NULL)
  100. status = attp_cl_send_cmd(p_tcb, clcb_idx, op_code, p_cmd);
  101. }
  102. else
  103. {
  104. GATT_TRACE_ERROR("Peer device not connected");
  105. }
  106. return status;
  107. }

复制代码

-->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function attp_build_value_cmd
  4. **
  5. ** Description Build a attribute value request
  6. **
  7. ** Returns None.
  8. **
  9. *******************************************************************************/
  10. BT_HDR *attp_build_value_cmd (UINT16 payload_size, UINT8 op_code, UINT16 handle,
  11. UINT16 offset, UINT16 len, UINT8 *p_data)
  12. {
  13. BT_HDR *p_buf = NULL;
  14. UINT8 *p, *pp, pair_len, *p_pair_len;
  15. if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET))) != NULL)
  16. {
  17. p = pp =(UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
  18. UINT8_TO_STREAM (p, op_code);
  19. p_buf->offset = L2CAP_MIN_OFFSET;
  20. p_buf->len = 1;
  21. if (op_code == GATT_RSP_READ_BY_TYPE)
  22. {
  23. p_pair_len = p;
  24. pair_len = len + 2;
  25. UINT8_TO_STREAM (p, pair_len);
  26. p_buf->len += 1;
  27. }
  28. if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ)
  29. {
  30. UINT16_TO_STREAM (p, handle);
  31. p_buf->len += 2;
  32. }
  33. if (op_code == GATT_REQ_PREPARE_WRITE ||op_code == GATT_RSP_PREPARE_WRITE )
  34. {
  35. UINT16_TO_STREAM (p, offset);
  36. p_buf->len += 2;
  37. }
  38. if (len > 0 && p_data != NULL)
  39. {
  40. /* ensure data not exceed MTU size */
  41. if (payload_size - p_buf->len < len)
  42. {
  43. len = payload_size - p_buf->len;
  44. /* update handle value pair length */
  45. if (op_code == GATT_RSP_READ_BY_TYPE)
  46. *p_pair_len = (len + 2);
  47. GATT_TRACE_WARNING("attribute value too long, to be truncated to %d", len);
  48. }
  49. ARRAY_TO_STREAM (p, p_data, len);
  50. p_buf->len += len;
  51. }
  52. }
  53. return p_buf;
  54. }

复制代码

—>

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function attp_cl_send_cmd
  4. **
  5. ** Description Send a ATT command or enqueue it.
  6. **
  7. ** Returns GATT_SUCCESS if command sent
  8. ** GATT_CONGESTED if command sent but channel congested
  9. ** GATT_CMD_STARTED if command queue up in GATT
  10. ** GATT_ERROR if command sending failure
  11. **
  12. *******************************************************************************/
  13. tGATT_STATUS attp_cl_send_cmd(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 cmd_code, BT_HDR *p_cmd)
  14. {
  15. tGATT_STATUS att_ret = GATT_SUCCESS;
  16. if (p_tcb != NULL)
  17. {
  18. cmd_code &= ~GATT_AUTH_SIGN_MASK;
  19. /* no pending request or value confirmation */
  20. if (p_tcb->pending_cl_req == p_tcb->next_slot_inq ||
  21. cmd_code == GATT_HANDLE_VALUE_CONF)
  22. {
  23. att_ret = attp_send_msg_to_l2cap(p_tcb, p_cmd); //发送数据到l2cap层
  24. if (att_ret == GATT_CONGESTED || att_ret == GATT_SUCCESS)
  25. {
  26. /* do not enq cmd if handle value confirmation or set request */
  27. if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE)
  28. {
  29. gatt_start_rsp_timer (clcb_idx); //如果是write request数据类型,则会创建定时器等待respond(5s超时)
  30. gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL);
  31. }
  32. }
  33. else
  34. att_ret = GATT_INTERNAL_ERROR;
  35. }
  36. else
  37. {
  38. att_ret = GATT_CMD_STARTED;
  39. gatt_cmd_enq(p_tcb, clcb_idx, TRUE, cmd_code, p_cmd);
  40. }
  41. }
  42. else
  43. att_ret = GATT_ERROR;
  44. return att_ret;
  45. }

复制代码

->

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function attp_send_msg_to_l2cap
  4. **
  5. ** Description Send message to L2CAP.
  6. **
  7. *******************************************************************************/
  8. tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB *p_tcb, BT_HDR *p_toL2CAP)
  9. {
  10. UINT16 l2cap_ret;
  11. if (p_tcb->att_lcid == L2CAP_ATT_CID)
  12. l2cap_ret = L2CA_SendFixedChnlData (L2CAP_ATT_CID, p_tcb->peer_bda, p_toL2CAP);
  13. else
  14. l2cap_ret = (UINT16) L2CA_DataWrite (p_tcb->att_lcid, p_toL2CAP);
  15. if (l2cap_ret == L2CAP_DW_FAILED)
  16. {
  17. GATT_TRACE_ERROR("ATT failed to pass msg:0x%0x to L2CAP",
  18. *((UINT8 *)(p_toL2CAP + 1) + p_toL2CAP->offset));
  19. return GATT_INTERNAL_ERROR;
  20. }
  21. else if (l2cap_ret == L2CAP_DW_CONGESTED)
  22. {
  23. GATT_TRACE_DEBUG("ATT congested, message accepted");
  24. return GATT_CONGESTED;
  25. }
  26. return GATT_SUCCESS;
  27. }

复制代码

->

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function L2CA_SendFixedChnlData
  4. **
  5. ** Description Write data on a fixed channel.
  6. **
  7. ** Parameters: Fixed CID
  8. ** BD Address of remote
  9. ** Pointer to buffer of type BT_HDR
  10. **
  11. ** Return value L2CAP_DW_SUCCESS, if data accepted
  12. ** L2CAP_DW_FAILED, if error
  13. **
  14. *******************************************************************************/
  15. UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
  16. {
  17. tL2C_LCB *p_lcb;
  18. tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
  19. L2CAP_TRACE_API ("L2CA_SendFixedChnlData() CID: 0x%04x BDA: %08x%04x", fixed_cid,
  20. (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
  21. #if BLE_INCLUDED == TRUE
  22. if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
  23. transport = BT_TRANSPORT_LE;
  24. #endif
  25. /* Check CID is valid and registered */
  26. if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
  27. || (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
  28. {
  29. L2CAP_TRACE_ERROR ("L2CA_SendFixedChnlData() Invalid CID: 0x%04x", fixed_cid);
  30. GKI_freebuf (p_buf);
  31. return (L2CAP_DW_FAILED);
  32. }
  33. /* Fail if BT is not yet up */
  34. if (!BTM_IsDeviceUp())
  35. {
  36. L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData(0x%04x) - BTU not ready", fixed_cid);
  37. GKI_freebuf (p_buf);
  38. return (L2CAP_DW_FAILED);
  39. }
  40. /* We need to have a link up */
  41. if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) == NULL ||
  42. /* if link is disconnecting, also report data sending failure */
  43. p_lcb->link_state == LST_DISCONNECTING)
  44. {
  45. L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
  46. GKI_freebuf (p_buf);
  47. return (L2CAP_DW_FAILED);
  48. }
  49. if ((p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)) == 0)
  50. {
  51. L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData() - peer does not support fixed chnl: 0x%04x", fixed_cid);
  52. GKI_freebuf (p_buf);
  53. return (L2CAP_DW_FAILED);
  54. }
  55. p_buf->event = 0;
  56. p_buf->layer_specific = L2CAP_FLUSHABLE_CH_BASED;
  57. if (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL])
  58. {
  59. if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
  60. {
  61. L2CAP_TRACE_WARNING ("L2CA_SendFixedChnlData() - no CCB for chnl: 0x%4x", fixed_cid);
  62. GKI_freebuf (p_buf);
  63. return (L2CAP_DW_FAILED);
  64. }
  65. }
  66. /* If already congested, do not accept any more packets */
  67. if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent)
  68. {
  69. L2CAP_TRACE_ERROR ("L2CAP - CID: 0x%04x cannot send, already congested \
  70. xmit_hold_q.count: %u buff_quota: %u", fixed_cid,
  71. p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->xmit_hold_q.count,
  72. p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota);
  73. GKI_freebuf (p_buf);
  74. return (L2CAP_DW_FAILED);
  75. }
  76. l2c_enqueue_peer_data (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL], p_buf);
  77. l2c_link_check_send_pkts (p_lcb, NULL, NULL);
  78. /* If there is no dynamic CCB on the link, restart the idle timer each time something is sent */
  79. if (p_lcb->in_use && p_lcb->link_state == LST_CONNECTED && !p_lcb->ccb_queue.p_first_ccb)
  80. {
  81. l2cu_no_dynamic_ccbs (p_lcb);
  82. }
  83. if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent)
  84. return (L2CAP_DW_CONGESTED);
  85. return (L2CAP_DW_SUCCESS);
  86. }

复制代码

调用 l2c_enqueue_peer_data 让数据进入到当前 ccb 的 xmit_hold_q 队列中,暂存此数据包。

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function l2c_enqueue_peer_data
  4. **
  5. ** Description Enqueues data destined for the peer in the ccb. Handles
  6. ** FCR segmentation and checks for congestion.
  7. **
  8. ** Returns void
  9. **
  10. *******************************************************************************/
  11. void l2c_enqueue_peer_data (tL2C_CCB *p_ccb, BT_HDR *p_buf)
  12. {
  13. UINT8 *p;
  14. if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
  15. {
  16. p_buf->event = 0;
  17. }
  18. else
  19. {
  20. /* Save the channel ID for faster counting */
  21. p_buf->event = p_ccb->local_cid;
  22. /* Step back to add the L2CAP header */
  23. p_buf->offset -= L2CAP_PKT_OVERHEAD;
  24. p_buf->len += L2CAP_PKT_OVERHEAD;
  25. /* Set the pointer to the beginning of the data */
  26. p = (UINT8 *)(p_buf + 1) + p_buf->offset;
  27. /* Now the L2CAP header */
  28. UINT16_TO_STREAM (p, p_buf->len - L2CAP_PKT_OVERHEAD);
  29. UINT16_TO_STREAM (p, p_ccb->remote_cid);
  30. }
  31. GKI_enqueue (&p_ccb->xmit_hold_q, p_buf);
  32. l2cu_check_channel_congestion (p_ccb);  //检测当前 Channel 拥堵情况
  33. #if (L2CAP_ROUND_ROBIN_CHANNEL_SERVICE == TRUE)
  34. /* if new packet is higher priority than serving ccb and it is not overrun */
  35. if (( p_ccb->p_lcb->rr_pri > p_ccb->ccb_priority )
  36. &&( p_ccb->p_lcb->rr_serv[p_ccb->ccb_priority].quota > 0))
  37. {
  38. /* send out higher priority packet */
  39. p_ccb->p_lcb->rr_pri = p_ccb->ccb_priority;
  40. }
  41. #endif
  42. /* if we are doing a round robin scheduling, set the flag */
  43. if (p_ccb->p_lcb->link_xmit_quota == 0)
  44. l2cb.check_round_robin = TRUE;
  45. }

复制代码

-->

复制代码

  1. /******************************************************************************
  2. **
  3. ** Function l2cu_check_channel_congestion
  4. **
  5. ** Description check if any change in congestion status
  6. **
  7. ** Returns None
  8. **
  9. *******************************************************************************/
  10. void l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
  11. {
  12. UINT16 q_count = GKI_queue_length(&p_ccb->xmit_hold_q);
  13. #if (L2CAP_UCD_INCLUDED == TRUE)
  14. if ( p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
  15. {
  16. q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
  17. }
  18. #endif
  19. /* If the CCB queue limit is subject to a quota, check for congestion */
  20. /* if this channel has outgoing traffic */
  21. if (p_ccb->buff_quota != 0)
  22. {
  23. /* If this channel was congested */
  24. if ( p_ccb->cong_sent )
  25. {
  26. /* If the channel is not congested now, tell the app */
  27.         //在函数 l2c_link_adjust_chnl_allocation 中配置此值
  28.         //p_ccb->buff_quota = quota_per_weighted_chnls[p_ccb->ertm_info.user_tx_pool_id] * p_ccb->tx_data_rate;
  29. if (q_count <= (p_ccb->buff_quota / 2)) //当前CCB中的 xmit_hold_q 小于 buffer_quota 值的一半,即认为已经不拥堵
  30. {
  31. p_ccb->cong_sent = FALSE;
  32. if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
  33. {
  34. L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (FALSE), CID: 0x%04x xmit_hold_q.count: %u buff_quota: %u",
  35. p_ccb->local_cid, q_count, p_ccb->buff_quota);
  36. /* Prevent recursive calling */
  37. l2cb.is_cong_cback_context = TRUE;
  38. (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, FALSE);
  39. l2cb.is_cong_cback_context = FALSE;
  40. }
  41. #if (L2CAP_UCD_INCLUDED == TRUE)
  42. else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
  43. {
  44. if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
  45. {
  46. L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (FALSE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
  47. p_ccb->p_lcb->ucd_out_sec_pending_q.count,
  48. p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
  49. p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, FALSE );
  50. }
  51. }
  52. #endif
  53. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  54. else
  55. {
  56. UINT8 xx;
  57. for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
  58. {
  59. if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
  60. {
  61. if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
  62. (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, FALSE);
  63. break;
  64. }
  65. }
  66. }
  67. #endif
  68. }
  69. }
  70. else
  71. {
  72. /* If this channel was not congested but it is congested now, tell the app */
  73. if (q_count > p_ccb->buff_quota)
  74. {
  75. p_ccb->cong_sent = TRUE;
  76. if (p_ccb->p_rcb && p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)
  77. {
  78. L2CAP_TRACE_DEBUG ("L2CAP - Calling CongestionStatus_Cb (TRUE),CID:0x%04x,XmitQ:%u,Quota:%u",
  79. p_ccb->local_cid, q_count, p_ccb->buff_quota);
  80. (*p_ccb->p_rcb->api.pL2CA_CongestionStatus_Cb)(p_ccb->local_cid, TRUE);
  81. }
  82. #if (L2CAP_UCD_INCLUDED == TRUE)
  83. else if ( p_ccb->p_rcb && p_ccb->local_cid == L2CAP_CONNECTIONLESS_CID )
  84. {
  85. if ( p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb )
  86. {
  87. L2CAP_TRACE_DEBUG ("L2CAP - Calling UCD CongestionStatus_Cb (TRUE), SecPendingQ:%u,XmitQ:%u,Quota:%u",
  88. p_ccb->p_lcb->ucd_out_sec_pending_q.count,
  89. p_ccb->xmit_hold_q.count, p_ccb->buff_quota);
  90. p_ccb->p_rcb->ucd.cb_info.pL2CA_UCD_Congestion_Status_Cb( p_ccb->p_lcb->remote_bd_addr, TRUE );
  91. }
  92. }
  93. #endif
  94. #if (L2CAP_NUM_FIXED_CHNLS > 0)
  95. else
  96. {
  97. UINT8 xx;
  98. for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx ++)
  99. {
  100. if (p_ccb->p_lcb->p_fixed_ccbs[xx] == p_ccb)
  101. {
  102. if (l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb != NULL)
  103. (* l2cb.fixed_reg[xx].pL2CA_FixedCong_Cb)(p_ccb->p_lcb->remote_bd_addr, TRUE);
  104. break;
  105. }
  106. }
  107. }
  108. #endif
  109. }
  110. }
  111. }
  112. }

复制代码

 

L2CAP层是通过 l2c_link_check_send_pkts 这个函数发送数据包:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function l2c_link_check_send_pkts
  4. **
  5. ** Description This function is called to check if it can send packets
  6. ** to the Host Controller. It may be passed the address of
  7. ** a packet to send.
  8. **
  9. ** Returns void
  10. **
  11. *******************************************************************************/
  12. void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
  13. {
  14. int xx;
  15. BOOLEAN single_write = FALSE; //最后 Link Disc 用来把 CCB 中的数据包放到 Link 上的队列发,速度加快
  16. /* Save the channel ID for faster counting */
  17. if (p_buf)//一般数据包都为空,只有发送 L2CAP 发送 command/response 或 发送 S-Frame 才用到
  18. {
  19. if (p_ccb != NULL) //这个 case 就是 当前 Link 即将断开的情况了
  20. {
  21. p_buf->event = p_ccb->local_cid;
  22. single_write = TRUE;
  23. }
  24. else
  25. p_buf->event = 0;
  26. p_buf->layer_specific = 0;
  27. //把这个数据包放到 当前 link 上的 link_xmit_data_q队列中
  28. GKI_enqueue (&p_lcb->link_xmit_data_q, p_buf);
  29. //没有发送窗口了,需要 RR 看看有没有别的数据包可以发
  30. if (p_lcb->link_xmit_quota == 0)
  31. {
  32. #if BLE_INCLUDED == TRUE
  33. if (p_lcb->transport == BT_TRANSPORT_LE)
  34. l2cb.ble_check_round_robin = TRUE;
  35. else
  36. #endif
  37. l2cb.check_round_robin = TRUE;
  38. }
  39. }
  40. /* If this is called from uncongested callback context break recursive calling.
  41. ** This LCB will be served when receiving number of completed packet event.
  42. */
  43. if (l2cb.is_cong_cback_context)//当前 Link 拥堵了,不发送数据包直接返回
  44. return;
  45. /* If we are in a scenario where there are not enough buffers for each link to
  46. ** have at least 1, then do a round-robin for all the LCBs
  47. */
  48. if ( (p_lcb == NULL) || (p_lcb->link_xmit_quota == 0) )
  49. {
  50. if (p_lcb == NULL)
  51. p_lcb = l2cb.lcb_pool;
  52. else if (!single_write)
  53. p_lcb++;
  54. /* Loop through, starting at the next */
  55. //没有足够buffer发送窗口了,在所有的 Link 上做一次 RR
  56. for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
  57. {
  58. /* If controller window is full, nothing to do */
  59. if ( (l2cb.controller_xmit_window == 0
  60. #if (BLE_INCLUDED == TRUE)
  61. && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
  62. #endif
  63. )
  64. #if (BLE_INCLUDED == TRUE)
  65. || (p_lcb->transport == BT_TRANSPORT_LE && l2cb.controller_le_xmit_window == 0 )
  66. #endif
  67. || (l2cb.round_robin_unacked >= l2cb.round_robin_quota) )
  68. break;
  69. /* Check for wraparound */
  70. if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS])
  71. p_lcb = &l2cb.lcb_pool[0];
  72. if ( (!p_lcb->in_use)
  73. || (p_lcb->partial_segment_being_sent)
  74. || (p_lcb->link_state != LST_CONNECTED)
  75. || (p_lcb->link_xmit_quota != 0)
  76. || (L2C_LINK_CHECK_POWER_MODE (p_lcb)) )
  77. continue;
  78. /* See if we can send anything from the Link Queue */
  79. //首先从当前 Link 上的 link_xmit_data_q 中取出数据包并发送
  80. if ((p_buf = (BT_HDR *)GKI_dequeue (&p_lcb->link_xmit_data_q)) != NULL)
  81. {
  82. l2c_link_send_to_lower (p_lcb, p_buf);
  83. }
  84. else if (single_write)//如果是 single_write 设置为 TRUE,说明数据包 已经在 link_xmit_data_q 发送了,没必要在执行下面的 code 了
  85. {
  86. /* If only doing one write, break out */
  87. break;
  88. }
  89. /* If nothing on the link queue, check the channel queue */
  90. //Link 上的 Queue 中没有东西可以发送,查找 CCB 中的 Queue,直到找到一个为止。
  91. else if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) != NULL)
  92. {
  93. l2c_link_send_to_lower (p_lcb, p_buf);
  94. }
  95. }
  96. /* If we finished without using up our quota, no need for a safety check */
  97. if ( (l2cb.controller_xmit_window > 0)
  98. && (l2cb.round_robin_unacked < l2cb.round_robin_quota)
  99. #if (BLE_INCLUDED == TRUE)
  100. && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
  101. #endif
  102. )
  103. l2cb.check_round_robin = FALSE;
  104. #if (BLE_INCLUDED == TRUE)
  105. if ( (l2cb.controller_le_xmit_window > 0)
  106. && (l2cb.ble_round_robin_unacked < l2cb.ble_round_robin_quota)
  107. && (p_lcb->transport == BT_TRANSPORT_LE))
  108. l2cb.ble_check_round_robin = FALSE;
  109. #endif
  110. }
  111. else /* if this is not round-robin service */
  112. {
  113. /* If a partial segment is being sent, can't send anything else */
  114. if ( (p_lcb->partial_segment_being_sent)
  115. || (p_lcb->link_state != LST_CONNECTED)
  116. || (L2C_LINK_CHECK_POWER_MODE (p_lcb)) )
  117. return;
  118. /* See if we can send anything from the link queue */
  119. #if (BLE_INCLUDED == TRUE)
  120. while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
  121. (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
  122. && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
  123. #else
  124. while ( (l2cb.controller_xmit_window != 0)
  125. && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
  126. #endif
  127. {
  128. if ((p_buf = (BT_HDR *)GKI_dequeue (&p_lcb->link_xmit_data_q)) == NULL)
  129. break;
  130. if (!l2c_link_send_to_lower (p_lcb, p_buf))
  131. break;
  132. }
  133. if (!single_write)//确保不是在链路 disc 状态下
  134. {
  135. /* See if we can send anything for any channel */
  136. #if (BLE_INCLUDED == TRUE)
  137. while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
  138. (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
  139. && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
  140. #else
  141. while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
  142. #endif
  143. {
  144. if ((p_buf = l2cu_get_next_buffer_to_send (p_lcb)) == NULL)//找到一个数据包来发送
  145. break;
  146. if (!l2c_link_send_to_lower (p_lcb, p_buf))
  147. break;
  148. }
  149. }
  150. /* There is a special case where we have readjusted the link quotas and */
  151. /* this link may have sent anything but some other link sent packets so */
  152. /* so we may need a timer to kick off this link's transmissions. */
  153. if ( (p_lcb->link_xmit_data_q.count) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota) )
  154. btu_start_timer (&p_lcb->timer_entry, BTU_TTYPE_L2CAP_LINK, L2CAP_LINK_FLOW_CONTROL_TOUT);
  155. }
  156. }

复制代码

最终 l2c_link_check_send_pkts 把数据包交给了 l2c_link_send_to_lower 来做处理,我们的音乐数据包最终也被从某个 CCB 中的队列出队列给了 l2c_link_send_to_lower。l2c_link_send_to_lower 主要做了这些事情:

  1. 如果当前数据包 p_buf 的长度小于 ACL 包的最大值,sent_not_acked 加1,整个 L2CAP 的 controller_xmit_window 减1。然后通过 L2C_LINK_SEND_ACL_DATA 将此数据包发送出去。
  2. 如果当前数据包 p_buf 的长度大于 ACL 包的最大值,先看看能分成几个分包(为了求的几个窗口能容下),然后窗口值减掉这些分包个数,然后将整个数据包交给 L2C_LINK_SEND_ACL_DATA (大于ACL包长度),具体分包发送由 H5(串口) 部分来负责。

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function l2c_link_send_to_lower
  4. **
  5. ** Description This function queues the buffer for HCI transmission
  6. **
  7. ** Returns TRUE for success, FALSE for fail
  8. **
  9. *******************************************************************************/
  10. static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
  11. {
  12. UINT16 num_segs;
  13. UINT16 xmit_window, acl_data_size;
  14. if ((p_buf->len <= btu_cb.hcit_acl_pkt_size
  15. #if (BLE_INCLUDED == TRUE)
  16. && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
  17. ((p_lcb->transport == BT_TRANSPORT_LE) && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size))
  18. #else
  19. )
  20. #endif
  21. )
  22. {
  23. if (p_lcb->link_xmit_quota == 0)
  24. {
  25. #if (BLE_INCLUDED == TRUE)
  26. if (p_lcb->transport == BT_TRANSPORT_LE)
  27. l2cb.ble_round_robin_unacked++;
  28. else
  29. #endif
  30. l2cb.round_robin_unacked++;
  31. }
  32. p_lcb->sent_not_acked++;
  33. p_buf->layer_specific = 0;
  34. #if (BLE_INCLUDED == TRUE)
  35. if (p_lcb->transport == BT_TRANSPORT_LE)
  36. {
  37. l2cb.controller_le_xmit_window--;
  38. L2C_LINK_SEND_BLE_ACL_DATA (p_buf);
  39. }
  40. else
  41. #endif
  42. {
  43. l2cb.controller_xmit_window--;
  44. L2C_LINK_SEND_ACL_DATA (p_buf);
  45. }
  46. }
  47. else
  48. {
  49. #if BLE_INCLUDED == TRUE
  50. if (p_lcb->transport == BT_TRANSPORT_LE)
  51. {
  52. acl_data_size = btu_cb.hcit_ble_acl_data_size;
  53. xmit_window = l2cb.controller_le_xmit_window;
  54. }
  55. else
  56. #endif
  57. {
  58. acl_data_size = btu_cb.hcit_acl_data_size;
  59. xmit_window = l2cb.controller_xmit_window;
  60. }
  61. num_segs = (p_buf->len - HCI_DATA_PREAMBLE_SIZE + acl_data_size - 1) / acl_data_size;
  62. /* If doing round-robin, then only 1 segment each time */
  63. if (p_lcb->link_xmit_quota == 0)
  64. {
  65. num_segs = 1;
  66. p_lcb->partial_segment_being_sent = TRUE;
  67. }
  68. else
  69. {
  70. /* Multi-segment packet. Make sure it can fit */
  71. if (num_segs > xmit_window)
  72. {
  73. num_segs = xmit_window;
  74. p_lcb->partial_segment_being_sent = TRUE;
  75. }
  76. if (num_segs > (p_lcb->link_xmit_quota - p_lcb->sent_not_acked))
  77. {
  78. num_segs = (p_lcb->link_xmit_quota - p_lcb->sent_not_acked);
  79. p_lcb->partial_segment_being_sent = TRUE;
  80. }
  81. }
  82. p_buf->layer_specific = num_segs;
  83. #if BLE_INCLUDED == TRUE
  84. if (p_lcb->transport == BT_TRANSPORT_LE)
  85. {
  86. l2cb.controller_le_xmit_window -= num_segs;
  87. if (p_lcb->link_xmit_quota == 0)
  88. l2cb.ble_round_robin_unacked += num_segs;
  89. }
  90. else
  91. #endif
  92. {
  93. l2cb.controller_xmit_window -= num_segs;
  94. if (p_lcb->link_xmit_quota == 0)
  95. l2cb.round_robin_unacked += num_segs;
  96. }
  97. p_lcb->sent_not_acked += num_segs;
  98. #if BLE_INCLUDED == TRUE
  99. if (p_lcb->transport == BT_TRANSPORT_LE)
  100. {
  101. L2C_LINK_SEND_BLE_ACL_DATA(p_buf);
  102. }
  103. else
  104. #endif
  105. {
  106. L2C_LINK_SEND_ACL_DATA (p_buf);
  107. }
  108. }
  109. #if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE)
  110. #if (BLE_INCLUDED == TRUE)
  111. if (p_lcb->transport == BT_TRANSPORT_LE)
  112. {
  113. L2CAP_TRACE_DEBUG ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
  114. l2cb.controller_le_xmit_window,
  115. p_lcb->handle,
  116. p_lcb->link_xmit_quota, p_lcb->sent_not_acked,
  117. l2cb.ble_round_robin_quota, l2cb.ble_round_robin_unacked);
  118. }
  119. else
  120. #endif
  121. {
  122. L2CAP_TRACE_DEBUG ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
  123. l2cb.controller_xmit_window,
  124. p_lcb->handle,
  125. p_lcb->link_xmit_quota, p_lcb->sent_not_acked,
  126. l2cb.round_robin_quota, l2cb.round_robin_unacked);
  127. }
  128. #endif
  129. return TRUE;
  130. }

复制代码

l2c_link_send_to_lower 把数据交给了 L2C_LINK_SEND_ACL_DATA,L2C_LINK_SEND_ACL_DATA 其实是 bte_main_hci_send 函数,bte_main_hci_send 函数通过调用 hci 的接口 transmit_buf 来转送数据包。transmit_buf 函数作用比较简单,将此数据包入 tx_q 队列,串口(H5)的守护线程 bt_hc_worker_thread 会从 tx_q 队列中获取数据包,并将其发送。

复制代码

  1. /******************************************************************************
  2. **
  3. ** Function bte_main_hci_send
  4. **
  5. ** Description BTE MAIN API - This function is called by the upper stack to
  6. ** send an HCI message. The function displays a protocol trace
  7. ** message (if enabled), and then calls the 'transmit' function
  8. ** associated with the currently selected HCI transport
  9. **
  10. ** Returns None
  11. **
  12. ******************************************************************************/
  13. void bte_main_hci_send (BT_HDR *p_msg, UINT16 event)
  14. {
  15. UINT16 sub_event = event & BT_SUB_EVT_MASK; /* local controller ID */
  16. p_msg->event = event;
  17. OS_PRINTF("bte_main_hci_send event 0x%2x\n",event);
  18. if((sub_event == LOCAL_BR_EDR_CONTROLLER_ID) || \
  19. (sub_event == LOCAL_BLE_CONTROLLER_ID))
  20. {
  21. if (bt_hc_if)
  22. bt_hc_if->transmit_buf((TRANSAC)p_msg, \
  23. (char *) (p_msg + 1), \
  24. p_msg->len);
  25. else
  26. GKI_freebuf(p_msg);
  27. }
  28. else
  29. {
  30. APPL_TRACE_ERROR("Invalid Controller ID. Discarding message.");
  31. GKI_freebuf(p_msg);
  32. }
  33. }

复制代码

在hci中,数据被写入bt driver中

复制代码

  1. static int transmit_buf(TRANSAC transac, char *p_buf, int len)
  2. {
  3. utils_enqueue(&tx_q, (void *) transac);
  4. bthc_signal_event(HC_EVENT_TX);
  5. return BT_HC_STATUS_SUCCESS;
  6. }

复制代码

external\bluetooth\bluedroid\hci\src\bt_hci_bdroid.c

bt_hc_worker_thread负责处理hci事件

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function bt_hc_worker_thread
  4. **
  5. ** Description Mian worker thread
  6. **
  7. ** Returns void *
  8. **
  9. *******************************************************************************/
  10. static void *bt_hc_worker_thread(void *arg)
  11. {
  12. uint16_t events;
  13. HC_BT_HDR *p_msg, *p_next_msg;
  14. ALOGI("bt_hc_worker_thread started");
  15. prctl(PR_SET_NAME, (unsigned long)"bt_hc_worker", 0, 0, 0);
  16. tx_cmd_pkts_pending = FALSE;
  17. raise_priority_a2dp(TASK_HIGH_HCI_WORKER);
  18. while (lib_running)
  19. {
  20. pthread_mutex_lock(&hc_cb.mutex);
  21. while (ready_events == 0)
  22. {
  23. pthread_cond_wait(&hc_cb.cond, &hc_cb.mutex);
  24. }
  25. events = ready_events;
  26. ready_events = 0;
  27. pthread_mutex_unlock(&hc_cb.mutex);
  28. #ifndef HCI_USE_MCT
  29. if (events & HC_EVENT_RX)
  30. {
  31. p_hci_if->rcv();
  32. if ((tx_cmd_pkts_pending == TRUE) && (num_hci_cmd_pkts > 0))
  33. {
  34. /* Got HCI Cmd Credits from Controller.
  35. * Prepare to send prior pending Cmd packets in the
  36. * following HC_EVENT_TX session.
  37. */
  38. events |= HC_EVENT_TX;
  39. }
  40. }
  41. #endif
  42. if (events & HC_EVENT_PRELOAD)
  43. {
  44. userial_open(USERIAL_PORT_1);
  45. /* Calling vendor-specific part */
  46. if (bt_vnd_if)
  47. {
  48. bt_vnd_if->op(BT_VND_OP_FW_CFG, NULL);
  49. }
  50. else
  51. {
  52. if (bt_hc_cbacks)
  53. bt_hc_cbacks->preload_cb(NULL, BT_HC_PRELOAD_FAIL);
  54. }
  55. }
  56. if (events & HC_EVENT_POSTLOAD)
  57. {
  58. /* Start from SCO related H/W configuration, if SCO configuration
  59. * is required. Then, follow with reading requests of getting
  60. * ACL data length for both BR/EDR and LE.
  61. */
  62. int result = -1;
  63. /* Calling vendor-specific part */
  64. if (bt_vnd_if)
  65. result = bt_vnd_if->op(BT_VND_OP_SCO_CFG, NULL);
  66. if (result == -1)
  67. p_hci_if->get_acl_max_len();
  68. }
  69. if (events & HC_EVENT_TX)
  70. {
  71. /*
  72. * We will go through every packets in the tx queue.
  73. * Fine to clear tx_cmd_pkts_pending.
  74. */
  75. tx_cmd_pkts_pending = FALSE;
  76. HC_BT_HDR * sending_msg_que[64];
  77. int sending_msg_count = 0;
  78. int sending_hci_cmd_pkts_count = 0;
  79. utils_lock();
  80. p_next_msg = tx_q.p_first;
  81. while (p_next_msg && sending_msg_count <
  82. (int)sizeof(sending_msg_que)/sizeof(sending_msg_que[0]))
  83. {
  84. if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD)
  85. {
  86. /*
  87. * if we have used up controller's outstanding HCI command
  88. * credits (normally is 1), skip all HCI command packets in
  89. * the queue.
  90. * The pending command packets will be sent once controller
  91. * gives back us credits through CommandCompleteEvent or
  92. * CommandStatusEvent.
  93. */
  94. if ((tx_cmd_pkts_pending == TRUE) ||
  95. (sending_hci_cmd_pkts_count >= num_hci_cmd_pkts))
  96. {
  97. tx_cmd_pkts_pending = TRUE;
  98. p_next_msg = utils_getnext(p_next_msg);
  99. continue;
  100. }
  101. sending_hci_cmd_pkts_count++;
  102. }
  103. p_msg = p_next_msg;
  104. p_next_msg = utils_getnext(p_msg);
  105. utils_remove_from_queue_unlocked(&tx_q, p_msg);
  106. sending_msg_que[sending_msg_count++] = p_msg;
  107. }
  108. utils_unlock();
  109. int i;
  110. for(i = 0; i < sending_msg_count; i++)
  111. p_hci_if->send(sending_msg_que[i]);
  112. if (tx_cmd_pkts_pending == TRUE)
  113. BTHCDBG("Used up Tx Cmd credits");
  114. }
  115. if (events & HC_EVENT_LPM_ENABLE)
  116. {
  117. lpm_enable(TRUE);
  118. }
  119. if (events & HC_EVENT_LPM_DISABLE)
  120. {
  121. lpm_enable(FALSE);
  122. }
  123. if (events & HC_EVENT_LPM_IDLE_TIMEOUT)
  124. {
  125. lpm_wake_deassert();
  126. }
  127. if (events & HC_EVENT_LPM_ALLOW_SLEEP)
  128. {
  129. lpm_allow_bt_device_sleep();
  130. }
  131. if (events & HC_EVENT_LPM_WAKE_DEVICE)
  132. {
  133. lpm_wake_assert();
  134. }
  135. if (events & HC_EVENT_EPILOG)
  136. {
  137. /* Calling vendor-specific part */
  138. if (bt_vnd_if)
  139. bt_vnd_if->op(BT_VND_OP_EPILOG, NULL);
  140. else
  141. break; // equivalent to HC_EVENT_EXIT
  142. }
  143. if (events & HC_EVENT_EXIT)
  144. break;
  145. }
  146. ALOGI("bt_hc_worker_thread exiting");
  147. lib_running = 0;
  148. pthread_exit(NULL);
  149. return NULL; // compiler friendly
  150. }

复制代码

send to : userial.c

最终write 系统调操作driver的 fops 操作接口集:

复制代码

  1. /*******************************************************************************
  2. **
  3. ** Function userial_write
  4. **
  5. ** Description Write data to the userial port
  6. **
  7. ** Returns Number of bytes actually written to the userial port. This
  8. ** may be less than len.
  9. **
  10. *******************************************************************************/
  11. uint16_t userial_write(uint16_t msg_id, uint8_t *p_data, uint16_t len)
  12. {
  13. int ret, total = 0;
  14. while(len != 0)
  15. {
  16. #if defined(ENABLE_USERIAL_TIMING_LOGS) && (ENABLE_USERIAL_TIMING_LOGS==TRUE)
  17. log_userial_tx_timing(len);
  18. #endif
  19. ret = write(userial_cb.fd, p_data+total, len);
  20. total += ret;
  21. len -= ret;
  22. }
  23. return ((uint16_t)total);
  24. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/820345
推荐阅读
相关标签
  

闽ICP备14008679号