Establish an acl connection


The process of establishing an acl connection begins in the server or client module.

when one of both initiates they both call the same function, billotooth_connect, which initiates the connection establishment. These are the steps viewed from the initiator perspective:

 

billotooth_connect

 

- this function requires e bdadress_t structure with the appropriate BD_ADDR of the intended device which you want to connect. The then returns a hci_conn structure to handle further transmission.

- when the billotooth_connect begins it checks the connection hash list (conn_hash_lookup_ba) of the device to find if we already established such  connection. Since it's the first time, of course not, so it proceeds to the billotooth_create_connection.

- the result is then used to send the connect command via billotooth_acl_connect.

 

billotooth_create_connection

 

- To create a connection it allocates memory for a hci_conn structure. Then th function fills it accordingly:

The field dst receives the bdaddr_t structures passed along. Then is set the connection type to ACL_LINK; so far, only ACL is supported. The device is also put on the hci_conn structure at conn->hdev. Finally th state is set to BT_OPEN. After this the connection is added to the connection hash list and returned as the result.

 

billotooth_acl_connect

 

With the newly formed hci_conn structure this function then proceeds to the preparations to send the connect command. The state is set to BT_CONNECT, the connection is set as a outgoing and the link mode is set to HCI_LM_MASTER. Since we're establishing the connection might as well be the master.

Then we search through the inquiry list for information on the device we're about to connect. This is done with the billotooth_inquiry_lookup function.

Since we inquired the surrounding devices first, it's expected that the device we're trying to connect is already on the list.  So the collect the page scan repetition mode, page scan mode and clock offset gathered in the inquiry process.
Then we set the package type to acl packet type and the role switch as 0x01. After this it sends to another function that will prep it to send the frame down the pipe: billotooth_send_cmd(OGF_LINK_CTL, OCF_CREATE_CONN,
CREATE_CONN_CP_SIZE, &cp); where cp is a structure with the parameters set.

 

billotooth_send_cmd

- this function receives the OCF and OGF codes, the parameter length and the actual parameter and packs it all in a sk_buffer representing the hci command packet. The packet type is set and the new formed frame is sent to the hci_usb layer via billotooth_send_frame.

- it generates a response via a command complete event as soon as it's completed.

 

billotooth_send_frame

- this function takes out the owner field of the skb frame and passes to the hci_usb layer.

 

By now the connection request is on the way and we have to wait for the connection complete event. This event arrives after both devices negotiate the connection transaction, and both ends receive it.

 

billotooth_recv_frame

- this function receives an incoming frame in the form of a sk_buffer. It then look in the packet type field of the skb frame and switches to the appropriate function.

 

In this case the connection complete event is, obviously, an event packet, so the billotooth_recv_frame calls the billotooth_event_packet function.

 

billotooth_event_packet

- this function, much like the billotooth_recv_frame hadles the event packets analysing their type. In our case the ((hci_event_hdr *) skb->data)->evt is an EVT_CONN_COMPLETE(0x03) so the message is passed along to the billotooth_conn_complete_evt

 

billotooth_conn_complete_evt

- this function receives a sk_buffer frame and then look into the connection hash list to see if the connection is already there, just in case something went wrong. If it's already there like expected then it starts altering the state of the connection to BT_CONNECTED, and saving the connection handle to the hci_conn.

- After this it proceed to set the packet type for the incoming connection, and for this it takes the change_conn_ptype_cp command parameter structure and set its fields to the appropriate handle and the paket type to ACL_LINK. Then it sends to the billotooth_send_cmd function with these parameters: OGF_LINK_CTL(0x01), OCF_CHANGE_CONN_PTYPE(0x000F), CHANGE_CONN_PTYPE_CP_SIZE(4) and the parameters showed above.
 

From this moment on the connection is established.

 

Now for the receiver perspective:

billotooth_recv_frame

- this function receives an incoming frame in the form of a sk_buffer. It then look in the packet type field of the skb frame and switches to the appropriate function.

 

In this case the connection complete event is, obviously, an event packet, so the billotooth_recv_frame calls the billotooth_event_packet function.

 

billotooth_event_packet

- this function, much like the billotooth_recv_frame hadles the event packets analyzing their type. In our case the ((hci_event_hdr *) skb->data)->evt is an EVT_CONN_REQUEST(0x04) so the message is passed along to the billotooth_conn_request_evt

 

billotooth_conn_request_evt

- this function receives the connection request event packet and looks in the connection hash list to see if we already have such connection. if so, we just return the hci_conn structure and go on, but if we do not have then we must create a connection with the billotooth_create_connection function.

- after having the appropriate connection done, it chages the connection state to BT_CONNECT, and fills the accept_conn_req_cp command parameter structure with the bdaddress provided by the connection request event and set its role to slave, since it didn't initiate the connection. With this done it sends a billotooth_send_cmd function with these parameters: OGF_LINK_CTL(0x01), OCF_ACCEPT_CONN_REQ(0x0009), ACCEPT_CONN_REQ_CP_SIZE(7) and the parameters showed above.

- this will result in a connection complete event later on.

 

billotooth_recv_frame

- this function receives an incoming frame in the form of a sk_buffer. It then look in the packet type field of the skb frame and switches to the appropriate function.

 

In this case the connection complete event is, obviously, an event packet, so the billotooth_recv_frame calls the billotooth_event_packet function.

 

billotooth_event_packet

- this function, much like the billotooth_recv_frame hadles the event packets analyzing their type. In our case the ((hci_event_hdr *) skb->data)->evt is an EVT_CONN_COMPLETE(0x03) so the message is passed along to the billotooth_conn_complete_evt

 

billotooth_conn_complete_evt

- this function receives a sk_buffer frame and then look into the connection hash list to see if the connection is already there, just in case something went wrong. If it's already there like expected then it starts altering the state of the connection to BT_CONNECTED, and saving the connection handle to the hci_conn.

- After this it proceed to set the packet type for the incoming connection, and for this it takes the change_conn_ptype_cp command parameter structure and set its fields to the appropriate handle and the packet type to ACL_LINK. Then it sends to the billotooth_send_cmd function with these parameters: OGF_LINK_CTL(0x01), OCF_CHANGE_CONN_PTYPE(0x000F), CHANGE_CONN_PTYPE_CP_SIZE(4) and the parameters showed above.
 

From this moment on the connection is established.