控制器数据数据到btu_hci_msg_process调用流程

在蓝牙使能后enable 过程中  调用 hal_open函数(system\bt\hci\src\hci_hal_mct.c)

  event_stream = hci_reader_new(uart_fds[CH_EVT], HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX,
                                                 thread, event_event_stream_has_bytes);
  if (!event_stream) {
    LOG_ERROR("%s unable to create hci reader for the event uart serial port.", __func__);
    goto error;
  }

  acl_stream = hci_reader_new(uart_fds[CH_ACL_IN], HCI_HAL_SERIAL_BUFFER_SIZE, SIZE_MAX,
                                                    thread, event_acl_stream_has_bytes);
  if (!acl_stream) {
    LOG_ERROR("%s unable to create hci reader for the acl-in uart serial port.", __func__);
    goto error;
  }

当SCO链路层有数据event_event_stream_has_bytes函数会被执行:

static void event_event_stream_has_bytes(void *context) {
  int bytes_read;
  hci_reader_t *reader = (hci_reader_t *) context;
  bytes_read = read(reader->inbound_fd, reader->data_buffer+reader->wr_ptr,
                                    reader->buffer_size - reader->wr_ptr);
  if (bytes_read <= 0) {
    LOG_ERROR("%s could not read HCI message type", __func__);
    return;
  }
  reader->wr_ptr += bytes_read;
  callbacks->data_ready(DATA_TYPE_EVENT);
}

当ACL链路层有数据 event_acl_stream_has_bytes函数会被调用;

static void event_acl_stream_has_bytes(void *context) {
  // No real concept of incoming SCO typed data, just ACL
  int bytes_read;
  hci_reader_t *reader = (hci_reader_t *) context;
  bytes_read = read(reader->inbound_fd, reader->data_buffer+reader->wr_ptr,
                                  reader->buffer_size - reader->wr_ptr);
  if (bytes_read <= 0) {
    LOG_ERROR("%s could not read HCI message type", __func__);
    return;
  }
  reader->wr_ptr += bytes_read;
  callbacks->data_ready(DATA_TYPE_ACL);
}
static bool hal_init(const hci_hal_callbacks_t *upper_callbacks, thread_t *upper_thread) {
  assert(upper_callbacks != NULL);
  assert(upper_thread != NULL);
/*  hal->init(&hal_callbacks, thread);callbacks = hal_callbacks = hal_says_data_ready*/
  callbacks = upper_callbacks;   // callbacks 等于  hal_says_data_ready
  /*
	upper_thread 为 hci_layer.c  调用start_up函数创建   thread= thread_new("hci_thread");  
	hal->init(&hal_callbacks, thread);
  */
  thread = upper_thread; 
  return true;
}

callbacks回调在hal_init的时候已经初始化,    callbacks->data_ready 函数对应hal_says_data_ready函数;

 hal_says_data_ready函数定义在 system\bt\hci\src\hci_layer.c文件中

// Event/packet receiving functions

