mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 22:20:37 +00:00
rfcomm: request l2cap can send now for channel and handle event, drop rfcomm_run
This commit is contained in:
parent
b35818ceb1
commit
62b5b74105
@ -133,12 +133,12 @@ static gap_security_level_t rfcomm_security_level;
|
||||
|
||||
static int rfcomm_channel_can_send(rfcomm_channel_t * channel);
|
||||
static int rfcomm_channel_ready_for_open(rfcomm_channel_t *channel);
|
||||
static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_channel_event_t *event);
|
||||
static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, rfcomm_channel_event_t *event);
|
||||
static int rfcomm_channel_ready_to_send(rfcomm_channel_t * channel);
|
||||
static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, const rfcomm_channel_event_t *event);
|
||||
static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, const rfcomm_channel_event_t *event);
|
||||
static void rfcomm_emit_can_send_now(rfcomm_channel_t *channel);
|
||||
static int rfcomm_multiplexer_ready_to_send(rfcomm_multiplexer_t * multiplexer);
|
||||
static void rfcomm_multiplexer_state_machine(rfcomm_multiplexer_t * multiplexer, RFCOMM_MULTIPLEXER_EVENT event);
|
||||
static void rfcomm_run(void);
|
||||
|
||||
// MARK: RFCOMM CLIENT EVENTS
|
||||
|
||||
@ -822,7 +822,7 @@ static void rfcomm_multiplexer_opened(rfcomm_multiplexer_t *multiplexer){
|
||||
log_info("Multiplexer up and running");
|
||||
multiplexer->state = RFCOMM_MULTIPLEXER_OPEN;
|
||||
|
||||
rfcomm_channel_event_t event = { CH_EVT_MULTIPLEXER_READY };
|
||||
const rfcomm_channel_event_t event = { CH_EVT_MULTIPLEXER_READY };
|
||||
|
||||
// transition of channels that wait for multiplexer
|
||||
btstack_linked_item_t *it;
|
||||
@ -830,6 +830,9 @@ static void rfcomm_multiplexer_opened(rfcomm_multiplexer_t *multiplexer){
|
||||
rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
|
||||
if (channel->multiplexer != multiplexer) continue;
|
||||
rfcomm_channel_state_machine(channel, &event);
|
||||
if (rfcomm_channel_ready_to_send(channel)){
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
}
|
||||
rfcomm_multiplexer_prepare_idle_timer(multiplexer);
|
||||
|
||||
@ -841,8 +844,9 @@ static void rfcomm_multiplexer_opened(rfcomm_multiplexer_t *multiplexer){
|
||||
|
||||
static void rfcomm_handle_can_send_now(uint16_t l2cap_cid){
|
||||
|
||||
// find multiplexer for this cid
|
||||
btstack_linked_list_iterator_t it;
|
||||
|
||||
// find multiplexer for this cid
|
||||
btstack_linked_list_iterator_init(&it, &rfcomm_multiplexers);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
rfcomm_multiplexer_t * multiplexer = (rfcomm_multiplexer_t *) btstack_linked_list_iterator_next(&it);
|
||||
@ -852,13 +856,39 @@ static void rfcomm_handle_can_send_now(uint16_t l2cap_cid){
|
||||
// more to send?
|
||||
if (rfcomm_multiplexer_ready_to_send(multiplexer)){
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rfcomm_run(); // rfcomm signaling packets first
|
||||
rfcomm_notify_channel_can_send();
|
||||
// find channels for this cid
|
||||
btstack_linked_list_iterator_init(&it, &rfcomm_channels);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
rfcomm_channel_t * channel = (rfcomm_channel_t *) btstack_linked_list_iterator_next(&it);
|
||||
if (channel->multiplexer->l2cap_cid != l2cap_cid) continue;
|
||||
// channel state machine
|
||||
if (rfcomm_channel_ready_to_send(channel)){
|
||||
const rfcomm_channel_event_t event = { CH_EVT_READY_TO_SEND };
|
||||
rfcomm_channel_state_machine(channel, &event);
|
||||
if (rfcomm_channel_ready_to_send(channel)){
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// client waiting for can send now
|
||||
if (!channel->waiting_for_can_send_now) continue;
|
||||
if (!channel->credits_outgoing) continue;
|
||||
if ((channel->multiplexer->fcon & 1) == 0) continue;
|
||||
|
||||
channel->waiting_for_can_send_now = 0;
|
||||
rfcomm_emit_can_send_now(channel);
|
||||
|
||||
// TODO: call request send now if ... ?
|
||||
|
||||
if (!l2cap_can_send_packet_now(l2cap_cid)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1244,8 +1274,10 @@ static void rfcomm_channel_opened(rfcomm_channel_t *rfChannel){
|
||||
// hack for problem detecting authentication failure
|
||||
multiplexer->at_least_one_connection = 1;
|
||||
|
||||
// start next connection request if pending
|
||||
rfcomm_run();
|
||||
// request can send now if channel ready
|
||||
if (rfcomm_channel_ready_to_send(rfChannel)){
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
}
|
||||
|
||||
static void rfcomm_channel_packet_handler_uih(rfcomm_multiplexer_t *multiplexer, uint8_t * packet, uint16_t size){
|
||||
@ -1268,6 +1300,9 @@ static void rfcomm_channel_packet_handler_uih(rfcomm_multiplexer_t *multiplexer,
|
||||
// notify channel statemachine
|
||||
rfcomm_channel_event_t channel_event = { CH_EVT_RCVD_CREDITS };
|
||||
rfcomm_channel_state_machine(channel, &channel_event);
|
||||
if (channel->waiting_for_can_send_now && ((channel->multiplexer->fcon & 1) == 0)){
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
}
|
||||
|
||||
// contains payload?
|
||||
@ -1287,7 +1322,8 @@ static void rfcomm_channel_packet_handler_uih(rfcomm_multiplexer_t *multiplexer,
|
||||
|
||||
// automatically provide new credits to remote device, if no incoming flow control
|
||||
if (!channel->incoming_flow_control && channel->credits_incoming < 5){
|
||||
channel->new_credits_incoming =RFCOMM_CREDITS;
|
||||
channel->new_credits_incoming = RFCOMM_CREDITS;
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1322,7 +1358,7 @@ static void rfcomm_channel_finalize(rfcomm_channel_t *channel){
|
||||
rfcomm_multiplexer_prepare_idle_timer(multiplexer);
|
||||
}
|
||||
|
||||
static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, rfcomm_channel_event_t *event){
|
||||
static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, uint8_t dlci, const rfcomm_channel_event_t *event){
|
||||
|
||||
// TODO: if client max frame size is smaller than RFCOMM_DEFAULT_SIZE, send PN
|
||||
|
||||
@ -1343,6 +1379,7 @@ static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, u
|
||||
if (!service) {
|
||||
// discard request by sending disconnected mode
|
||||
multiplexer->send_dm_for_dlci = dlci;
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1357,6 +1394,7 @@ static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, u
|
||||
if (!channel){
|
||||
// discard request by sending disconnected mode
|
||||
multiplexer->send_dm_for_dlci = dlci;
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1366,8 +1404,10 @@ static void rfcomm_channel_state_machine_2(rfcomm_multiplexer_t * multiplexer, u
|
||||
if (!channel) {
|
||||
// discard request by sending disconnected mode
|
||||
multiplexer->send_dm_for_dlci = dlci;
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
rfcomm_channel_state_machine(channel, event);
|
||||
}
|
||||
|
||||
@ -1517,7 +1557,9 @@ static void rfcomm_channel_packet_handler(rfcomm_multiplexer_t * multiplexer, u
|
||||
}
|
||||
|
||||
// trigger next action - example W4_PN_RSP: transition to SEND_SABM which only depends on "can send"
|
||||
rfcomm_run();
|
||||
if (rfcomm_multiplexer_ready_to_send(multiplexer)){
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
}
|
||||
}
|
||||
|
||||
static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
@ -1550,7 +1592,6 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
|
||||
if (frame_dlci && (packet[1] == BT_RFCOMM_UIH || packet[1] == BT_RFCOMM_UIH_PF)) {
|
||||
rfcomm_channel_packet_handler_uih(multiplexer, packet, size);
|
||||
rfcomm_run();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1588,7 +1629,56 @@ inline static void rfcomm_channel_state_remove(rfcomm_channel_t *channel, RFCOMM
|
||||
channel->state_var = (RFCOMM_CHANNEL_STATE_VAR) (channel->state_var & ~event);
|
||||
}
|
||||
|
||||
static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_channel_event_t *event){
|
||||
static int rfcomm_channel_ready_to_send(rfcomm_channel_t * channel){
|
||||
switch (channel->state){
|
||||
case RFCOMM_CHANNEL_SEND_UIH_PN:
|
||||
log_debug("ch-ready: state %u", channel->state);
|
||||
return 1;
|
||||
case RFCOMM_CHANNEL_SEND_SABM_W4_UA:
|
||||
log_debug("ch-ready: state %u", channel->state);
|
||||
return 1;
|
||||
case RFCOMM_CHANNEL_SEND_UA_AFTER_DISC:
|
||||
log_debug("ch-ready: state %u", channel->state);
|
||||
return 1;
|
||||
case RFCOMM_CHANNEL_SEND_DISC:
|
||||
log_debug("ch-ready: state %u", channel->state);
|
||||
return 1;
|
||||
case RFCOMM_CHANNEL_SEND_DM:
|
||||
log_debug("ch-ready: state %u", channel->state);
|
||||
return 1;
|
||||
case RFCOMM_CHANNEL_OPEN:
|
||||
if (channel->new_credits_incoming) {
|
||||
log_debug("ch-ready: channel open & new_credits_incoming") ;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (channel->state_var & (
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_INFO |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_UA |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_CMD |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_MSC_RSP |
|
||||
RFCOMM_CHANNEL_STATE_VAR_SEND_CREDITS
|
||||
)){
|
||||
log_debug("ch-ready: state %x, state var %x", channel->state, channel->state_var);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (channel->rls_line_status != RFCOMM_RLS_STATUS_INVALID) {
|
||||
log_debug("ch-ready: rls_line_status");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, const rfcomm_channel_event_t *event){
|
||||
|
||||
// log_info("rfcomm_channel_state_machine: state %u, state_var %04x, event %u", channel->state, channel->state_var ,event->type);
|
||||
|
||||
@ -1645,7 +1735,7 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: integrate in common swich
|
||||
// TODO: integrate in common switch
|
||||
if (event->type == CH_EVT_READY_TO_SEND){
|
||||
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_SEND_RPN_RSP){
|
||||
log_info("Sending Remote Port Negotiation RSP for #%u", channel->dlci);
|
||||
@ -1923,48 +2013,6 @@ static void rfcomm_channel_state_machine(rfcomm_channel_t *channel, rfcomm_chann
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: RFCOMM RUN
|
||||
// process outstanding signaling tasks
|
||||
static void rfcomm_run(void){
|
||||
|
||||
btstack_linked_item_t *it;
|
||||
btstack_linked_item_t *next;
|
||||
|
||||
#if 0
|
||||
for (it = (btstack_linked_item_t *) rfcomm_multiplexers; it ; it = next){
|
||||
|
||||
next = it->next; // be prepared for removal of channel in state machine
|
||||
|
||||
rfcomm_multiplexer_t * multiplexer = ((rfcomm_multiplexer_t *) it);
|
||||
|
||||
if (!l2cap_can_send_packet_now(multiplexer->l2cap_cid)) {
|
||||
// log_info("rfcomm_run A cannot send l2cap packet for #%u, credits %u", multiplexer->l2cap_cid, multiplexer->l2cap_credits);
|
||||
continue;
|
||||
}
|
||||
// log_info("rfcomm_run: multi 0x%08x, state %u", (int) multiplexer, multiplexer->state);
|
||||
|
||||
rfcomm_multiplexer_state_machine(multiplexer, MULT_EV_READY_TO_SEND);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (it = (btstack_linked_item_t *) rfcomm_channels; it ; it = next){
|
||||
|
||||
next = it->next; // be prepared for removal of channel in state machine
|
||||
|
||||
rfcomm_channel_t * channel = ((rfcomm_channel_t *) it);
|
||||
rfcomm_multiplexer_t * multiplexer = channel->multiplexer;
|
||||
|
||||
if (!l2cap_can_send_packet_now(multiplexer->l2cap_cid)) {
|
||||
// log_info("rfcomm_run B cannot send l2cap packet for #%u, credits %u", multiplexer->l2cap_cid, multiplexer->l2cap_credits);
|
||||
continue;
|
||||
}
|
||||
|
||||
rfcomm_channel_event_t event = { CH_EVT_READY_TO_SEND };
|
||||
rfcomm_channel_state_machine(channel, &event);
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: RFCOMM BTstack API
|
||||
|
||||
void rfcomm_init(void){
|
||||
@ -2189,7 +2237,7 @@ static uint8_t rfcomm_channel_create_internal(btstack_packet_handler_t packet_ha
|
||||
channel->state = RFCOMM_CHANNEL_SEND_UIH_PN;
|
||||
|
||||
// start connecting, if multiplexer is already up and running
|
||||
rfcomm_run();
|
||||
l2cap_request_can_send_now_event(multiplexer->l2cap_cid);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@ -2214,7 +2262,7 @@ void rfcomm_disconnect(uint16_t rfcomm_cid){
|
||||
}
|
||||
|
||||
// process
|
||||
rfcomm_run();
|
||||
l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
|
||||
}
|
||||
|
||||
static uint8_t rfcomm_register_service_internal(btstack_packet_handler_t packet_handler,
|
||||
@ -2288,9 +2336,11 @@ void rfcomm_accept_connection(uint16_t rfcomm_cid){
|
||||
rfcomm_channel_state_add(channel, RFCOMM_CHANNEL_STATE_VAR_CLIENT_ACCEPTED);
|
||||
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_PN){
|
||||
rfcomm_channel_state_add(channel, RFCOMM_CHANNEL_STATE_VAR_SEND_PN_RSP);
|
||||
l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
|
||||
}
|
||||
if (channel->state_var & RFCOMM_CHANNEL_STATE_VAR_RCVD_SABM){
|
||||
rfcomm_channel_state_add(channel, RFCOMM_CHANNEL_STATE_VAR_SEND_UA);
|
||||
l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
|
||||
}
|
||||
// at least one of { PN RSP, UA } needs to be sent
|
||||
// state transistion incoming setup -> dlc setup happens in rfcomm_run after these have been sent
|
||||
@ -2299,8 +2349,6 @@ void rfcomm_accept_connection(uint16_t rfcomm_cid){
|
||||
break;
|
||||
}
|
||||
|
||||
// process
|
||||
rfcomm_run();
|
||||
}
|
||||
|
||||
void rfcomm_decline_connection(uint16_t rfcomm_cid){
|
||||
@ -2310,13 +2358,11 @@ void rfcomm_decline_connection(uint16_t rfcomm_cid){
|
||||
switch (channel->state) {
|
||||
case RFCOMM_CHANNEL_INCOMING_SETUP:
|
||||
channel->state = RFCOMM_CHANNEL_SEND_DM;
|
||||
l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// process
|
||||
rfcomm_run();
|
||||
}
|
||||
|
||||
void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits){
|
||||
@ -2327,7 +2373,7 @@ void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits){
|
||||
channel->new_credits_incoming += credits;
|
||||
|
||||
// process
|
||||
rfcomm_run();
|
||||
l2cap_request_can_send_now_event(channel->multiplexer->l2cap_cid);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user