Bluetooth L2CAP Layer. More...
#include "l2cap.h"#include "hci.h"#include "powerblocks/core/utils/log.h"#include "FreeRTOS.h"#include "task.h"#include "semphr.h"#include "blerror.h"#include <stdlib.h>#include <string.h>#include <endian.h>#include <stdalign.h>Macros | |
| #define | L2CAP_TASK_STACK_SIZE 8192 |
| #define | L2CAP_TASK_PRIORITY (configMAX_PRIORITIES / 4 * 3) |
| #define | L2CAP_SIGNAL_TIMEOUT 1000 |
| #define | L2CAP_ERROR_LOGGING |
| #define | L2CAP_INFO_LOGGING |
| #define | L2CAP_LOG_ERROR(fmt, ...) |
| #define | L2CAP_LOG_INFO(fmt, ...) |
| #define | L2CAP_LOG_DEBUG(fmt, ...) |
| #define | L2CAP_SIGNAL_CODE_REJECT 0x01 |
| #define | L2CAP_SIGNAL_CODE_CONNECTION_REQUEST 0x02 |
| #define | L2CAP_SIGNAL_CODE_CONNECTION_RESPONSE 0x03 |
| #define | L2CAP_SIGNAL_CODE_CONFIGURE_REQUEST 0x04 |
| #define | L2CAP_SIGNAL_CODE_CONFIGURE_RESPONSE 0x05 |
| #define | L2CAP_SIGNAL_CODE_DISCONNECTION_REQUEST 0x06 |
| #define | L2CAP_SIGNAL_CODE_DISCONNECTION_RESPONSE 0x07 |
| #define | L2CAP_SIGNAL_CODE_ECHO_REQUEST 0x08 |
| #define | L2CAP_SIGNAL_CODE_ECHO_RESPONSE 0x09 |
| #define | L2CAP_SIGNAL_CODE_INFORMATION_REQUEST 0x0A |
| #define | L2CAP_SIGNAL_CODE_INFORMATION_RESPONSE 0x0B |
Functions | |
| int | l2cap_initialize () |
| Initalized L2CAP. | |
| void | l2cap_signal_close () |
| Begins closing out of L2CAP. | |
| void | l2cap_close () |
| Closes out of L2CAP. | |
| int | l2cap_open_device (l2cap_device_t *device_handle, uint16_t hci_device_handle, const uint8_t *mac_address) |
| Opens a L2CAP Connections. | |
| void | l2cap_close_device (l2cap_device_t *device_handle) |
| Closes a L2CAP Connection. | |
| int | l2cap_open_channel (l2cap_device_t *device_handle, l2cap_channel_t *channel, uint16_t protocol_id, uint8_t *rx_buffer, int rx_buffer_size) |
| Opens a L2CAP Channel. | |
| void | l2cap_close_channel (l2cap_channel_t *channel) |
| Closes a L2CAP Channel. | |
| int | l2cap_send_channel (l2cap_channel_t *channel, const void *data, uint16_t size) |
| Sends data over a L2CAP Channel. | |
| int | l2cap_receive_channel (l2cap_channel_t *channel, void *data, uint16_t size) |
| Receives from a L2CAP Channel. | |
| void | l2cap_set_channel_receive_event (l2cap_channel_t *channel, l2cap_channel_event_t event, void *param) |
| Sets the L2CAP on packet receive event. | |
| void | l2cap_task_write_channel_buffer (l2cap_channel_t *channel, const uint8_t *buffer, size_t size) |
Variables | |
| int | round = 0 |
Bluetooth L2CAP Layer.
L2CAP is a higher level ontop of HCI's ACI packets used to send and receive data from devices.
Its in charge of multiplexing data and reassembling/disassembling packets.
| #define L2CAP_LOG_ERROR | ( | fmt, | |
| ... ) |
| #define L2CAP_LOG_INFO | ( | fmt, | |
| ... ) |
| void l2cap_close | ( | ) |
Closes out of L2CAP.
Must come after l2cap_signal_close and the HCI is closed. Will wait for the task to exit.
| void l2cap_close_channel | ( | l2cap_channel_t * | channel | ) |
Closes a L2CAP Channel.
Closes a channel and frees its resources.
This will automatically be done for any remaining open channels when calling l2cap_close_device.
| channel | Channel to close. |
| void l2cap_close_device | ( | l2cap_device_t * | device_handle | ) |
Closes a L2CAP Connection.
Frees a L2CAP device and closes and frees all associated open channels.
| device_handle | L2CAP device to close |
| int l2cap_initialize | ( | ) |
Initalized L2CAP.
Its recommended this is called after hci_initialize but before working with any bluetooth devices.
This allows you to use L2CAP once a connection has been established.
| int l2cap_open_channel | ( | l2cap_device_t * | device_handle, |
| l2cap_channel_t * | channel, | ||
| uint16_t | protocol_id, | ||
| uint8_t * | rx_buffer, | ||
| int | rx_buffer_size ) |
Opens a L2CAP Channel.
Once a device is open, channels can be opened and closed. Channels are much like sockets, and each one has its own protocol.
By default, the signal channel is already open and used by L2CAP.
| device_handle | L2CAP device to open the channel on |
| channel | Channel data structure to write into |
| protocol_id | Protocol of the channel. Like the socket. |
| rx_buffer | The receiving buffer for the channel. |
| rx_buffer_size | Size of the receiving buffer. Must be a power of 2. |
| int l2cap_open_device | ( | l2cap_device_t * | device_handle, |
| uint16_t | hci_device_handle, | ||
| const uint8_t * | mac_address ) |
Opens a L2CAP Connections.
Sets up L2CAP to communicate with a device. This sets up the default signal channel L2CAP uses, and adds the device to L2CAPS list of active devices.
| device_handle | L2CAP Device Handle To Create |
| hci_device_handle | Device handle created by hci_create_connection |
| mac_address | MAC address of the device. Used to prevent duplicate connections. |
| int l2cap_receive_channel | ( | l2cap_channel_t * | channel, |
| void * | data, | ||
| uint16_t | size ) |
Receives from a L2CAP Channel.
Receives data from the internal buffer specified when creating the channel.
The buffer is treated as a FIFO and can hold multiple packets. In the event of an overflow, packet truncation and packet drops are logged and this will just return truncated or 0 byte packets.
Packets should never be truly lost, just that you will have saved up a bunch of 0 byte packets.
Will error on incomplete FIFO fragments.
| channel | Channel to talk to |
| data | Data Buffer |
| size | Size of buffer. Up to 65535. |
| int l2cap_send_channel | ( | l2cap_channel_t * | channel, |
| const void * | data, | ||
| uint16_t | size ) |
Sends data over a L2CAP Channel.
Sends a buffer over a L2CAP channel. Channels in L2CAP can be thought of as a lot like sockets. One device can run multiple protocols, and we expect to see specific protocols on specific channels.
| channel | Channel to talk to |
| data | Data Buffer |
| size | Size of data. Up to 65535. |
| void l2cap_set_channel_receive_event | ( | l2cap_channel_t * | channel, |
| l2cap_channel_event_t | event, | ||
| void * | param ) |
Sets the L2CAP on packet receive event.
When a packet is received on a channel, this event will be called to receive it if you please.
| channel | Channel to set it in |
| event | Event Handler |
| param | Parameter passed to event. |
| void l2cap_signal_close | ( | ) |
Begins closing out of L2CAP.
I don't currently have a good way to cancel the blocking ACL read from it, so this will signal the thread to begin exiting. Once HCI is closed, it will actually exist.