BlueDroid HFP 源码分析笔记(1)

本文深入解析BlueDroid中的Hands-Free Profile(HFP)代码实现,重点介绍消息传递机制、状态机处理流程及SDP服务发现过程。通过详细代码分析,揭示蓝牙设备连接、服务发现及状态迁移背后的逻辑。

BlueDroid 代码分析

对部分代码一眼无法知道运行结果的地方备注。

HPF Connect

可以理解为闭包吧!将参数和方法打包在一起传入队列中等待执行。最终执行的就是 connect_init(),参数就是bd_addr, connect_init。

static bt_status_t connect(RawAddress* bd_addr) {
   
   
  return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
}

这里的用到BlueDroid中最常用的消息传递方式,malloc出结构体后。赋值event和layer_specific。
然后通过bta_sys_sendmsg发送event到bta_sys_main.cc bta_sys_event中进行处理。

void BTA_HfClientOpen(const RawAddress& bd_addr, tBTA_SEC sec_mask,
                      uint16_t* p_handle) {
   
   
  APPL_TRACE_DEBUG("%s", __func__);
  tBTA_HF_CLIENT_API_OPEN* p_buf =
      (tBTA_HF_CLIENT_API_OPEN*)osi_malloc(sizeof(tBTA_HF_CLIENT_API_OPEN));

  if (!bta_hf_client_allocate_handle(bd_addr, p_handle)) {
   
   
    APPL_TRACE_ERROR("%s: could not allocate handle", __func__);
    return;
  }

  p_buf->hdr.event = BTA_HF_CLIENT_API_OPEN_EVT; //BTA_HF_CLIENT_API_OPEN_EVT = 27 << 8:
  p_buf->hdr.layer_specific = *p_handle;
  p_buf->bd_addr = bd_addr;
  p_buf->sec_mask = sec_mask;

  bta_sys_sendmsg(p_buf);
}

enum {
   
   
  /* these events are handled by the state machine */
  BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS), // BTA_ID_HS 27
  BTA_HF_CLIENT_API_CLOSE_EVT,
  BTA_HF_CLIENT_API_AUDIO_OPEN_EVT,
  BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT,
  BTA_HF_CLIENT_RFC_OPEN_EVT,
  BTA_HF_CLIENT_RFC_CLOSE_EVT,
  BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT,
  BTA_HF_CLIENT_RFC_DATA_EVT,
  BTA_HF_CLIENT_DISC_ACP_RES_EVT,
  BTA_HF_CLIENT_DISC_INT_RES_EVT,
  BTA_HF_CLIENT_DISC_OK_EVT,
  BTA_HF_CLIENT_DISC_FAIL_EVT,
  BTA_HF_CLIENT_SCO_OPEN_EVT,
  BTA_HF_CLIENT_SCO_CLOSE_EVT,
  BTA_HF_CLIENT_SEND_AT_CMD_EVT,
  BTA_HF_CLIENT_MAX_EVT,

  /* these events are handled outside of the state machine */
  BTA_HF_CLIENT_API_ENABLE_EVT,
  BTA_HF_CLIENT_API_DISABLE_EVT
};


//记住这三个结构体,都包含有一个BT_HDR 的结构提。这结构体中包含一些共同的信息
/* data type for BTA_HF_CLIENT_API_OPEN_EVT */
typedef struct {
   
   
  BT_HDR hdr;
  RawAddress bd_addr;
  uint16_t* handle;
  tBTA_SEC sec_mask;
} tBTA_HF_CLIENT_API_OPEN;

/* data type for BTA_HF_CLIENT_DISC_RESULT_EVT */
typedef struct {
   
   
  BT_HDR hdr;
  uint16_t status;
} tBTA_HF_CLIENT_DISC_RESULT;

/* data type for RFCOMM events */
typedef struct {
   
   
  BT_HDR hdr;
  uint16_t port_handle;
} tBTA_HF_CLIENT_RFC;

/* generic purpose data type for other events */
typedef struct {
   
   
  BT_HDR hdr;
  bool bool_val;
  uint8_t uint8_val;
  uint32_t uint32_val1;
  uint32_t uint32_val2;
  char str[BTA_HF_CLIENT_NUMBER_LEN + 1];
} tBTA_HF_CLIENT_DATA_VAL;

//注意这是一个联合体!!! 后面会知道这个联合体的用处。
/* union of all event datatypes */
typedef union {
   
   
  BT_HDR hdr;
  tBTA_HF_CLIENT_API_OPEN api_open;
  tBTA_HF_CLIENT_DISC_RESULT disc_result;
  tBTA_HF_CLIENT_RFC rfc;
  tBTA_HF_CLIENT_DATA_VAL val;

} tBTA_HF_CLIENT_DATA;

这个方法就是处理event。传进来的参数已经是BT_HDR *,因为这个方法是通用的处理。不止HFP会发送消息到这里进行处理。其他的profile也会发送消息过来,所以需要一个共同的结构体。

  • id = (uint8_t)(p_msg->event >> 8);
    获取的id是右移8位,为什么要这样了。是因为BTA_HF_CLIENT_API_OPEN_EVT就是在 BTA_ID_HS的基础上左移8位,同时这个值又被enum包括,这样后续的值再右移8位后

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值