// This function is not required to read all of a packet in one go, so
// be wary of reentry. But this function must return after finishing a packet.
static void hal_says_data_ready(serial_data_type_t type) {
  packet_receive_data_t *incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type)];

  uint8_t reset;

  uint8_t byte;
  while (hal->read_data(type, &byte, 1) != 0) {
    if (soc_type == BT_SOC_SMD) {
        reset = hal->dev_in_reset();
        if (reset) {
            incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)];
            if(!create_hw_reset_evt_packet(incoming))
                break;
            else {
            //Reset SOC status to trigger hciattach service
                if(property_set("bluetooth.status", "off") < 0) {
                    LOG_ERROR(LOG_TAG, "SSR: Error resetting SOC status\n ");
                } else {
                    ALOGE("SSR: SOC Status is reset\n ");
                }
            }
        }
    }

    switch (incoming->state) {
        case BRAND_NEW:
            // Initialize and prepare to jump to the preamble reading state
            incoming->bytes_remaining = preamble_sizes[PACKET_TYPE_TO_INDEX(type)];
            memset(incoming->preamble, 0, PREAMBLE_BUFFER_SIZE);
            incoming->index = 0;
            incoming->state = PREAMBLE;
            // INTENTIONAL FALLTHROUGH
        case PREAMBLE:
            incoming->preamble[incoming->index] = byte;
            incoming->index++;
            incoming->bytes_remaining--;

            if (incoming->bytes_remaining == 0) {
                // For event and sco preambles, the last byte we read is the length
                incoming->bytes_remaining = (type == DATA_TYPE_ACL) ? RETRIEVE_ACL_LENGTH(incoming->preamble) : byte;

                size_t buffer_size = BT_HDR_SIZE + incoming->index + incoming->bytes_remaining;

                if (buffer_size > MCA_USER_RX_BUF_SIZE) {
                    LOG_ERROR(LOG_TAG, "%s buffer_size(%zu) exceeded allowed packet size, allocation not possible", __func__, buffer_size);
                    incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type = DATA_TYPE_EVENT)];
                    if(create_hw_reset_evt_packet(incoming))
                        break;
                    else
                        return;
                }

                incoming->buffer = (BT_HDR *)buffer_allocator->alloc(buffer_size);

                if (!incoming->buffer) {
                    LOG_ERROR(LOG_TAG, "%s error getting buffer for incoming packet of type %d and size %zd", __func__, type, buffer_size);
                    // Can't read any more of this current packet, so jump out
                    incoming->state = incoming->bytes_remaining == 0 ? BRAND_NEW : IGNORE;
                    break;
                }

                // Initialize the buffer
                incoming->buffer->offset = 0;
                incoming->buffer->layer_specific = 0;
                incoming->buffer->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
                memcpy(incoming->buffer->data, incoming->preamble, incoming->index);

                incoming->state = incoming->bytes_remaining > 0 ? BODY : FINISHED;
            }

            break;
        case BODY:
            incoming->buffer->data[incoming->index] = byte;
            incoming->index++;
            incoming->bytes_remaining--;

            size_t bytes_read = hal->read_data(type, (incoming->buffer->data + incoming->index), incoming->bytes_remaining);
            incoming->index += bytes_read;
            incoming->bytes_remaining -= bytes_read;

            incoming->state = incoming->bytes_remaining == 0 ? FINISHED : incoming->state;
            break;
        case IGNORE:
            incoming->bytes_remaining--;
            if (incoming->bytes_remaining == 0) {
                incoming->state = BRAND_NEW;
                // Don't forget to let the hal know we finished the packet we were ignoring.
                // Otherwise we'll get out of sync with hals that embed extra information
                // in the uart stream (like H4). #badnewsbears
                hal->packet_finished(type);
                return;
            }

            break;
        case FINISHED:
            LOG_ERROR(LOG_TAG, "%s the state machine should not have been left in the finished state.", __func__);
            break;
    }

    if (incoming->state == FINISHED) {
      incoming->buffer->len = incoming->index;
      btsnoop->capture(incoming->buffer, true);

      if (type != DATA_TYPE_EVENT) {
        if(hci_state == HCI_READY) {
          packet_fragmenter->reassemble_and_dispatch(incoming->buffer);
        } else {
          LOG_WARN("%s, Ignoring the ACL pkt received", __func__);
          buffer_allocator->free(incoming->buffer);
        }
      } else if (!filter_incoming_event(incoming->buffer)) {
        if (hci_state == HCI_READY) {
          // Dispatch the event by event code
          uint8_t *stream = incoming->buffer->data;
          uint8_t event_code;
          STREAM_TO_UINT8(event_code, stream);

          data_dispatcher_dispatch(
            interface.event_dispatcher,
            event_code,
            incoming->buffer
          );
        } else {
          LOG_WARN("%s, Ignoring the event pkt received", __func__);
          buffer_allocator->free(incoming->buffer);
        }
      }

      // We don't control the buffer anymore
      incoming->buffer = NULL;
      incoming->state = BRAND_NEW;
      hal->packet_finished(type);

      // We return after a packet is finished for two reasons:
      // 1. The type of the next packet could be different.
      // 2. We don't want to hog cpu time.
      return;
    }
  }
}

    hal->read_data(type, &byte, 1) ;  对应hci_hal_mct.c文件的read_data函数

