bt: Split SPP application layer data packets according to the MTU of the peer

This commit is contained in:
xiongweichao 2022-09-19 20:20:22 +08:00
parent a0ec1c8291
commit ea41a21b0e
5 changed files with 53 additions and 18 deletions

View File

@ -286,6 +286,7 @@ typedef struct {
/* data associated with BTA_JV_RFCOMM_OPEN_EVT */ /* data associated with BTA_JV_RFCOMM_OPEN_EVT */
typedef struct { typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT16 peer_mtu; /* Max MTU that port can send */
UINT32 handle; /* The connection handle */ UINT32 handle; /* The connection handle */
BD_ADDR rem_bda; /* The peer address */ BD_ADDR rem_bda; /* The peer address */
} tBTA_JV_RFCOMM_OPEN; } tBTA_JV_RFCOMM_OPEN;
@ -293,6 +294,7 @@ typedef struct {
/* data associated with BTA_JV_RFCOMM_SRV_OPEN_EVT */ /* data associated with BTA_JV_RFCOMM_SRV_OPEN_EVT */
typedef struct { typedef struct {
tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */ tBTA_JV_STATUS status; /* Whether the operation succeeded or failed. */
UINT16 peer_mtu; /* Max MTU that port can send */
UINT32 handle; /* The connection handle */ UINT32 handle; /* The connection handle */
UINT32 new_listen_handle; /* The new listen handle */ UINT32 new_listen_handle; /* The new listen handle */
BD_ADDR rem_bda; /* The peer address */ BD_ADDR rem_bda; /* The peer address */

View File

@ -1685,6 +1685,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat
BD_ADDR rem_bda = {0}; BD_ADDR rem_bda = {0};
UINT16 lcid; UINT16 lcid;
tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */ tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */
tPORT_MGMT_CL_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_CL_CALLBACK_ARG *)data;
APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle); APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle);
if (NULL == p_cb || NULL == p_cb->p_cback) { if (NULL == p_cb || NULL == p_cb->p_cback) {
@ -1701,6 +1702,9 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat
evt_data.rfc_open.status = BTA_JV_SUCCESS; evt_data.rfc_open.status = BTA_JV_SUCCESS;
bdcpy(evt_data.rfc_open.rem_bda, rem_bda); bdcpy(evt_data.rfc_open.rem_bda, rem_bda);
p_pcb->state = BTA_JV_ST_CL_OPEN; p_pcb->state = BTA_JV_ST_CL_OPEN;
if (p_mgmt_cb_arg) {
evt_data.rfc_open.peer_mtu = p_mgmt_cb_arg->peer_mtu;
}
p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->user_data); p_cb->p_cback(BTA_JV_RFCOMM_OPEN_EVT, &evt_data, p_pcb->user_data);
} else { } else {
evt_data.rfc_close.handle = p_pcb->handle; evt_data.rfc_close.handle = p_pcb->handle;
@ -1981,6 +1985,7 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat
} }
evt_data.rfc_srv_open.handle = p_pcb->handle; evt_data.rfc_srv_open.handle = p_pcb->handle;
evt_data.rfc_srv_open.status = BTA_JV_SUCCESS; evt_data.rfc_srv_open.status = BTA_JV_SUCCESS;
evt_data.rfc_srv_open.peer_mtu = p_mgmt_cb_arg->peer_mtu;
bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda); bdcpy(evt_data.rfc_srv_open.rem_bda, rem_bda);
tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb); tBTA_JV_PCB *p_pcb_new_listen = bta_jv_add_rfc_port(p_cb, p_pcb);
if (p_pcb_new_listen) { if (p_pcb_new_listen) {

View File

@ -52,8 +52,8 @@ typedef struct {
uint8_t serial; uint8_t serial;
uint8_t scn; uint8_t scn;
uint8_t max_session; uint8_t max_session;
uint16_t mtu;
uint32_t id; uint32_t id;
uint32_t mtu;//unused
uint32_t sdp_handle; uint32_t sdp_handle;
uint32_t rfc_handle; uint32_t rfc_handle;
uint32_t rfc_port_handle; uint32_t rfc_port_handle;
@ -133,6 +133,7 @@ static spp_slot_t *spp_malloc_slot(void)
(*slot)->fd = -1; (*slot)->fd = -1;
(*slot)->connected = false; (*slot)->connected = false;
(*slot)->is_server = false; (*slot)->is_server = false;
(*slot)->mtu = 0;
(*slot)->write_data = NULL; (*slot)->write_data = NULL;
(*slot)->close_alarm = NULL; (*slot)->close_alarm = NULL;
/* clear the old event bits */ /* clear the old event bits */
@ -333,6 +334,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
slot_new->max_session = slot->max_session; slot_new->max_session = slot->max_session;
strcpy(slot_new->service_name, slot->service_name); strcpy(slot_new->service_name, slot->service_name);
slot_new->sdp_handle = slot->sdp_handle; slot_new->sdp_handle = slot->sdp_handle;
slot_new->mtu = p_data->rfc_srv_open.peer_mtu;
slot_new->rfc_handle = p_data->rfc_srv_open.handle; slot_new->rfc_handle = p_data->rfc_srv_open.handle;
slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle); slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle);
BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN);
@ -375,6 +377,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u
} }
slot->connected = true; slot->connected = true;
slot->rfc_handle = p_data->rfc_open.handle; slot->rfc_handle = p_data->rfc_open.handle;
slot->mtu = p_data->rfc_open.peer_mtu;
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle); slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle);
BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN); BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN);
break; break;
@ -1384,7 +1387,7 @@ static ssize_t spp_vfs_write(int fd, const void * data, size_t size)
tx_event_group_val = 0; tx_event_group_val = 0;
if (size) { if (size) {
if (p_buf == NULL) { if (p_buf == NULL) {
write_size = size < BTA_JV_DEF_RFC_MTU ? size : BTA_JV_DEF_RFC_MTU; write_size = size < slot->mtu ? size : slot->mtu;
if ((p_buf = osi_malloc(sizeof(BT_HDR) + write_size)) == NULL) { if ((p_buf = osi_malloc(sizeof(BT_HDR) + write_size)) == NULL) {
BTC_TRACE_ERROR("%s malloc failed!", __func__); BTC_TRACE_ERROR("%s malloc failed!", __func__);
errno = ENOMEM; errno = ENOMEM;

View File

@ -113,8 +113,16 @@ typedef void (tPORT_MGMT_CALLBACK) (UINT32 code, UINT16 port_handle, void* data)
typedef struct { typedef struct {
BOOLEAN accept; /* If upper layer accepts the incoming connection */ BOOLEAN accept; /* If upper layer accepts the incoming connection */
BOOLEAN ignore_rfc_state; /* If need to ignore rfc state for PORT_CheckConnection */ BOOLEAN ignore_rfc_state; /* If need to ignore rfc state for PORT_CheckConnection */
UINT16 peer_mtu; /* Max MTU that port can send */
} tPORT_MGMT_SR_CALLBACK_ARG; } tPORT_MGMT_SR_CALLBACK_ARG;
/**
* Define the client port manage callback function argument
*/
typedef struct {
UINT16 peer_mtu; /* Max MTU that port can send */
} tPORT_MGMT_CL_CALLBACK_ARG;
/* /*
** Define events that registered application can receive in the callback ** Define events that registered application can receive in the callback
*/ */

View File

@ -427,9 +427,11 @@ void PORT_ParNegCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT8 cl, UINT8 k)
void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu) void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
{ {
tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
tPORT_MGMT_SR_CALLBACK_ARG mgmt_cb_arg = { tPORT_MGMT_CL_CALLBACK_ARG cl_mgmt_cb_arg = {0};
tPORT_MGMT_SR_CALLBACK_ARG sr_mgmt_cb_arg = {
.accept = TRUE, .accept = TRUE,
.ignore_rfc_state = FALSE, .ignore_rfc_state = FALSE,
.peer_mtu = 0,
}; };
RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port); RFCOMM_TRACE_DEBUG ("PORT_DlcEstablishInd p_mcb:%p, dlci:%d mtu:%di, p_port:%p", p_mcb, dlci, mtu, p_port);
@ -464,22 +466,29 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
} }
if (p_port->p_mgmt_callback) { if (p_port->p_mgmt_callback) {
/** if (p_port->is_server) {
* @note sr_mgmt_cb_arg.peer_mtu = p_port->peer_mtu;
* 1. The manage callback function may change the value of accept in mgmt_cb_arg. /**
* 2. Use mgmt_cb_arg.ignore_rfc_state to work around the issue caused by sending * @note
* RFCOMM establish response after the manage callback function. * 1. The manage callback function may change the value of accept in mgmt_cb_arg.
*/ * 2. Use mgmt_cb_arg.ignore_rfc_state to work around the issue caused by sending
mgmt_cb_arg.ignore_rfc_state = TRUE; * RFCOMM establish response after the manage callback function.
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &mgmt_cb_arg); */
sr_mgmt_cb_arg.ignore_rfc_state = TRUE;
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &sr_mgmt_cb_arg);
if (!sr_mgmt_cb_arg.accept) {
RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_LOW_RESOURCES);
return;
}
} else {
cl_mgmt_cb_arg.peer_mtu = p_port->peer_mtu;
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &cl_mgmt_cb_arg);
}
} }
if (mgmt_cb_arg.accept) { RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS);
RFCOMM_DlcEstablishRsp(p_mcb, dlci, p_port->mtu, RFCOMM_SUCCESS); p_port->state = PORT_STATE_OPENED;
p_port->state = PORT_STATE_OPENED;
} else {
RFCOMM_DlcEstablishRsp(p_mcb, dlci, 0, RFCOMM_LOW_RESOURCES);
}
} }
@ -496,6 +505,8 @@ void PORT_DlcEstablishInd (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu)
void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result) void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 result)
{ {
tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci); tPORT *p_port = port_find_mcb_dlci_port (p_mcb, dlci);
tPORT_MGMT_SR_CALLBACK_ARG sr_mgmt_cb_arg = {0};
tPORT_MGMT_CL_CALLBACK_ARG cl_mgmt_cb_arg = {0};
RFCOMM_TRACE_EVENT ("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, result); RFCOMM_TRACE_EVENT ("PORT_DlcEstablishCnf dlci:%d mtu:%d result:%d", dlci, mtu, result);
@ -522,7 +533,13 @@ void PORT_DlcEstablishCnf (tRFC_MCB *p_mcb, UINT8 dlci, UINT16 mtu, UINT16 resul
} }
if (p_port->p_mgmt_callback) { if (p_port->p_mgmt_callback) {
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, NULL); if (p_port->is_server) {
sr_mgmt_cb_arg.peer_mtu = p_port->peer_mtu;
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &sr_mgmt_cb_arg);
} else {
cl_mgmt_cb_arg.peer_mtu = p_port->peer_mtu;
p_port->p_mgmt_callback (PORT_SUCCESS, p_port->inx, &cl_mgmt_cb_arg);
}
} }
p_port->state = PORT_STATE_OPENED; p_port->state = PORT_STATE_OPENED;