PowerBlocks SDK
 
Loading...
Searching...
No Matches
hci.c File Reference

Bluetooth HCI Driver. More...

#include "hci.h"
#include "powerblocks/core/system/system.h"
#include "powerblocks/core/ios/ios.h"
#include "powerblocks/core/utils/log.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "blerror.h"
#include <string.h>
#include <stdalign.h>
#include <endian.h>

Classes

struct  hci_event
 
struct  hci_local_version_information_t
 
struct  hci_command_request
 
struct  hci_command_buffer
 

Macros

#define USB_ALIGN   32
 
#define HCI_TASK_STACK_SIZE   8192
 
#define HCI_TASK_PRIORITY   (configMAX_PRIORITIES / 4 * 3)
 
#define HCI_ERROR_LOGGING
 
#define HCI_LOG_ERROR(tab, fmt, ...)
 
#define HCI_LOG_INFO(tab, fmt, ...)
 
#define HCI_LOG_DEBUG(tab, fmt, ...)
 
#define HCI_MAX_COMMAND_DATA_LENGTH   64
 
#define HCI_MAX_EVENT_LENGTH   255
 
#define HCI_WAITER_TIMEOUT   6000
 
#define HCI_IOS_IOCTL_USB_CONTROL   0
 
#define HCI_IOS_IOCTL_USB_BULK   1
 
#define HCI_IOS_IOCTL_USB_INTERRUPT   2
 
#define HCI_ENDPOINT_CONTROL   0x00
 
#define HCI_ENDPOINT_ACL_OUT   0x02
 
#define HCI_ENDPOINT_EVENTS   0x81
 
#define HCI_ENDPOINT_ACL_IN   0x82
 
#define HCI_EVENT_CODE_INQUIRY_COMPLETE   0x01
 
#define HCI_EVENT_CODE_INQUIRY_RESULT   0x02
 
#define HCI_EVENT_CONNECTION_COMPLETE   0x03
 
#define HCI_EVENT_CODE_REMOTE_NAME_REQUEST_COMPLETE   0x07
 
#define HCI_EVENT_CODE_COMMAND_COMPLETE   0x0E
 
#define HCI_EVENT_CODE_COMMAND_STATUS   0x0F
 
#define HCI_EVENT_HARDWARE_ERROR   0x10
 
#define HCI_EVENT_ACL_NUMBER_OF_COMPLETE_PACKETS   0x13
 
#define HCI_OPCODE_READ_LOCAL_VERSION_INFORMATION   0x1001
 
#define HCI_OPCODE_READ_LOCAL_SUPPORTED_FEATURES   0x1003
 
#define HCI_OPCODE_READ_BUFFER_SIZE   0x1005
 
#define HCI_OPCODE_READ_BD_ADDR   0x1009
 
#define HCI_OPCODE_INQUIRY_START   0x0401
 
#define HCI_OPCODE_INQUIRY_CANCEL   0x0402
 
#define HCI_OPCODE_CREATE_CONNECTION   0x0405
 
#define HCI_OPCODE_REMOTE_NAME_REQUEST   0x0419
 
#define HCI_OPCODE_SET_EVENT_MASK   0x0C01
 
#define HCI_OPCODE_RESET   0x0C03
 

Enumerations