static size_t read_data(serial_data_type_t type, uint8_t *buffer, size_t max_size) {
#if (defined(REMOVE_EAGER_THREADS) && (REMOVE_EAGER_THREADS == TRUE))
  if (type == DATA_TYPE_ACL) {
    return hci_reader_read(acl_stream, buffer, max_size);
  } else if (type == DATA_TYPE_EVENT) {
    return hci_reader_read(event_stream, buffer, max_size);
  }
#else
  if (type == DATA_TYPE_ACL) {
    return eager_reader_read(acl_stream, buffer, max_size);
  } else if (type == DATA_TYPE_EVENT) {
    return eager_reader_read(event_stream, buffer, max_size);
  }
#endif

  LOG_ERROR(LOG_TAG, "%s invalid data type: %d", __func__, type);
  return 0;
}
size_t hci_reader_read(hci_reader_t *reader, uint8_t *buffer, size_t req_size) {
  int bytes_read = 0;
  assert(reader != NULL);
  assert(buffer != NULL);

  // If the caller wants nonblocking behavior, poll to see if we have
  // any bytes available before reading.
  if (reader->rd_ptr < reader->wr_ptr) {
    bytes_read = reader->wr_ptr - reader->rd_ptr;
    if ((size_t) bytes_read > req_size)
      bytes_read = req_size;
    memcpy(buffer, reader->data_buffer+reader->rd_ptr, bytes_read);
    reader->rd_ptr += bytes_read;
  } else {
    bytes_read = read(reader->inbound_fd, buffer, req_size);
    if(bytes_read == -1)
      bytes_read = 0;
  }

  return bytes_read;
}

hal_says_data_ready函数中,处理读到的数据 存入incoming->buffer , 调用函数reassemble_and_dispatch进行数据组装;

typedef struct {
  receive_state_t state;
  uint16_t bytes_remaining;
  uint8_t preamble[PREAMBLE_BUFFER_SIZE];
  uint16_t index;
  BT_HDR *buffer;
} packet_receive_data_t;

packet_receive_data_t *incoming = &incoming_packets[PACKET_TYPE_TO_INBOUND_INDEX(type)];

incoming->buffer 对应的结构体为BT_HDR

packet_fragmenter->reassemble_and_dispatch(incoming->buffer); 


static void reassemble_and_dispatch(UNUSED_ATTR BT_HDR *packet) {
	/*
		判断packet->event事件类型 如果是MSG_HC_TO_STACK_HCI_ACL执行以下, 如果不是执行
		callbacks->reassembled(packet);
	*/
  if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) {
    uint8_t *stream = packet->data;
    uint16_t handle;
    uint16_t l2cap_length;
    uint16_t acl_length;

    STREAM_TO_UINT16(handle, stream);
    STREAM_TO_UINT16(acl_length, stream);
    STREAM_TO_UINT16(l2cap_length, stream);

    assert(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);

    uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle);
    handle = handle & HANDLE_MASK;

    BT_HDR *partial_packet = (BT_HDR *)hash_map_get(partial_packets, (void *)(uintptr_t)handle);

    if (boundary_flag == START_PACKET_BOUNDARY) {
      if (partial_packet) {
        LOG_WARN(LOG_TAG, "%s found unfinished packet for handle with start packet. Dropping old.", __func__);

        hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
        buffer_allocator->free(partial_packet);
      }

      if (acl_length < L2CAP_HEADER_SIZE) {
        LOG_WARN(LOG_TAG, "%s L2CAP packet too small (%d < %d). Dropping it.", __func__, packet->len, L2CAP_HEADER_SIZE);
        buffer_allocator->free(packet);
        return;
      }

      uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;

      // Check for buffer overflow and that the full packet size + BT_HDR size is less than
      // the max buffer size
      if (check_uint16_overflow(l2cap_length, (L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE)) ||
          ((full_length + sizeof(BT_HDR)) > BT_DEFAULT_BUFFER_SIZE)) {
        LOG_ERROR(LOG_TAG, "%s L2CAP packet has invalid length (%d). Dropping it.", __func__, l2cap_length);
        buffer_allocator->free(packet);
        return;
      }

      if (full_length <= packet->len) {
        if (full_length < packet->len)
          LOG_WARN(LOG_TAG, "%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len);

        callbacks->reassembled(packet);
        return;
      }

      partial_packet = (BT_HDR *)buffer_allocator->alloc(full_length + sizeof(BT_HDR));
      partial_packet->event = packet->event;
      partial_packet->len = full_length;
      partial_packet->offset = packet->len;

      memcpy(partial_packet->data, packet->data, packet->len);

      // Update the ACL data size to indicate the full expected length
      stream = partial_packet->data;
      STREAM_SKIP_UINT16(stream); // skip the handle
      UINT16_TO_STREAM(stream, full_length - HCI_ACL_PREAMBLE_SIZE);

      hash_map_set(partial_packets, (void *)(uintptr_t)handle, partial_packet);
      // Free the old packet buffer, since we don't need it anymore
      buffer_allocator->free(packet);
    } else {
      if (!partial_packet) {
        LOG_WARN(LOG_TAG, "%s got continuation for unknown packet. Dropping it.", __func__);
        buffer_allocator->free(packet);
        return;
      }

      packet->offset = HCI_ACL_PREAMBLE_SIZE;
      uint16_t projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE);
      if (projected_offset > partial_packet->len) { // len stores the expected length
        LOG_WARN(LOG_TAG, "%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len);
        packet->len = partial_packet->len - partial_packet->offset;
        projected_offset = partial_packet->len;
      }

      memcpy(
        partial_packet->data + partial_packet->offset,
        packet->data + packet->offset,
        packet->len - packet->offset
      );

      // Free the old packet buffer, since we don't need it anymore
      buffer_allocator->free(packet);
      partial_packet->offset = projected_offset;

      if (partial_packet->offset == partial_packet->len) {
        hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
        partial_packet->offset = 0;
        callbacks->reassembled(partial_packet);
      }
    }
  } else {
    callbacks->reassembled(packet);
  }
}

