diff --git a/MSP-EXP430F5438-CC256x/example-ant/ant-test.c b/MSP-EXP430F5438-CC256x/example-ant/ant-test.c index 56ccee8be..c3e5b7da1 100644 --- a/MSP-EXP430F5438-CC256x/example-ant/ant-test.c +++ b/MSP-EXP430F5438-CC256x/example-ant/ant-test.c @@ -167,10 +167,12 @@ static void heartbeat_handler(struct timer *ts){ char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n\r", ++counter); printf(lineBuffer); - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); - if (err) { - printf("rfcomm_send_internal -> error %d", err); - } + if (rfcomm_can_send_packet_now(rfcomm_channel_id)){ + err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); + if (err) { + printf("rfcomm_send_internal -> error %d", err); + } + } } run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); diff --git a/MSP-EXP430F5438-CC256x/example/spp_accel.c b/MSP-EXP430F5438-CC256x/example/spp_accel.c index 7203a9af6..dcf9e8459 100644 --- a/MSP-EXP430F5438-CC256x/example/spp_accel.c +++ b/MSP-EXP430F5438-CC256x/example/spp_accel.c @@ -69,6 +69,20 @@ static void prepare_accel_packet(){ printf("Accel: X: %04d, Y: %04d, Z: %04d\n\r", accl_x, accl_y, accl_z); } +static void send_packet(){ + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); + switch(err){ + case 0: + prepare_accel_packet(); + break; + case BTSTACK_ACL_BUFFERS_FULL: + break; + default: + printf("rfcomm_send_internal() -> err %d\n\r", err); + break; + } +} + // Bluetooth logic static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; @@ -135,19 +149,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha case DAEMON_EVENT_HCI_PACKET_SENT: case RFCOMM_EVENT_CREDITS: - if (!rfcomm_channel_id) break; - // try send - err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); - switch (err){ - case 0: - prepare_accel_packet(); - break; - case BTSTACK_ACL_BUFFERS_FULL: - break; - default: - printf("rfcomm_send_internal() -> err %d\n\r", err); - break; - } + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); break; case RFCOMM_EVENT_CHANNEL_CLOSED: diff --git a/MSP-EXP430F5438-CC256x/example/spp_counter.c b/MSP-EXP430F5438-CC256x/example/spp_counter.c index 159544c7d..e18faf6f9 100644 --- a/MSP-EXP430F5438-CC256x/example/spp_counter.c +++ b/MSP-EXP430F5438-CC256x/example/spp_counter.c @@ -43,8 +43,7 @@ static int counter_to_send = 0; enum STATE {INIT, W4_CONNECTION, W4_CHANNEL_COMPLETE, ACTIVE} ; enum STATE state = INIT; -static void tryToSend(void){ - if (!rfcomm_channel_id) return; +static void send_packet(void){ if (real_counter <= counter_to_send) return; char lineBuffer[30]; @@ -129,7 +128,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha break; case DAEMON_EVENT_HCI_PACKET_SENT: case RFCOMM_EVENT_CREDITS: - tryToSend(); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); break; case RFCOMM_EVENT_CHANNEL_CLOSED: @@ -152,7 +151,7 @@ static void timer_handler(timer_source_t *ts){ real_counter++; // re-register timer run_loop_register_timer(ts, HEARTBEAT_PERIOD_MS); - tryToSend(); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); } static void timer_setup(){ diff --git a/eZ430-RF2560/example/spp_accel.c b/eZ430-RF2560/example/spp_accel.c index 7f11b9439..f1a78d964 100644 --- a/eZ430-RF2560/example/spp_accel.c +++ b/eZ430-RF2560/example/spp_accel.c @@ -98,6 +98,20 @@ static void prepare_accel_packet(){ printf("Accel: X: %04d, Y: %04d, Z: %04d\n\r", accl_x, accl_y, accl_z); } +static void send_packet(void){ + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); + switch (err){ + case 0: + prepare_accel_packet(); + break; + case BTSTACK_ACL_BUFFERS_FULL: + break; + default: + printf("rfcomm_send_internal -> error 0X%02x", err); + break; + } +} + // Bluetooth logic static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ bd_addr_t event_addr; @@ -166,19 +180,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha case DAEMON_EVENT_HCI_PACKET_SENT: case RFCOMM_EVENT_CREDITS: - if (!rfcomm_channel_id) break; - // try send - err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t *)accel_buffer, sizeof(accel_buffer)); - switch (err){ - case 0: - prepare_accel_packet(); - break; - case BTSTACK_ACL_BUFFERS_FULL: - break; - default: - printf("rfcomm_send_internal() -> err %d\n\r", err); - break; - } + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); break; case RFCOMM_EVENT_CHANNEL_CLOSED: diff --git a/eZ430-RF2560/example/spp_counter.c b/eZ430-RF2560/example/spp_counter.c index 5619edd0d..a0ffe875e 100644 --- a/eZ430-RF2560/example/spp_counter.c +++ b/eZ430-RF2560/example/spp_counter.c @@ -120,9 +120,11 @@ static void heartbeat_handler(struct timer *ts){ char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n\r", ++counter); printf(lineBuffer); - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); - if (err) { - printf("rfcomm_send_internal -> error %d", err); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) { + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); + if (err) { + printf("rfcomm_send_internal -> error %d", err); + } } } diff --git a/example/libusb/classic_test.c b/example/libusb/classic_test.c index 7d0cf2ba8..5392cddbc 100644 --- a/example/libusb/classic_test.c +++ b/example/libusb/classic_test.c @@ -375,16 +375,15 @@ void handle_query_rfcomm_event(sdp_query_event_t * event, void * context){ } void heartbeat_handler(struct timer *ts){ - if (rfcomm_channel_id){ static int counter = 0; char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n\r", ++counter); puts(lineBuffer); - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); - if (err) { - printf("rfcomm_send_internal -> error 0X%02x", err); - } + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) { + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); + if (err) printf("rfcomm_send_internal -> error 0X%02x", err); + } } run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); diff --git a/example/libusb/spp_and_le_counter.c b/example/libusb/spp_and_le_counter.c index 67d2f0573..4b65a8bf1 100644 --- a/example/libusb/spp_and_le_counter.c +++ b/example/libusb/spp_and_le_counter.c @@ -199,11 +199,13 @@ static void heartbeat_handler(struct timer *ts){ counter_string_len = sprintf(counter_string, "BTstack counter %04u\n", counter); if (rfcomm_channel_id){ - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) counter_string, counter_string_len); - if (err) { - log_error("rfcomm_send_internal -> error 0X%02x", err); - } else { - printf("%s", counter_string); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) { + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) counter_string, counter_string_len); + if (err) { + log_error("rfcomm_send_internal -> error 0X%02x", err); + } else { + printf("%s", counter_string); + } } } diff --git a/example/libusb/spp_counter.c b/example/libusb/spp_counter.c index bc0a9e6cf..02929cee8 100644 --- a/example/libusb/spp_counter.c +++ b/example/libusb/spp_counter.c @@ -122,10 +122,12 @@ static void heartbeat_handler(struct timer *ts){ char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n", ++counter); printf("%s", lineBuffer); - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); - if (err) { - log_error("rfcomm_send_internal -> error 0X%02x", err); - } + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) { + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); + if (err) { + log_error("rfcomm_send_internal -> error 0X%02x", err); + } + } } run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); diff --git a/example/libusb/spp_streamer.c b/example/libusb/spp_streamer.c index f065003a2..fddc015f9 100644 --- a/example/libusb/spp_streamer.c +++ b/example/libusb/spp_streamer.c @@ -59,10 +59,13 @@ static void create_test_data(void){ } } -static void try_send(){ - if (!rfcomm_cid) return; +static void send_packet(){ int err = rfcomm_send_internal(rfcomm_cid, (uint8_t*) test_data, test_data_len); - if (err) return; + if (err){ + printf("rfcomm_send_internal -> error 0X%02x", err); + return; + } + if (data_to_send < test_data_len){ rfcomm_disconnect_internal(rfcomm_cid); rfcomm_cid = 0; @@ -98,13 +101,13 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha if ((test_data_len > mtu)) { test_data_len = mtu; } - try_send(); + if (rfcomm_can_send_packet_now(rfcomm_cid)) send_packet(); break; } break; case DAEMON_EVENT_HCI_PACKET_SENT: case RFCOMM_EVENT_CREDITS: - try_send(); + if (rfcomm_can_send_packet_now(rfcomm_cid)) send_packet(); break; default: break; diff --git a/platforms/stm32-f103rb-nucleo/spp_and_le_counter.c b/platforms/stm32-f103rb-nucleo/spp_and_le_counter.c index d64833367..fb1dabd34 100644 --- a/platforms/stm32-f103rb-nucleo/spp_and_le_counter.c +++ b/platforms/stm32-f103rb-nucleo/spp_and_le_counter.c @@ -200,9 +200,11 @@ static void heartbeat_handler(struct timer *ts){ // printf("%s", counter_string); if (rfcomm_channel_id){ - int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) counter_string, counter_string_len); - if (err) { - log_error("rfcomm_send_internal -> error 0X%02x", err); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)){ + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) counter_string, counter_string_len); + if (err) { + log_error("rfcomm_send_internal -> error 0X%02x", err); + } } } diff --git a/platforms/stm32-f103rb-nucleo/spp_counter.c b/platforms/stm32-f103rb-nucleo/spp_counter.c index 089238d51..61185273a 100644 --- a/platforms/stm32-f103rb-nucleo/spp_counter.c +++ b/platforms/stm32-f103rb-nucleo/spp_counter.c @@ -36,25 +36,17 @@ static int counter_to_send = 0; enum STATE {INIT, W4_CONNECTION, W4_CHANNEL_COMPLETE, ACTIVE} ; enum STATE state = INIT; -static void tryToSend(void){ - if (!rfcomm_channel_id) return; +static void send_packet(void){ if (real_counter <= counter_to_send) return; char lineBuffer[30]; sprintf(lineBuffer, "BTstack counter %04u\n\r", counter_to_send); printf(lineBuffer); + int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); - - switch (err){ - case 0: - counter_to_send++; - break; - case BTSTACK_ACL_BUFFERS_FULL: - break; - default: - printf("rfcomm_send_internal() -> err %d\n\r", err); - break; - } + if (err) return; + + counter_to_send++; } // Bluetooth logic @@ -122,7 +114,7 @@ static void packet_handler (void * connection, uint8_t packet_type, uint16_t cha break; case DAEMON_EVENT_HCI_PACKET_SENT: case RFCOMM_EVENT_CREDITS: - tryToSend(); + if (rfcomm_can_send_packet_now(rfcomm_channel_id)) send_packet(); break; case RFCOMM_EVENT_CHANNEL_CLOSED: @@ -145,7 +137,6 @@ static void timer_handler(timer_source_t *ts){ real_counter++; // re-register timer run_loop_register_timer(ts, HEARTBEAT_PERIOD_MS); - tryToSend(); } // main diff --git a/src/rfcomm.c b/src/rfcomm.c index aeafddb80..4f5673331 100644 --- a/src/rfcomm.c +++ b/src/rfcomm.c @@ -1989,6 +1989,21 @@ void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t p int rfcomm_can_send_packet_now(uint16_t rfcomm_cid){ rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid); + if (!channel){ + log_error("rfcomm_send_internal cid 0x%02x doesn't exist!", rfcomm_cid); + return 0; + } + if (!channel->credits_outgoing) return 0; + if (!channel->packets_granted) return 0; + if ((channel->multiplexer->fcon & 1) == 0) return 0; + + return l2cap_can_send_packet_now(channel->multiplexer->l2cap_cid); +} + +// send packet over specific channel +int rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){ + rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid); + if (!channel){ log_error("rfcomm_send_internal cid 0x%02x doesn't exist!", rfcomm_cid); return 1; @@ -2008,18 +2023,7 @@ int rfcomm_can_send_packet_now(uint16_t rfcomm_cid){ log_info("rfcomm_send_internal cid 0x%02x, aggregate flow off!", rfcomm_cid); return RFCOMM_AGGREGATE_FLOW_OFF; } - // log_info("rfcomm_send_internal: len %u... outgoing credits %u, l2cap credit %us, granted %u", - // len, channel->credits_outgoing, channel->multiplexer->l2cap_credits, channel->packets_granted); - return 0; -} -// send packet over specific channel -int rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){ - int err = rfcomm_can_send_packet_now(rfcomm_cid); - if (err) return err; - - rfcomm_channel_t * channel = rfcomm_channel_for_rfcomm_cid(rfcomm_cid); - // send might cause l2cap to emit new credits, update counters first channel->credits_outgoing--; int packets_granted_decreased = 0; diff --git a/src/rfcomm.h b/src/rfcomm.h index 104908a9e..312b88bf2 100644 --- a/src/rfcomm.h +++ b/src/rfcomm.h @@ -405,7 +405,7 @@ void rfcomm_decline_connection_internal(uint16_t rfcomm_cid); // Grant more incoming credits to the remote side for the given RFCOMM channel identifier. void rfcomm_grant_credits(uint16_t rfcomm_cid, uint8_t credits); -// Chekcs if RFCOMM can send packet. If yes returns 0, otherwise returns an error code. +// Checks if RFCOMM can send packet. Returns yes if packet can be sent. int rfcomm_can_send_packet_now(uint16_t rfcomm_cid); // Sends RFCOMM data packet to the RFCOMM channel with given identifier.