enum  hci_event_id_t {
  HCI_EVENT_ID_INQUIRY_COMPLETE = 0 , HCI_EVENT_ID_INQUIRY_RESULT = 1 , HCI_EVENT_ID_CONNECTION_COMPLETE = 2 , HCI_EVENT_ID_CONNECTION_REQUEST = 3 ,
  HCI_EVENT_ID_DISCONNECTION_COMPLETE = 4 , HCI_EVENT_ID_AUTHENTICATION_COMPLETE = 5 , HCI_EVENT_ID_REMOTE_NAME_REQUEST = 6 , HCI_EVENT_ID_ENCRYPTION_CHANGE = 7 ,
  HCI_EVENT_ID_CHANGE_CONNECTION_LINK_KEY_COMPLETE = 8 , HCI_EVENT_ID_MASTER_LINK_KEY_COMPLETE = 9 , HCI_EVENT_ID_READ_REMOTE_SUPPORTED_FEATURES_COMPLETE = 10 , HCI_EVENT_ID_READ_REMOTE_VERSION_INFORMATION_COMPLETE = 11 ,
  HCI_EVENT_ID_QOS_SETUP_COMPLETE = 12 , HCI_EVENT_ID_HARDWARE_ERROR = 15 , HCI_EVENT_ID_FLUSH_OCCURRED = 16 , HCI_EVENT_ID_ROLE_CHANGE = 17 ,
  HCI_EVENT_ID_MODE_CHANGE = 19 , HCI_EVENT_ID_RETURN_LINK_KEYS = 20 , HCI_EVENT_ID_PIN_CODE_REQUEST = 21 , HCI_EVENT_ID_LINK_KEY_REQUEST = 22 ,
  HCI_EVENT_ID_LINK_KEY_NOTIFICATION = 23 , HCI_EVENT_ID_LOOPBACK_COMMAND = 24 , HCI_EVENT_ID_DATA_BUFFER_OVERFLOW = 25 , HCI_EVENT_ID_MAX_SLOTS_CHANGE = 26 ,
  HCI_EVENT_ID_READ_CLOCK_OFFSET_COMPLETE = 27 , HCI_EVENT_ID_CONNECTION_PACKET_TYPE_CHANGED = 28 , HCI_EVENT_ID_QOS_VIOLATION = 29 , HCI_EVENT_ID_PAGE_SCAN_MODE_CHANGE = 30 ,
  HCI_EVENT_ID_PAGE_SCAN_REPETITION_MODE_CHANGE = 31 , HCI_EVENT_ID_FLOW_SPECIFICATION_COMPLETE = 32 , HCI_EVENT_ID_INQUIRY_RESULT_WITH_RSSI = 33 , HCI_EVENT_ID_READ_REMOTE_EXTENDED_FEATURES_COMPLETE = 34 ,
  HCI_EVENT_ID_SYNCHRONOUS_CONNECTION_COMPLETE = 43 , HCI_EVENT_ID_SYNCHRONOUS_CONNECTED_CHANGED = 44 , HCI_EVENT_ID_SNIFF_SUBRATING = 45 , HCI_EVENT_ID_EXTENDED_INQUIRY_RESULT = 46 ,
  HCI_EVENT_ID_ENCRYPTION_KEY_REFRESH_COMPLETE = 47 , HCI_EVENT_ID_IO_CAPABILITY_REQUEST = 48 , HCI_EVENT_ID_IO_CAPABILITY_REQUEST_REPLY = 49 , HCI_EVENT_ID_USER_CONFIRMATION_REQUEST = 50 ,
  HCI_EVENT_ID_USER_PASSKEY_REQUEST = 51 , HCI_EVENT_ID_REMOTE_OOB_DATA_REQUEST = 52 , HCI_EVENT_ID_SIMPLE_PAIRING_COMPLETE = 53 , HCI_EVENT_ID_LINK_SUPERVISION_TIMEOUT_CHANGED = 55 ,
  HCI_EVENT_ID_ENHANCED_FLUSH_COMPLETE = 56 , HCI_EVENT_ID_USER_PASSKEY_NOTIFICATION = 58 , HCI_EVENT_ID_KEYPRESS_NOTIFICATION_EVENT = 59 , HCI_EVENT_ID_REMOTE_HOST_SUPPORTED_FEATURES = 60
}
 

Functions

int hci_initialize (const char *device)
 Initializes the HCI interface.
 
void hci_close ()
 Closes the HCI driver.
 
int hci_reset ()
 Resets the HCI Interface.
 
int hci_begin_discovery (uint32_t lap, uint8_t length, uint8_t responses, hci_discovered_device_handler on_discovered, hci_discovery_complete_handler on_complete, void *user_data)
 Begins looking for bluetooth devices.
 
int hci_cancel_discovery ()
 Stops a discovery session.
 
int hci_get_remote_name (const hci_discovered_device_info_t *device, uint8_t *name)
 Returns the remote name of a device.
 
int hci_create_connection (const hci_discovered_device_info_t *device, uint16_t *handle)
 Creates a connection to a device for you to use.
 
int hci_send_acl (uint16_t handle, hci_acl_packet_boundary_flag_t pb, hci_acl_packet_broadcast_flag_t bc, uint16_t length)
 Sends a ACL Packet.
 
int hci_receive_acl_async (hci_acl_packet_t *acl_buffer, uint8_t *ipc_buffer, ipc_async_handler_t handler, void *params)
 Receives a ACL Packet Asynchronously.
 
void hci_decode_received_acl (uint16_t *handle, hci_acl_packet_boundary_flag_t *pb, hci_acl_packet_broadcast_flag_t *bc, uint16_t *length, const hci_acl_packet_t *acl_buffer)
 Decodes a received ACL packet.
 
hci_event hci_event_buffer MEM2 ALIGN (32) = "/shared2/sys/SYSCONF"
 

Variables

hci_buffer_sizes_t hci_buffer_sizes
 
SemaphoreHandle_t hcl_acl_packet_out_lock
 

Detailed Description

Bluetooth HCI Driver.

This driver talks to USB HCI devices. Those are "Host Controller Interfaces" for communicating with bluetooth devices over USB

This is done as Wiimotes are connected through the Wii's internal bluetooth dongle.

Author
Samuel Fitzsimons (rainbain)
Date
2025

Macro Definition Documentation

◆ HCI_LOG_ERROR