函数中的callbacks在init的时候赋值为 packet_fragmenter_callbacks 


static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {
  transmit_fragment,
  dispatch_reassembled,
  fragmenter_transmit_finished
};

 dispatch_reassembled函数中通过发送消息给upwards_data_queue队列处理,

// Callback for the fragmenter to dispatch up a completely reassembled packet
static void dispatch_reassembled(BT_HDR *packet) {
  // Events should already have been dispatched before this point
  assert((packet->event & MSG_EVT_MASK) != MSG_HC_TO_STACK_HCI_EVT);
  assert(upwards_data_queue != NULL);

  if (upwards_data_queue) {
    fixed_queue_enqueue(upwards_data_queue, packet);
  } else {
    LOG_ERROR(LOG_TAG, "%s had no queue to place upwards data packet in. Dropping it on the floor.", __func__);
    buffer_allocator->free(packet);
  }
}

 

static void set_data_queue(fixed_queue_t *queue) {
  upwards_data_queue = queue;
}

     upwards_data_queue  在函数 set_data_queue 进行赋值  
      set_data_queue 函数在bte_main_boot_entry被调用 upwards_data_queue 赋值为

btu_hci_msg_queue。 btu_hci_msg_queue为初期HCI发送回来的消息队列,所有消息在btu_hci_msg_ready函数中处理 

btu_hci_msg_ready定义如下:

system\bt\stack\btu\btu_task.c

void btu_hci_msg_ready(fixed_queue_t *queue, UNUSED_ATTR void *context) {
    BT_HDR *p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
    btu_hci_msg_process(p_msg);
}
static void btu_hci_msg_process(BT_HDR *p_msg) {
    /* Determine the input message type. */
    switch (p_msg->event & BT_EVT_MASK)
    {
        case BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK: // TODO(zachoverflow): remove this
            ((post_to_task_hack_t *)(&p_msg->data[0]))->callback(p_msg);
#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
            /* If the host receives events which it doesn't responsd to, */
            /* it should start an idle timer to enter sleep mode.        */
            btu_check_bt_sleep ();
#endif
            break;
        case BT_EVT_TO_BTU_HCI_ACL:
            /* All Acl Data goes to L2CAP */
            l2c_rcv_acl_data (p_msg);
            break;

        case BT_EVT_TO_BTU_L2C_SEG_XMIT:
            /* L2CAP segment transmit complete */
            l2c_link_segments_xmitted (p_msg);
            break;

        case BT_EVT_TO_BTU_HCI_SCO:
#if BTM_SCO_INCLUDED == TRUE
            btm_route_sco_data (p_msg);
            break;
#endif

        case BT_EVT_TO_BTU_HCI_EVT:
            btu_hcif_process_event ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
            osi_free(p_msg);

#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
            /* If host receives events which it doesn't response to, */
            /* host should start idle timer to enter sleep mode.     */
            btu_check_bt_sleep ();
#endif
            break;

        case BT_EVT_TO_BTU_HCI_CMD:
            btu_hcif_send_cmd ((UINT8)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
            break;

        default:
            osi_free(p_msg);
            break;
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值