问题点4:原生BT中,客户端(BluetoothSocket)主动发起connect 动作的API call flow
-->执行到BT Service(Bluetooth.apk) 中的getSocketManager;
-->getSocketManagerNative的实现是得到JNI层句柄;
-->执行到JNI层的connectSocket,此函数的实现核心是“socketInterface->connect”
对应的是
-->通过btif_sock_get_interface;
所以执行到btsock_connect -->alloc_rfc_slot-->socketpair 建立一个套接字,并返回套接字给Java层;
而connect API 中的阻塞实现:waitSocketSignal
-->执行到readAll,这里根据第二个参数设定的长度值进行监听,以便退出while循环;
-->最终通过InputStream(输入字节流)的read 方法监听是否收到底层发送的data,来判别当前是否连接上;20Byte 内容是结构体“sock_connect_signal_t”的大小;
小结:
通过在Android 9原生Source Code 中搜索waitSocketSignal,可以看到在BluetoothSocket.java中的connect 和accept中都在使用;所以不论是客户端还是服务端都使用waitSocketSignal等待20Byte 进行阻塞;同时,在等待20Byte数据前,客户端在执行connect 方法、服务端在执行监听方法bindListen中,先等待固定长度 4Byte “int channel = readInt(mSocketIS);”(rfc_slot_t 中的“int len”)来获得Channel ID(底层发送API是send_app_scn)。
这里需留意的是:send_app_scn是btif_sock_rfc.cc (system\bt\btif\src)中定义的API;
问题点延伸:在原生的l2cap “btif_sock_l2cap.cc (system\bt\btif\src)” 连接中,为何没有看到类似的发送4 Byte Data, 而Framework层中在调用BluetoothSocket的connect 方法时不会区别当前是连接RFCOMM 还是L2cap 还是SCO?
socket的connect时不区分具体连接类型;
---L2cap 中发送4Byte data 的API 是send_app_psm_or_chan_l;
---L2cap 中发送表示连接上的20Byte data API 是send_app_connect_signal;
--SCO 中发送20Byte data 的是socket_write_and_transfer_fd;