#define HCI_LOG_ERROR ( tab,
fmt,
... )
Value:
LOG_ERROR(tab, fmt, ##__VA_ARGS__)

Function Documentation

◆ hci_begin_discovery()

int hci_begin_discovery ( uint32_t lap,
uint8_t length,
uint8_t responses,
hci_discovered_device_handler on_discovered,
hci_discovery_complete_handler on_complete,
void * user_data )

Begins looking for bluetooth devices.

Will begin looking for bluetooth devices.

On emulator, dolphin will report wiimote devices 1 at a time.

Only 1 thing can be running discovery at a time. Calling this while a discovery session is already running will return an error.

You generally need to wait for the inquiry to end before doing anything. ACL packets are fine though.

Handlers called from the HCI Task. Please do not call HCI function from the HCI task.

Parameters
lapAccess code for what devices to discover. Usually HCI_INQUIRY_MODE_GENERAL_ACCESS
lengthTime to discover devices for. In units of 1.28 seconds. 0x01 – 0x30, Dolphin always completes instantly
responsesMax devices discovered. Or 0 for infinite up until timeout.
on_discoveredCalled when a device is discovered. May be NOT be NULL
on_completeCalled when the discovery session ends. May be NULL
user_dataPointer passed to handlers. May be NULL.
Returns
Negative if Error

◆ hci_cancel_discovery()

int hci_cancel_discovery ( )

Stops a discovery session.

Once returns a non error value, no more of the discovery handlers will be called.

Returns
Negative if Error

◆ hci_close()

void hci_close ( )

Closes the HCI driver.

Currently, if HCI gets stuck, this function will get stuck waiting for the resource to open up.

Returns
Negative if Error

◆ hci_create_connection()

int hci_create_connection ( const hci_discovered_device_info_t * device,
uint16_t * handle )

Creates a connection to a device for you to use.

Parameters
deviceDiscovered device to connect to
handleDevice handle out. Not null
Returns
Negative if Error

◆ hci_decode_received_acl()

void hci_decode_received_acl ( uint16_t * handle,
hci_acl_packet_boundary_flag_t * pb,
hci_acl_packet_broadcast_flag_t * bc,
uint16_t * length,
const hci_acl_packet_t * acl_buffer )

Decodes a received ACL packet.

Like send, gets back the packet boundary, broadcast flags, and more.

Parameters
handleBluetooth Connection Handle In. Not NULL!
pbPacket boundary Flag In. Not NULL!
bcBroadcast boundary Flag In. Not NULL!
lengthLength of data received. Not NULL!
Returns
Negative if Error

◆ hci_get_remote_name()

int hci_get_remote_name ( const hci_discovered_device_info_t * device,
uint8_t * name )

Returns the remote name of a device.

Useful for for device detection and enumeration.

IMPORTANT: You can't call this during an inquiry, you must wait for it to end.

Parameters
deviceDevice information to poll.
nameName output, must be HCI_MAX_NAME_REQUEST_LENGTH in size.
Returns
Negative if Error

◆ hci_initialize()

int hci_initialize ( const char * device)

Initializes the HCI interface.

Initializes the HCI driver opening the USB interface in IOS.

Parameters
deviceDevice path to the USB device. For the wii's built in its "/dev/usb/oh1/57e/305"
Returns
Negative if Error

◆ hci_receive_acl_async()

int hci_receive_acl_async ( hci_acl_packet_t * acl_buffer,
uint8_t * ipc_buffer,
ipc_async_handler_t handler,
void * params )

Receives a ACL Packet Asynchronously.

Unlike send, this is done asynchronously, and returns early, so that you can double buffer and make sure to never miss an ACL packet. Multiplexing / Reassembly / Channels are handled by L2CAP that makes these

These parameters will be set into hci_acl_packet_in. Your data and length is available in there.

Also must be provided is a buffer size HCI_ACL_RECEIVE_IPC_BUFFER_SIZE for storing the IPC data. So that it can store the message in the mean time until the callback is called.

Parameters
bufferACL packet buffer to receive into.
ipc_bufferData buffer for the IPC data. Needs to be kept around until the callback is called. Needs to be 32 byte aligned.
handlerCalled when data is received
paramsPointer passed to handler
Returns
Negative if Error

◆ hci_reset()

int hci_reset ( )

Resets the HCI Interface.

Its recommended to do this to get it into a known state.

Returns
Negative if Error

◆ hci_send_acl()

int hci_send_acl ( uint16_t handle,
hci_acl_packet_boundary_flag_t pb,
hci_acl_packet_broadcast_flag_t bc,
uint16_t length )

Sends a ACL Packet.

These are the asynchronous data packets that are sent to devices. Multiplexing / Reassembly / Channels are handled by L2CAP that makes these

These parameters will be set into hci_acl_packet_out, you must fill in the data though.

Parameters
handleBluetooth Connection Handle From hci_create_connection
pbPacket boundary flag.
bcBroadcast boundary flag.
lengthLength of data transmitted.
Returns
Negative if Error