问题点5:原生BT 中的SPP 是如何断开的(主动断开和被动断开)
不论Socket Server 还是Client,其断开动作都是执行close() 方法;
问题点延伸1:当上层执行BluetoothSocket close()主动断开时,如何触发底层FRCOMM主动断开?(Java-->JNI-->Bluedroid)
Note:
在BlueDroid中实现轮询check Java层通过socket 发出data的核心API 是 sock_poll_thread;
核心原理:当BlueDroid层的socket初始化(btif_sock_init)时,其通过btsock_thread_create创建监测socket fd 线程;核心轮询API 是sock_poll_thread,其负责监测从java 层socket 发出的data并转发给对应的rfcomm \l2cap \sco,同时也负责fd的异常检测;
当Java层主动断开Socket(执行BluetoothSocket的close())关闭socket时,sock_poll_thread检测到 对应fd发生exception进而设置,最后执行callback API (通过btsock_thread_create注册下来的callback API,在btif_sock.cc中是btsock_signaled)
SOCK_THREAD_FD_EXCEPTION;
Note:btsock_thread_add_fdàadd_poll负责添加fd到fd集
” static thread_slot_t ts[MAX_THREAD];”,进行集中检测;
-->btsock_signaled,被检测线程触发;
Note : btsock_signaled是在btif_sock_init时创建的线程;
-->btsock_rfc_signaled中执行cleanup_rfc_slot;
从实际log中看到被设置的flag 有:SOCK_THREAD_FD_EXCEPTION
-->cleanup_rfc_slot
-->BTA_JvRfcommClose
-->bta_jv_rfcomm_close
-->bta_jv_free_rfc_cb中执行RFCOMM_RemoveConnection;
-->RFCOMM_RemoveConnection;
-->执行port_start_close;
问题点延伸2:当SPP被动断开时的flow?
-->当remote device 执行断开flow时,BlueDroid执行PORT_DlcReleaseInd;
-->port_start_close,在 函数里面执行callback,
此callback为执行RFCOMM_CreateConnection时注册
注册flow(
-->BTA_JvRfcommConnect
-->bta_jv_rfcomm_connect
-->RFCOMM_CreateConnectionà注册callbackbta_jv_port_mgmt_cl_cback
)
-->callback 对应的是:callback bta_jv_port_mgmt_cl_cback(车机主动发起的SPP 连接时,
若是手机端发起的SPP 连接,则此时执行的callback是bta_jv_port_mgmt_sr_cback,
其是通过建立socket listen时触发
-->BTA_JV_CREATE_RECORD_EVT;
-->BTA_JvRfcommStartServer
-->bta_jv_rfcomm_start_server
-->RFCOMM_CreateConnection注册bta_jv_port_mgmt_sr_cback等待被连接)
通过callback执行Message BTA_JV_RFCOMM_CLOSE_EVT
-->执行Message BTA_JV_RFCOMM_CLOSE_EVT,在API rfcomm_cback函数中执行
on_rfc_close;
-->on_rfc_close
-->cleanup_rfc_slot, 这里执行socket的关闭动作,使得轮询函数sock_poll_thread抛出异常;同时Java层BluetoothSocket也能检测到异常;