[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bluetooth-dev] hci_ctrl.nbr_of_connections handled incorrectly



In some cases, the HCI variable hci_ctrl.nbr_of_connections is not 
decreased when it should be. The case is:
- a master pages a slave
- the master establishes an L2CAP connection to the slave
- l2ca_disconnect_req() is called on the master's side.

When the L2CAP disconnect message is received by the slave, it replies by 
calling l2ca_disconnect_rsp() on its side. In this function, the lines

if (count_con(con->hci_hdl) > 1) {
                                                 delete_con(con); 
                                 }

are executed: the last L2CAP connection is not deleted.

When the master receives the L2CAP disconnect response message, the wait 
queue at l2ca_disconnect_req is woken up and

                 delete_con(con);

is always called. SInce this is the last L2CAP connection on this HCI 
handle, lp_disconnect() is called on the master's side.

Now, DISCONNECTION_COMPLETE events occur on both the master's and the 
slave's side. process_event() in hci.c executes the code

                                 if (lp_disconnect_ind(hci_hdl))
                                                 if (hci_ctrl.nbr_of_connections > 0) {
 hci_ctrl.nbr_of_connections--;
 hci_update_load_factor();
                                                 }

lp_disconnect_ind() returns the number of L2CAP connections on the HCI 
handle. On the slave's side, it returns 1 (because the closed L2CAP 
connection has not been deleted yet). On the master's side, it returns 0 
(because the closed L2CAP connection has been deleted). So, on the slave's 
side, hci_ctrl.nbr_of_connections is not decreased as it should.

A possible workaround is: l2ca_disconnect_req() should not delete the last 
connection, instead it should let lp_disconnect_ind() delete it.
The code
                 delete_con(con);
 
                 /* If this is the last l2cap-session on the baseband connection we
                    disconnect the baseband as well */
                 if (count_con(tmp_hdl) == 0) {
                                 DSYS("l2ca_disconnect_req : (C) no more l2cap cons\n");
                                 DSYS("Shutdown baseband\n");
                                 lp_disconnect(tmp_hdl);
                 }

should be replaced with
                 if (count_con(tmp_hdl) > 1)
                        delete_con(con);
                 else {
                 /* If this is the last l2cap-session on the baseband connection we
                    disconnect the baseband as well */
                                 DSYS("l2ca_disconnect_req : (C) no more l2cap cons\n");
                                 DSYS("Shutdown baseband\n");
                                 lp_disconnect(tmp_hdl);
                 }


What do you think about this?

Fabrizio Gennari
Philips Research Monza
via G.Casati 23, 20052 Monza (MI), Italy
tel. +39 039 2037816, fax +39 039 2037800
-
To unsubscribe from this list: send the line "unsubscribe bluetooth-dev" in
the body of a message to majordomo@xxxxxxx.com