void l2cap_hand_out_credits(void){ if (new_credits_blocked) return; // we're told not to. used by daemon linked_item_t *it; for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){ if (!hci_number_free_acl_slots()) return; l2cap_channel_t * channel = (l2cap_channel_t *) it; if (channel->state != L2CAP_STATE_OPEN) continue; if (hci_number_outgoing_packets(channel->handle) < NR_BUFFERED_ACL_PACKETS && channel->packets_granted == 0) { l2cap_emit_credits(channel, 1); } } }
int hci_send_acl_packet(uint8_t *packet, int size){ // check for free places on BT module if (!hci_number_free_acl_slots()) return BTSTACK_ACL_BUFFERS_FULL; hci_con_handle_t con_handle = READ_ACL_CONNECTION_HANDLE(packet); hci_connection_t *connection = connection_for_handle( con_handle); if (!connection) return 0; hci_connection_timestamp(connection); // count packet connection->num_acl_packets_sent++; // log_info("hci_send_acl_packet - handle %u, sent %u\n", connection->con_handle, connection->num_acl_packets_sent); // send packet int err = hci_stack.hci_transport->send_packet(HCI_ACL_DATA_PACKET, packet, size); return err; }
int hci_can_send_packet_now(uint8_t packet_type){ // check for async hci transport implementations if (hci_stack.hci_transport->can_send_packet_now){ if (!hci_stack.hci_transport->can_send_packet_now(packet_type)){ return 0; } } // check regular Bluetooth flow control switch (packet_type) { case HCI_ACL_DATA_PACKET: return hci_number_free_acl_slots(); case HCI_COMMAND_DATA_PACKET: return hci_stack.num_cmd_packets; default: return 0; } }