irgendwas

This commit is contained in:
danielvici123
2025-01-22 10:10:30 +01:00
parent 1507b7d590
commit b6eafc20e5
29 changed files with 3241 additions and 2 deletions

View File

@@ -0,0 +1,192 @@
#include "Ps3Controller.h"
#include <esp_bt_main.h>
#include <esp_bt_defs.h>
extern "C" {
#include "esp_bt_device.h"
#include "include/ps3.h"
}
#define ESP_BD_ADDR_HEX_STR "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"
#define ESP_BD_ADDR_HEX_ARR(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
#define ESP_BD_ADDR_HEX_PTR(addr) &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]
Ps3Controller::Ps3Controller()
{
}
bool Ps3Controller::begin()
{
ps3SetEventObjectCallback(this, &Ps3Controller::_event_callback);
ps3SetConnectionObjectCallback(this, &Ps3Controller::_connection_callback);
if(!btStarted() && !btStart()){
log_e("btStart failed");
return false;
}
esp_bluedroid_status_t bt_state = esp_bluedroid_get_status();
if(bt_state == ESP_BLUEDROID_STATUS_UNINITIALIZED){
if (esp_bluedroid_init()) {
log_e("esp_bluedroid_init failed");
return false;
}
}
if(bt_state != ESP_BLUEDROID_STATUS_ENABLED){
if (esp_bluedroid_enable()) {
log_e("esp_bluedroid_enable failed");
return false;
}
}
ps3Init();
return true;
}
bool Ps3Controller::begin(const char *mac)
{
esp_bd_addr_t addr;
if (sscanf(mac, ESP_BD_ADDR_HEX_STR, ESP_BD_ADDR_HEX_PTR(addr)) != ESP_BD_ADDR_LEN){
log_e("Could not convert %s\n to a MAC address", mac);
return false;
}
ps3SetBluetoothMacAddress( addr );
return begin();
}
bool Ps3Controller::end()
{
ps3Deinit();
return true;
}
String Ps3Controller::getAddress() {
String address = "";
if (btStarted()) {
char mac[18];
const uint8_t* addr = esp_bt_dev_get_address();
sprintf(mac, ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX_ARR(addr));
address = String(mac);
}
return address;
}
bool Ps3Controller::isConnected()
{
return ps3IsConnected();
}
void Ps3Controller::setPlayer(int player)
{
this->player = player;
ps3SetLed(player);
}
void Ps3Controller::setRumble(float intensity, int duration) {
const float int_min = 0.0;
const float int_max = 100.0;
const int dur_min = 0;
const int dur_max = 5000;
uint8_t raw_intensity = map(constrain(intensity, int_min, int_max), int_min, int_max, 0, 255);
uint8_t raw_duration = map(constrain(duration, dur_min, dur_max), dur_min, dur_max, 0, 254);
if (duration == -1) {
raw_duration = 255;
}
ps3_cmd_t cmd = {};
cmd.rumble_right_intensity = raw_intensity;
cmd.rumble_left_intensity = raw_intensity;
cmd.rumble_right_duration = raw_duration;
cmd.rumble_left_duration = raw_duration;
ps3SetLedCmd(&cmd, this->player);
ps3Cmd(cmd);
}
void Ps3Controller::attach(callback_t callback)
{
_callback_event = callback;
}
void Ps3Controller::attachOnConnect(callback_t callback)
{
_callback_connect = callback;
}
void Ps3Controller::attachOnDisconnect(callback_t callback)
{
_callback_disconnect = callback;
}
void Ps3Controller::_event_callback(void *object, ps3_t data, ps3_event_t event)
{
Ps3Controller* This = (Ps3Controller*) object;
memcpy(&This->data, &data, sizeof(ps3_t));
memcpy(&This->event, &event, sizeof(ps3_event_t));
if (This->_callback_event){
This->_callback_event();
}
}
void Ps3Controller::_connection_callback(void *object, uint8_t is_connected)
{
Ps3Controller* This = (Ps3Controller*) object;
if (is_connected)
{
// Set LED1 by default
This->setPlayer(1);
if (This->_callback_connect){
This->_callback_connect();
}
}else
{
if (This->_callback_disconnect){
This->_callback_disconnect();
}
}
}
#if !defined(NO_GLOBAL_INSTANCES)
Ps3Controller Ps3;
#endif

View File

@@ -0,0 +1,54 @@
#ifndef Ps3Controller_h
#define Ps3Controller_h
#include <inttypes.h>
#include "Arduino.h"
extern "C" {
#include "include/ps3.h"
}
class Ps3Controller
{
public:
typedef void(*callback_t)();
ps3_t data;
ps3_event_t event;
Ps3Controller();
bool begin();
bool begin(const char *mac);
bool end();
String getAddress();
bool isConnected();
void setPlayer(int player);
void setRumble(float intensity, int duration = -1);
void attach(callback_t callback);
void attachOnConnect(callback_t callback);
void attachOnDisconnect(callback_t callback);
private:
static void _event_callback(void *object, ps3_t data, ps3_event_t event);
static void _connection_callback(void *object, uint8_t is_connected);
int player;
callback_t _callback_event = nullptr;
callback_t _callback_connect = nullptr;
callback_t _callback_disconnect = nullptr;
};
#if !defined(NO_GLOBAL_INSTANCES)
extern Ps3Controller Ps3;
#endif
#endif

View File

@@ -0,0 +1,34 @@
/******************************************************************************
*
* Copyright (c) 2014 The Android Open Source Project
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef BT_TARGET_H
#define BT_TARGET_H
/******************************************************************************
**
** Buffer Size
**
******************************************************************************/
#ifndef BT_DEFAULT_BUFFER_SIZE
#define BT_DEFAULT_BUFFER_SIZE (4096 + 16)
#endif
#endif /* BT_TARGET_H */

View File

@@ -0,0 +1,180 @@
#ifndef PS3_H
#define PS3_H
/********************************************************************************/
/* T Y P E S */
/********************************************************************************/
/********************/
/* A N A L O G */
/********************/
typedef struct {
int8_t lx;
int8_t ly;
int8_t rx;
int8_t ry;
} ps3_analog_stick_t;
typedef struct {
uint8_t up;
uint8_t right;
uint8_t down;
uint8_t left;
uint8_t l2;
uint8_t r2;
uint8_t l1;
uint8_t r1;
uint8_t triangle;
uint8_t circle;
uint8_t cross;
uint8_t square;
} ps3_analog_button_t;
typedef struct {
ps3_analog_stick_t stick;
ps3_analog_button_t button;
} ps3_analog_t;
/*********************/
/* B U T T O N S */
/*********************/
typedef struct {
uint8_t select : 1;
uint8_t l3 : 1;
uint8_t r3 : 1;
uint8_t start : 1;
uint8_t up : 1;
uint8_t right : 1;
uint8_t down : 1;
uint8_t left : 1;
uint8_t l2 : 1;
uint8_t r2 : 1;
uint8_t l1 : 1;
uint8_t r1 : 1;
uint8_t triangle : 1;
uint8_t circle : 1;
uint8_t cross : 1;
uint8_t square : 1;
uint8_t ps : 1;
} ps3_button_t;
/*******************************/
/* S T A T U S F L A G S */
/*******************************/
enum ps3_status_battery {
ps3_status_battery_shutdown = 0x01,
ps3_status_battery_dying = 0x02,
ps3_status_battery_low = 0x03,
ps3_status_battery_high = 0x04,
ps3_status_battery_full = 0x05,
ps3_status_battery_charging = 0xEE
};
enum ps3_status_connection {
ps3_status_connection_usb,
ps3_status_connection_bluetooth
};
typedef struct {
enum ps3_status_battery battery;
enum ps3_status_connection connection;
uint8_t charging : 1;
uint8_t rumbling : 1;
} ps3_status_t;
/********************/
/* S E N S O R S */
/********************/
typedef struct {
int16_t z;
} ps3_sensor_gyroscope_t;
typedef struct {
int16_t x;
int16_t y;
int16_t z;
} ps3_sensor_accelerometer_t;
typedef struct {
ps3_sensor_accelerometer_t accelerometer;
ps3_sensor_gyroscope_t gyroscope;
} ps3_sensor_t;
/*******************/
/* O T H E R */
/*******************/
typedef struct {
/* Rumble control */
uint8_t rumble_right_duration;
uint8_t rumble_right_intensity;
uint8_t rumble_left_duration;
uint8_t rumble_left_intensity;
/* LED control */
uint8_t led1 : 1;
uint8_t led2 : 1;
uint8_t led3 : 1;
uint8_t led4 : 1;
} ps3_cmd_t;
typedef struct {
ps3_button_t button_down;
ps3_button_t button_up;
ps3_analog_t analog_changed;
} ps3_event_t;
typedef struct {
ps3_analog_t analog;
ps3_button_t button;
ps3_status_t status;
ps3_sensor_t sensor;
} ps3_t;
/***************************/
/* C A L L B A C K S */
/***************************/
typedef void(*ps3_connection_callback_t)( uint8_t is_connected );
typedef void(*ps3_connection_object_callback_t)( void *object, uint8_t is_connected );
typedef void(*ps3_event_callback_t)( ps3_t ps3, ps3_event_t event );
typedef void(*ps3_event_object_callback_t)( void *object, ps3_t ps3, ps3_event_t event );
/********************************************************************************/
/* F U N C T I O N S */
/********************************************************************************/
bool ps3IsConnected();
void ps3Init();
void ps3Deinit();
void ps3Enable();
void ps3Cmd( ps3_cmd_t ps3_cmd );
void ps3SetConnectionCallback( ps3_connection_callback_t cb );
void ps3SetConnectionObjectCallback( void *object, ps3_connection_object_callback_t cb );
void ps3SetEventCallback( ps3_event_callback_t cb );
void ps3SetEventObjectCallback( void *object, ps3_event_object_callback_t cb );
void ps3SetLed( uint8_t player );
void ps3SetLedCmd( ps3_cmd_t *cmd, uint8_t player );
void ps3SetBluetoothMacAddress( const uint8_t *mac );
#endif

View File

@@ -0,0 +1,152 @@
#ifndef PS3_INT_H
#define PS3_INT_H
#include "sdkconfig.h"
/** Check if the project is configured properly */
#ifndef ARDUINO_ARCH_ESP32
#ifndef CONFIG_BT_ENABLED
#error "The ESP32-PS3 module requires the Bluetooth component to be enabled in the project's menuconfig"
#endif
#ifndef CONFIG_BLUEDROID_ENABLED
#error "The ESP32-PS3 module requires Bluedroid to be enabled in the project's menuconfig"
#endif
#ifndef CONFIG_CLASSIC_BT_ENABLED
#error "The ESP32-PS3 module requires Classic Bluetooth to be enabled in the project's menuconfig"
#endif
#ifndef CONFIG_BT_SPP_ENABLED
#error "The ESP32-PS3 module requires Classic Bluetooth's SPP to be enabled in the project's menuconfig"
#endif
/** Check the configured blueooth mode */
#ifdef CONFIG_BTDM_CONTROLLER_MODE_BTDM
#define BT_MODE ESP_BT_MODE_BTDM
#elif defined CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY
#define BT_MODE ESP_BT_MODE_CLASSIC_BT
#else
#error "The selected Bluetooth controller mode is not supported by the ESP32-PS3 module"
#endif
#endif // ARDUINO_ARCH_ESP32
/* Detect ESP-IDF releases */
#if __has_include("esp_idf_version.h")
#include <esp_idf_version.h>
#else
/* Detect Arduino releases */
#if __has_include("core_version.h")
#include <core_version.h>
#endif
/* Arduino releases using IDF v3.2.3 */
#if defined(ARDUINO_ESP32_RELEASE_1_0_4) || defined(ARDUINO_ESP32_RELEASE_1_0_3)
#define ESP_IDF_VERSION_MAJOR 3
#define ESP_IDF_VERSION_MINOR 2
#define ESP_IDF_VERSION_PATCH 3
#endif
/* Arduino releases using IDF v3.2.2 */
#if defined(ARDUINO_ESP32_RELEASE_1_0_3) || defined(ARDUINO_ESP32_RELEASE_1_0_2) || defined(ARDUINO_ESP32_RELEASE_1_0_1) || defined(ARDUINO_ESP32_RELEASE_1_0_0)
#define ESP_IDF_VERSION_MAJOR 3
#define ESP_IDF_VERSION_MINOR 2
#define ESP_IDF_VERSION_PATCH 2
#endif
// Macro to convert IDF version number into an integer
#define ESP_IDF_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
// Current IDF version, as an integer
#define ESP_IDF_VERSION ESP_IDF_VERSION_VAL(ESP_IDF_VERSION_MAJOR, \
ESP_IDF_VERSION_MINOR, \
ESP_IDF_VERSION_PATCH)
#endif // __has_include("esp_idf_version.h")
/** Size of the output report buffer for the Dualshock and Navigation controllers */
#define PS3_REPORT_BUFFER_SIZE 48
#define PS3_HID_BUFFER_SIZE 50
/********************************************************************************/
/* S H A R E D T Y P E S */
/********************************************************************************/
enum hid_cmd_code {
hid_cmd_code_set_report = 0x50,
hid_cmd_code_type_output = 0x02,
hid_cmd_code_type_feature = 0x03
};
enum hid_cmd_identifier {
hid_cmd_identifier_ps3_enable = 0xf4,
hid_cmd_identifier_ps3_control = 0x01
};
typedef struct {
uint8_t code;
uint8_t identifier;
uint8_t data[PS3_REPORT_BUFFER_SIZE];
} hid_cmd_t;
enum ps3_control_packet_index {
ps3_control_packet_index_rumble_right_duration = 1,
ps3_control_packet_index_rumble_right_intensity = 2,
ps3_control_packet_index_rumble_left_duration = 3,
ps3_control_packet_index_rumble_left_intensity = 4,
ps3_control_packet_index_leds = 9,
ps3_control_packet_index_led4_arguments = 10,
ps3_control_packet_index_led3_arguments = 15,
ps3_control_packet_index_led2_arguments = 20,
ps3_control_packet_index_led1_arguments = 25
};
enum ps3_led_mask {
ps3_led_mask_led1 = 1 << 1,
ps3_led_mask_led2 = 1 << 2,
ps3_led_mask_led3 = 1 << 3,
ps3_led_mask_led4 = 1 << 4,
};
/********************************************************************************/
/* C A L L B A C K F U N C T I O N S */
/********************************************************************************/
void ps3_connect_event(uint8_t is_connected);
void ps3_packet_event( ps3_t ps3, ps3_event_t event );
/********************************************************************************/
/* P A R S E R F U N C T I O N S */
/********************************************************************************/
void ps3_parse_packet( uint8_t *packet );
/********************************************************************************/
/* S P P F U N C T I O N S */
/********************************************************************************/
void ps3_spp_init();
void ps3_spp_deinit();
/********************************************************************************/
/* L 2 C A P F U N C T I O N S */
/********************************************************************************/
void ps3_l2cap_init_services();
void ps3_l2cap_deinit_services();
void ps3_l2cap_send_hid( hid_cmd_t *hid_cmd, uint8_t len );
#endif

View File

@@ -0,0 +1,145 @@
/******************************************************************************
*
* Copyright (C) 2014 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef _ALLOCATOR_H_
#define _ALLOCATOR_H_
#include <stddef.h>
#include <stdlib.h>
#include "esp_heap_caps.h"
char *osi_strdup(const char *str);
void *osi_malloc_func(size_t size);
void *osi_calloc_func(size_t size);
void osi_free_func(void *ptr);
#if HEAP_MEMORY_DEBUG
void osi_mem_dbg_init(void);
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
void osi_mem_dbg_clean(void *p, const char *func, int line);
void osi_mem_dbg_show(void);
uint32_t osi_mem_dbg_get_max_size(void);
uint32_t osi_mem_dbg_get_current_size(void);
void osi_men_dbg_set_section_start(uint8_t index);
void osi_men_dbg_set_section_end(uint8_t index);
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index);
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
#define osi_malloc(size) \
({ \
void *p; \
p = heap_caps_malloc_prefer(size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#define osi_calloc(size) \
({ \
void *p; \
p = heap_caps_calloc_prefer(1, size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#else
#define osi_malloc(size) \
({ \
void *p; \
p = malloc((size)); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#define osi_calloc(size) \
({ \
void *p; \
p = calloc(1, (size)); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
#if 0
#define osi_malloc(size) \
do { \
void *p; \
\
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = malloc((size)); \
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
}while(0)
#define osi_calloc(size) \
do { \
void *p; \
\
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_calloc_prefer(1, size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = calloc(1, (size)); \
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
} while(0)
#endif
#define osi_free(ptr) \
do { \
void *tmp_point = (void *)(ptr); \
osi_mem_dbg_clean(tmp_point, __func__, __LINE__); \
free(tmp_point); \
} while (0)
#else
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#else
#define osi_malloc(size) malloc((size))
#define osi_calloc(size) calloc(1, (size))
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */
#define osi_free(p) free((p))
#endif /* HEAP_MEMORY_DEBUG */
#define FREE_AND_RESET(a) \
do { \
if (a) { \
osi_free(a); \
a = NULL; \
} \
}while (0)
#endif /* _ALLOCATOR_H_ */

View File

@@ -0,0 +1,332 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <esp_system.h>
#include "include/ps3.h"
#include "include/ps3_int.h"
/********************************************************************************/
/* C O N S T A N T S */
/********************************************************************************/
static const uint8_t hid_cmd_payload_ps3_enable[] = { 0x42, 0x03, 0x00, 0x00 };
static const uint8_t hid_cmd_payload_led_arguments[] = { 0xff, 0x27, 0x10, 0x00, 0x32 };
/********************************************************************************/
/* L O C A L V A R I A B L E S */
/********************************************************************************/
static ps3_connection_callback_t ps3_connection_cb = NULL;
static ps3_connection_object_callback_t ps3_connection_object_cb = NULL;
static void *ps3_connection_object = NULL;
static ps3_event_callback_t ps3_event_cb = NULL;
static ps3_event_object_callback_t ps3_event_object_cb = NULL;
static void *ps3_event_object = NULL;
static bool is_active = false;
/********************************************************************************/
/* P U B L I C F U N C T I O N S */
/********************************************************************************/
/*******************************************************************************
**
** Function ps3Init
**
** Description This initializes the bluetooth services to listen
** for an incoming PS3 controller connection.
**
**
** Returns void
**
*******************************************************************************/
void ps3Init()
{
ps3_spp_init();
ps3_l2cap_init_services();
}
/*******************************************************************************
**
** Function ps3Deinit
**
** Description This deinitializes the bluetooth services to stop
** listening for incoming connections.
**
**
** Returns void
**
*******************************************************************************/
void ps3Deinit()
{
ps3_l2cap_deinit_services();
ps3_spp_deinit();
}
/*******************************************************************************
**
** Function ps3IsConnected
**
** Description This returns whether a PS3 controller is connected, based
** on whether a successful handshake has taken place.
**
**
** Returns bool
**
*******************************************************************************/
bool ps3IsConnected()
{
return is_active;
}
/*******************************************************************************
**
** Function ps3Enable
**
** Description This triggers the PS3 controller to start continually
** sending its data.
**
**
** Returns void
**
*******************************************************************************/
void ps3Enable()
{
uint16_t len = sizeof(hid_cmd_payload_ps3_enable);
hid_cmd_t hid_cmd;
hid_cmd.code = hid_cmd_code_set_report | hid_cmd_code_type_feature;
hid_cmd.identifier = hid_cmd_identifier_ps3_enable;
memcpy( hid_cmd.data, hid_cmd_payload_ps3_enable, len);
ps3_l2cap_send_hid( &hid_cmd, len );
}
/*******************************************************************************
**
** Function ps3Cmd
**
** Description Send a command to the PS3 controller.
**
**
** Returns void
**
*******************************************************************************/
void ps3Cmd( ps3_cmd_t cmd )
{
hid_cmd_t hid_cmd = { .data = {0} };
uint16_t len = sizeof(hid_cmd.data);
hid_cmd.code = hid_cmd_code_set_report | hid_cmd_code_type_output;
hid_cmd.identifier = hid_cmd_identifier_ps3_control;
hid_cmd.data[ps3_control_packet_index_rumble_right_duration] = cmd.rumble_right_duration;
hid_cmd.data[ps3_control_packet_index_rumble_right_intensity] = cmd.rumble_right_intensity;
hid_cmd.data[ps3_control_packet_index_rumble_left_duration] = cmd.rumble_left_duration;
hid_cmd.data[ps3_control_packet_index_rumble_left_intensity] = cmd.rumble_left_intensity;
hid_cmd.data[ps3_control_packet_index_leds] = 0;
if (cmd.led1) hid_cmd.data[ps3_control_packet_index_leds] |= ps3_led_mask_led1;
if (cmd.led2) hid_cmd.data[ps3_control_packet_index_leds] |= ps3_led_mask_led2;
if (cmd.led3) hid_cmd.data[ps3_control_packet_index_leds] |= ps3_led_mask_led3;
if (cmd.led4) hid_cmd.data[ps3_control_packet_index_leds] |= ps3_led_mask_led4;
if (cmd.led1) memcpy( hid_cmd.data + ps3_control_packet_index_led1_arguments, hid_cmd_payload_led_arguments, sizeof(hid_cmd_payload_led_arguments));
if (cmd.led2) memcpy( hid_cmd.data + ps3_control_packet_index_led2_arguments, hid_cmd_payload_led_arguments, sizeof(hid_cmd_payload_led_arguments));
if (cmd.led3) memcpy( hid_cmd.data + ps3_control_packet_index_led3_arguments, hid_cmd_payload_led_arguments, sizeof(hid_cmd_payload_led_arguments));
if (cmd.led4) memcpy( hid_cmd.data + ps3_control_packet_index_led4_arguments, hid_cmd_payload_led_arguments, sizeof(hid_cmd_payload_led_arguments));
ps3_l2cap_send_hid( &hid_cmd, len );
}
/*******************************************************************************
**
** Function ps3SetLed
**
** Description Sets the LEDs on the PS3 controller to the player
** number. Up to 10 players are supported.
**
**
** Returns void
**
*******************************************************************************/
void ps3SetLed( uint8_t player )
{
ps3_cmd_t cmd = {0};
ps3SetLedCmd(&cmd, player);
ps3Cmd(cmd);
}
/*******************************************************************************
**
** Function ps3SetLed
**
** Description Sets the LED bits on the PS3 controller command to the
** player number. Up to 10 players are supported.
**
**
** Returns void
**
*******************************************************************************/
void ps3SetLedCmd( ps3_cmd_t *cmd, uint8_t player )
{
// led4 led3 led2 led1
// player 1 1
// player 2 1
// player 3 1
// player 4 1
// player 5 1 1
// player 6 1 1
// player 7 1 1
// player 8 1 1 1
// player 9 1 1 1
// player 10 1 1 1 1
if( (cmd->led4 = player >= 4) != 0 ) player -= 4;
if( (cmd->led3 = player >= 3) != 0 ) player -= 3;
if( (cmd->led2 = player >= 2) != 0 ) player -= 2;
if( (cmd->led1 = player >= 1) != 0 ) player -= 1;
}
/*******************************************************************************
**
** Function ps3SetConnectionCallback
**
** Description Registers a callback for receiving PS3 controller
** connection notifications
**
**
** Returns void
**
*******************************************************************************/
void ps3SetConnectionCallback( ps3_connection_callback_t cb )
{
ps3_connection_cb = cb;
}
/*******************************************************************************
**
** Function ps3SetConnectionObjectCallback
**
** Description Registers a callback for receiving PS3 controller
** connection notifications
**
**
** Returns void
**
*******************************************************************************/
void ps3SetConnectionObjectCallback( void *object, ps3_connection_object_callback_t cb )
{
ps3_connection_object_cb = cb;
ps3_connection_object = object;
}
/*******************************************************************************
**
** Function ps3SetEventCallback
**
** Description Registers a callback for receiving PS3 controller events
**
**
** Returns void
**
*******************************************************************************/
void ps3SetEventCallback( ps3_event_callback_t cb )
{
ps3_event_cb = cb;
}
/*******************************************************************************
**
** Function ps3SetEventObjectCallback
**
** Description Registers a callback for receiving PS3 controller events
**
**
** Returns void
**
*******************************************************************************/
void ps3SetEventObjectCallback( void *object, ps3_event_object_callback_t cb )
{
ps3_event_object_cb = cb;
ps3_event_object = object;
}
/*******************************************************************************
**
** Function ps3SetBluetoothMacAddress
**
** Description Writes a Registers a callback for receiving PS3 controller events
**
**
** Returns void
**
*******************************************************************************/
void ps3SetBluetoothMacAddress( const uint8_t *mac )
{
// The bluetooth MAC address is derived from the base MAC address
// https://docs.espressif.com/projects/esp-idf/en/stable/api-reference/system/system.html#mac-address
uint8_t base_mac[6];
memcpy(base_mac, mac, 6);
base_mac[5] -= 2;
esp_base_mac_addr_set(base_mac);
}
/********************************************************************************/
/* L O C A L F U N C T I O N S */
/********************************************************************************/
void ps3_connect_event( uint8_t is_connected )
{
if(is_connected){
ps3Enable();
}else{
is_active = false;
}
}
void ps3_packet_event( ps3_t ps3, ps3_event_t event )
{
// Trigger packet event, but if this is the very first packet
// after connecting, trigger a connection event instead
if(is_active){
if(ps3_event_cb != NULL)
{
ps3_event_cb( ps3, event );
}
if(ps3_event_object_cb != NULL && ps3_event_object != NULL)
{
ps3_event_object_cb( ps3_event_object, ps3, event );
}
}else{
is_active = true;
if(ps3_connection_cb != NULL)
{
ps3_connection_cb( is_active );
}
if(ps3_connection_object_cb != NULL && ps3_connection_object != NULL)
{
ps3_connection_object_cb( ps3_connection_object, is_active );
}
}
}

View File

@@ -0,0 +1,332 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "include/ps3.h"
#include "include/ps3_int.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "stack/gap_api.h"
#include "stack/bt_types.h"
#include "stack/l2c_api.h"
#include "osi/allocator.h"
#define PS3_TAG "PS3_L2CAP"
#define PS3_L2CAP_ID_HIDC 0x40
#define PS3_L2CAP_ID_HIDI 0x41
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
static void ps3_l2cap_init_service( char *name, uint16_t psm, uint8_t security_id);
static void ps3_l2cap_deinit_service( char *name, uint16_t psm );
static void ps3_l2cap_connect_ind_cback (BD_ADDR bd_addr, uint16_t l2cap_cid, uint16_t psm, uint8_t l2cap_id);
static void ps3_l2cap_connect_cfm_cback (uint16_t l2cap_cid, uint16_t result);
static void ps3_l2cap_config_ind_cback (uint16_t l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void ps3_l2cap_config_cfm_cback (uint16_t l2cap_cid, tL2CAP_CFG_INFO *p_cfg);
static void ps3_l2cap_disconnect_ind_cback (uint16_t l2cap_cid, bool ack_needed);
static void ps3_l2cap_disconnect_cfm_cback (uint16_t l2cap_cid, uint16_t result);
static void ps3_l2cap_data_ind_cback (uint16_t l2cap_cid, BT_HDR *p_msg);
static void ps3_l2cap_congest_cback (uint16_t cid, bool congested);
/********************************************************************************/
/* L O C A L V A R I A B L E S */
/********************************************************************************/
static const tL2CAP_APPL_INFO dyn_info = {
ps3_l2cap_connect_ind_cback,
ps3_l2cap_connect_cfm_cback,
NULL,
ps3_l2cap_config_ind_cback,
ps3_l2cap_config_cfm_cback,
ps3_l2cap_disconnect_ind_cback,
ps3_l2cap_disconnect_cfm_cback,
NULL,
ps3_l2cap_data_ind_cback,
ps3_l2cap_congest_cback,
NULL
} ;
static tL2CAP_CFG_INFO ps3_cfg_info;
bool is_connected = false;
/********************************************************************************/
/* P U B L I C F U N C T I O N S */
/********************************************************************************/
/*******************************************************************************
**
** Function ps3_l2cap_init_services
**
** Description This function initialises the required L2CAP services.
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_init_services()
{
ps3_l2cap_init_service( "PS3-HIDC", BT_PSM_HIDC, BTM_SEC_SERVICE_FIRST_EMPTY );
ps3_l2cap_init_service( "PS3-HIDI", BT_PSM_HIDI, BTM_SEC_SERVICE_FIRST_EMPTY+1 );
}
/*******************************************************************************
**
** Function ps3_l2cap_deinit_services
**
** Description This function deinitialises the required L2CAP services.
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_deinit_services()
{
ps3_l2cap_deinit_service( "PS3-HIDC", BT_PSM_HIDC );
ps3_l2cap_deinit_service( "PS3-HIDI", BT_PSM_HIDI );
}
/*******************************************************************************
**
** Function ps3_l2cap_send_hid
**
** Description This function sends the HID command using the L2CAP service.
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_send_hid( hid_cmd_t *hid_cmd, uint8_t len )
{
uint8_t result;
BT_HDR *p_buf;
p_buf = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
if( !p_buf ){
ESP_LOGE(PS3_TAG, "[%s] allocating buffer for sending the command failed", __func__);
}
p_buf->len = len + ( sizeof(*hid_cmd) - sizeof(hid_cmd->data) );
p_buf->offset = L2CAP_MIN_OFFSET;
memcpy ((uint8_t *)(p_buf + 1) + p_buf->offset, (uint8_t*)hid_cmd, p_buf->len);
result = L2CA_DataWrite( PS3_L2CAP_ID_HIDC, p_buf );
if (result == L2CAP_DW_SUCCESS)
ESP_LOGI(PS3_TAG, "[%s] sending command: success", __func__);
if (result == L2CAP_DW_CONGESTED)
ESP_LOGW(PS3_TAG, "[%s] sending command: congested", __func__);
if (result == L2CAP_DW_FAILED)
ESP_LOGE(PS3_TAG, "[%s] sending command: failed", __func__);
}
/********************************************************************************/
/* L O C A L F U N C T I O N S */
/********************************************************************************/
/*******************************************************************************
**
** Function ps3_l2cap_init_service
**
** Description This registers the specified bluetooth service in order
** to listen for incoming connections.
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_init_service( char *name, uint16_t psm, uint8_t security_id)
{
/* Register the PSM for incoming connections */
if (!L2CA_Register(psm, (tL2CAP_APPL_INFO *) &dyn_info)) {
ESP_LOGE(PS3_TAG, "%s Registering service %s failed", __func__, name);
return;
}
/* Register with the Security Manager for our specific security level (none) */
if (!BTM_SetSecurityLevel (false, name, security_id, 0, psm, 0, 0)) {
ESP_LOGE (PS3_TAG, "%s Registering security service %s failed", __func__, name);\
return;
}
ESP_LOGI(PS3_TAG, "[%s] Service %s Initialized", __func__, name);
}
/*******************************************************************************
**
** Function ps3_l2cap_deinit_service
**
** Description This deregisters the specified bluetooth service.
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_deinit_service( char *name, uint16_t psm )
{
/* Deregister the PSM from incoming connections */
L2CA_Deregister(psm);
ESP_LOGI(PS3_TAG, "[%s] Service %s Deinitialized", __func__, name);
}
/*******************************************************************************
**
** Function ps3_l2cap_connect_ind_cback
**
** Description This the L2CAP inbound connection indication callback function.
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_connect_ind_cback (BD_ADDR bd_addr, uint16_t l2cap_cid, uint16_t psm, uint8_t l2cap_id)
{
ESP_LOGI(PS3_TAG, "[%s] bd_addr: %s\n l2cap_cid: 0x%02x\n psm: %d\n id: %d", __func__, bd_addr, l2cap_cid, psm, l2cap_id );
/* Send connection pending response to the L2CAP layer. */
L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_PENDING, L2CAP_CONN_PENDING, NULL, NULL);
/* Send response to the L2CAP layer. */
L2CA_CONNECT_RSP (bd_addr, l2cap_id, l2cap_cid, L2CAP_CONN_OK, L2CAP_CONN_OK, NULL, NULL);
/* Send a Configuration Request. */
L2CA_CONFIG_REQ (l2cap_cid, &ps3_cfg_info);
}
/*******************************************************************************
**
** Function ps3_l2cap_connect_cfm_cback
**
** Description This is the L2CAP connect confirmation callback function.
**
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_connect_cfm_cback(uint16_t l2cap_cid, uint16_t result)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n result: %d", __func__, l2cap_cid, result );
}
/*******************************************************************************
**
** Function ps3_l2cap_config_cfm_cback
**
** Description This is the L2CAP config confirmation callback function.
**
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_config_cfm_cback(uint16_t l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n p_cfg->result: %d", __func__, l2cap_cid, p_cfg->result );
/* The PS3 controller is connected after */
/* receiving the second config confirmation */
is_connected = l2cap_cid == PS3_L2CAP_ID_HIDI;
if(is_connected){
ps3Enable();
}
}
/*******************************************************************************
**
** Function ps3_l2cap_config_ind_cback
**
** Description This is the L2CAP config indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_config_ind_cback(uint16_t l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n p_cfg->result: %d\n p_cfg->mtu_present: %d\n p_cfg->mtu: %d", __func__, l2cap_cid, p_cfg->result, p_cfg->mtu_present, p_cfg->mtu );
p_cfg->result = L2CAP_CFG_OK;
L2CA_ConfigRsp(l2cap_cid, p_cfg);
}
/*******************************************************************************
**
** Function ps3_l2cap_disconnect_ind_cback
**
** Description This is the L2CAP disconnect indication callback function.
**
**
** Returns void
**
*******************************************************************************/
void ps3_l2cap_disconnect_ind_cback(uint16_t l2cap_cid, bool ack_needed)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n ack_needed: %d", __func__, l2cap_cid, ack_needed );
}
/*******************************************************************************
**
** Function ps3_l2cap_disconnect_cfm_cback
**
** Description This is the L2CAP disconnect confirm callback function.
**
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_disconnect_cfm_cback(uint16_t l2cap_cid, uint16_t result)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n result: %d", __func__, l2cap_cid, result );
}
/*******************************************************************************
**
** Function ps3_l2cap_data_ind_cback
**
** Description This is the L2CAP data indication callback function.
**
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_data_ind_cback(uint16_t l2cap_cid, BT_HDR *p_buf)
{
if ( p_buf->len > 2 )
{
ps3_parse_packet( p_buf->data );
}
osi_free( p_buf );
}
/*******************************************************************************
**
** Function ps3_l2cap_congest_cback
**
** Description This is the L2CAP congestion callback function.
**
** Returns void
**
*******************************************************************************/
static void ps3_l2cap_congest_cback (uint16_t l2cap_cid, bool congested)
{
ESP_LOGI(PS3_TAG, "[%s] l2cap_cid: 0x%02x\n congested: %d", __func__, l2cap_cid, congested );
}

View File

@@ -0,0 +1,307 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "include/ps3.h"
#include "include/ps3_int.h"
#include "esp_log.h"
#define PS3_TAG "PS3_PARSER"
/********************************************************************************/
/* L O C A L T Y P E S */
/********************************************************************************/
enum ps3_packet_index {
ps3_packet_index_buttons_raw = 12,
ps3_packet_index_analog_stick_lx = 16,
ps3_packet_index_analog_stick_ly = 17,
ps3_packet_index_analog_stick_rx = 18,
ps3_packet_index_analog_stick_ry = 19,
ps3_packet_index_analog_button_up = 24,
ps3_packet_index_analog_button_right = 25,
ps3_packet_index_analog_button_down = 26,
ps3_packet_index_analog_button_left = 27,
ps3_packet_index_analog_button_l2 = 28,
ps3_packet_index_analog_button_r2 = 29,
ps3_packet_index_analog_button_l1 = 30,
ps3_packet_index_analog_button_r1 = 31,
ps3_packet_index_analog_button_triangle = 32,
ps3_packet_index_analog_button_circle = 33,
ps3_packet_index_analog_button_cross = 34,
ps3_packet_index_analog_button_square = 35,
ps3_packet_index_status = 39,
ps3_packet_index_sensor_accelerometer_x = 51,
ps3_packet_index_sensor_accelerometer_y = 53,
ps3_packet_index_sensor_accelerometer_z = 55,
ps3_packet_index_sensor_gyroscope_z = 57
};
enum ps3_button_mask {
ps3_button_mask_select = 1 << 0,
ps3_button_mask_l3 = 1 << 1,
ps3_button_mask_r3 = 1 << 2,
ps3_button_mask_start = 1 << 3,
ps3_button_mask_up = 1 << 4,
ps3_button_mask_right = 1 << 5,
ps3_button_mask_down = 1 << 6,
ps3_button_mask_left = 1 << 7,
ps3_button_mask_l2 = 1 << 8,
ps3_button_mask_r2 = 1 << 9,
ps3_button_mask_l1 = 1 << 10,
ps3_button_mask_r1 = 1 << 11,
ps3_button_mask_triangle = 1 << 12,
ps3_button_mask_circle = 1 << 13,
ps3_button_mask_cross = 1 << 14,
ps3_button_mask_square = 1 << 15,
ps3_button_mask_ps = 1 << 16
};
enum ps3_status_mask {
ps3_status_mask_rumbling = 0x02,
ps3_status_mask_bluetooth = 0x04
};
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
ps3_sensor_t ps3_parse_packet_sensor( uint8_t *packet );
ps3_status_t ps3_parse_packet_status( uint8_t *packet );
ps3_analog_stick_t ps3_parse_packet_analog_stick( uint8_t *packet );
ps3_analog_button_t ps3_parse_packet_analog_button( uint8_t *packet );
ps3_button_t ps3_parse_packet_buttons( uint8_t *packet );
ps3_event_t ps3_parse_event( ps3_t prev, ps3_t cur );
/********************************************************************************/
/* L O C A L V A R I A B L E S */
/********************************************************************************/
static ps3_t ps3;
static ps3_event_callback_t ps3_event_cb = NULL;
/********************************************************************************/
/* P U B L I C F U N C T I O N S */
/********************************************************************************/
void ps3_parser_set_event_cb( ps3_event_callback_t cb )
{
ps3_event_cb = cb;
}
void ps3_parse_packet( uint8_t *packet )
{
ps3_t prev_ps3 = ps3;
ps3.button = ps3_parse_packet_buttons(packet);
ps3.analog.stick = ps3_parse_packet_analog_stick(packet);
ps3.analog.button = ps3_parse_packet_analog_button(packet);
ps3.sensor = ps3_parse_packet_sensor(packet);
ps3.status = ps3_parse_packet_status(packet);
ps3_event_t ps3_event = ps3_parse_event( prev_ps3, ps3 );
ps3_packet_event( ps3, ps3_event );
}
/********************************************************************************/
/* L O C A L F U N C T I O N S */
/********************************************************************************/
/******************/
/* E V E N T */
/******************/
ps3_event_t ps3_parse_event( ps3_t prev, ps3_t cur )
{
ps3_event_t ps3_event;
/* Button down events */
ps3_event.button_down.select = !prev.button.select && cur.button.select;
ps3_event.button_down.l3 = !prev.button.l3 && cur.button.l3;
ps3_event.button_down.r3 = !prev.button.r3 && cur.button.r3;
ps3_event.button_down.start = !prev.button.start && cur.button.start;
ps3_event.button_down.up = !prev.button.up && cur.button.up;
ps3_event.button_down.right = !prev.button.right && cur.button.right;
ps3_event.button_down.down = !prev.button.down && cur.button.down;
ps3_event.button_down.left = !prev.button.left && cur.button.left;
ps3_event.button_down.l2 = !prev.button.l2 && cur.button.l2;
ps3_event.button_down.r2 = !prev.button.r2 && cur.button.r2;
ps3_event.button_down.l1 = !prev.button.l1 && cur.button.l1;
ps3_event.button_down.r1 = !prev.button.r1 && cur.button.r1;
ps3_event.button_down.triangle = !prev.button.triangle && cur.button.triangle;
ps3_event.button_down.circle = !prev.button.circle && cur.button.circle;
ps3_event.button_down.cross = !prev.button.cross && cur.button.cross;
ps3_event.button_down.square = !prev.button.square && cur.button.square;
ps3_event.button_down.ps = !prev.button.ps && cur.button.ps;
/* Button up events */
ps3_event.button_up.select = prev.button.select && !cur.button.select;
ps3_event.button_up.l3 = prev.button.l3 && !cur.button.l3;
ps3_event.button_up.r3 = prev.button.r3 && !cur.button.r3;
ps3_event.button_up.start = prev.button.start && !cur.button.start;
ps3_event.button_up.up = prev.button.up && !cur.button.up;
ps3_event.button_up.right = prev.button.right && !cur.button.right;
ps3_event.button_up.down = prev.button.down && !cur.button.down;
ps3_event.button_up.left = prev.button.left && !cur.button.left;
ps3_event.button_up.l2 = prev.button.l2 && !cur.button.l2;
ps3_event.button_up.r2 = prev.button.r2 && !cur.button.r2;
ps3_event.button_up.l1 = prev.button.l1 && !cur.button.l1;
ps3_event.button_up.r1 = prev.button.r1 && !cur.button.r1;
ps3_event.button_up.triangle = prev.button.triangle && !cur.button.triangle;
ps3_event.button_up.circle = prev.button.circle && !cur.button.circle;
ps3_event.button_up.cross = prev.button.cross && !cur.button.cross;
ps3_event.button_up.square = prev.button.square && !cur.button.square;
ps3_event.button_up.ps = prev.button.ps && !cur.button.ps;
/* Analog events */
ps3_event.analog_changed.stick.lx = cur.analog.stick.lx - prev.analog.stick.lx;
ps3_event.analog_changed.stick.ly = cur.analog.stick.ly - prev.analog.stick.ly;
ps3_event.analog_changed.stick.rx = cur.analog.stick.rx - prev.analog.stick.rx;
ps3_event.analog_changed.stick.ry = cur.analog.stick.ry - prev.analog.stick.ry;
ps3_event.analog_changed.button.up = cur.analog.button.up - prev.analog.button.up;
ps3_event.analog_changed.button.right = cur.analog.button.right - prev.analog.button.right;
ps3_event.analog_changed.button.down = cur.analog.button.down - prev.analog.button.down;
ps3_event.analog_changed.button.left = cur.analog.button.left - prev.analog.button.left;
ps3_event.analog_changed.button.l2 = cur.analog.button.l2 - prev.analog.button.l2;
ps3_event.analog_changed.button.r2 = cur.analog.button.r2 - prev.analog.button.r2;
ps3_event.analog_changed.button.l1 = cur.analog.button.l1 - prev.analog.button.l1;
ps3_event.analog_changed.button.r1 = cur.analog.button.r1 - prev.analog.button.r1;
ps3_event.analog_changed.button.triangle = cur.analog.button.triangle - prev.analog.button.triangle;
ps3_event.analog_changed.button.circle = cur.analog.button.circle - prev.analog.button.circle;
ps3_event.analog_changed.button.cross = cur.analog.button.cross - prev.analog.button.cross;
ps3_event.analog_changed.button.square = cur.analog.button.square - prev.analog.button.square;
return ps3_event;
}
/********************/
/* A N A L O G */
/********************/
ps3_analog_stick_t ps3_parse_packet_analog_stick( uint8_t *packet )
{
ps3_analog_stick_t ps3_analog_stick;
const uint8_t int_offset = 0x80;
ps3_analog_stick.lx = (int16_t)packet[ps3_packet_index_analog_stick_lx] - int_offset;
ps3_analog_stick.ly = (int16_t)packet[ps3_packet_index_analog_stick_ly] - int_offset;
ps3_analog_stick.rx = (int16_t)packet[ps3_packet_index_analog_stick_rx] - int_offset;
ps3_analog_stick.ry = (int16_t)packet[ps3_packet_index_analog_stick_ry] - int_offset;
return ps3_analog_stick;
}
ps3_analog_button_t ps3_parse_packet_analog_button( uint8_t *packet )
{
ps3_analog_button_t ps3_analog_button;
ps3_analog_button.up = packet[ps3_packet_index_analog_button_up];
ps3_analog_button.right = packet[ps3_packet_index_analog_button_right];
ps3_analog_button.down = packet[ps3_packet_index_analog_button_down];
ps3_analog_button.left = packet[ps3_packet_index_analog_button_left];
ps3_analog_button.l2 = packet[ps3_packet_index_analog_button_l2];
ps3_analog_button.r2 = packet[ps3_packet_index_analog_button_r2];
ps3_analog_button.l1 = packet[ps3_packet_index_analog_button_l1];
ps3_analog_button.r1 = packet[ps3_packet_index_analog_button_r1];
ps3_analog_button.triangle = packet[ps3_packet_index_analog_button_triangle];
ps3_analog_button.circle = packet[ps3_packet_index_analog_button_circle];
ps3_analog_button.cross = packet[ps3_packet_index_analog_button_cross];
ps3_analog_button.square = packet[ps3_packet_index_analog_button_square];
return ps3_analog_button;
}
/*********************/
/* B U T T O N S */
/*********************/
ps3_button_t ps3_parse_packet_buttons( uint8_t *packet )
{
ps3_button_t ps3_button;
uint32_t ps3_buttons_raw = *((uint32_t*)&packet[ps3_packet_index_buttons_raw]);
ps3_button.select = (ps3_buttons_raw & ps3_button_mask_select) ? true : false;
ps3_button.l3 = (ps3_buttons_raw & ps3_button_mask_l3) ? true : false;
ps3_button.r3 = (ps3_buttons_raw & ps3_button_mask_r3) ? true : false;
ps3_button.start = (ps3_buttons_raw & ps3_button_mask_start) ? true : false;
ps3_button.up = (ps3_buttons_raw & ps3_button_mask_up) ? true : false;
ps3_button.right = (ps3_buttons_raw & ps3_button_mask_right) ? true : false;
ps3_button.down = (ps3_buttons_raw & ps3_button_mask_down) ? true : false;
ps3_button.left = (ps3_buttons_raw & ps3_button_mask_left) ? true : false;
ps3_button.l2 = (ps3_buttons_raw & ps3_button_mask_l2) ? true : false;
ps3_button.r2 = (ps3_buttons_raw & ps3_button_mask_r2) ? true : false;
ps3_button.l1 = (ps3_buttons_raw & ps3_button_mask_l1) ? true : false;
ps3_button.r1 = (ps3_buttons_raw & ps3_button_mask_r1) ? true : false;
ps3_button.triangle = (ps3_buttons_raw & ps3_button_mask_triangle) ? true : false;
ps3_button.circle = (ps3_buttons_raw & ps3_button_mask_circle) ? true : false;
ps3_button.cross = (ps3_buttons_raw & ps3_button_mask_cross) ? true : false;
ps3_button.square = (ps3_buttons_raw & ps3_button_mask_square) ? true : false;
ps3_button.ps = (ps3_buttons_raw & ps3_button_mask_ps) ? true : false;
return ps3_button;
}
/*******************************/
/* S T A T U S F L A G S */
/*******************************/
ps3_status_t ps3_parse_packet_status( uint8_t *packet )
{
ps3_status_t ps3_status;
ps3_status.battery = packet[ps3_packet_index_status+1];
ps3_status.charging = ps3_status.battery == ps3_status_battery_charging;
ps3_status.connection = (packet[ps3_packet_index_status+2] & ps3_status_mask_bluetooth) ? ps3_status_connection_bluetooth : ps3_status_connection_usb;
ps3_status.rumbling = (packet[ps3_packet_index_status+2] & ps3_status_mask_rumbling) ? false: true;
return ps3_status;
}
/********************/
/* S E N S O R S */
/********************/
ps3_sensor_t ps3_parse_packet_sensor( uint8_t *packet )
{
ps3_sensor_t ps3_sensor;
const uint16_t int_offset = 0x200;
ps3_sensor.accelerometer.x = (packet[ps3_packet_index_sensor_accelerometer_x] << 8) + packet[ps3_packet_index_sensor_accelerometer_x+1] - int_offset;
ps3_sensor.accelerometer.y = (packet[ps3_packet_index_sensor_accelerometer_y] << 8) + packet[ps3_packet_index_sensor_accelerometer_y+1] - int_offset;
ps3_sensor.accelerometer.z = (packet[ps3_packet_index_sensor_accelerometer_z] << 8) + packet[ps3_packet_index_sensor_accelerometer_z+1] - int_offset;
ps3_sensor.gyroscope.z = (packet[ps3_packet_index_sensor_gyroscope_z] << 8) + packet[ps3_packet_index_sensor_gyroscope_z+1] - int_offset;
return ps3_sensor;
}

View File

@@ -0,0 +1,152 @@
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "include/ps3.h"
#include "include/ps3_int.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"
#define PS3_TAG "PS3_SPP"
#define PS3_DEVICE_NAME "PS3 Host"
#define PS3_SERVER_NAME "PS3_SERVER"
/********************************************************************************/
/* L O C A L F U N C T I O N P R O T O T Y P E S */
/********************************************************************************/
static void ps3_spp_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
/********************************************************************************/
/* P U B L I C F U N C T I O N S */
/********************************************************************************/
/*******************************************************************************
**
** Function ps3_spp_init
**
** Description Initialise the SPP server to allow to be connected to
**
** Returns void
**
*******************************************************************************/
void ps3_spp_init()
{
esp_err_t ret;
#ifndef ARDUINO_ARCH_ESP32
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bt_controller_enable(BT_MODE)) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bluedroid_init()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bluedroid_enable()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
#endif
if ((ret = esp_spp_register_callback(ps3_spp_callback)) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_spp_init(ESP_SPP_MODE_CB)) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
}
/*******************************************************************************
**
** Function ps3_spp_deinit
**
** Description Deinitialise the SPP server
**
** Returns void
**
*******************************************************************************/
void ps3_spp_deinit()
{
esp_err_t ret;
if ((ret = esp_spp_deinit()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s spp deinit failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
#ifndef ARDUINO_ARCH_ESP32
if ((ret = esp_bluedroid_disable()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s disable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bluedroid_deinit()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s deinitialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bt_controller_disable()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s disable controller failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
if ((ret = esp_bt_controller_deinit()) != ESP_OK) {
ESP_LOGE(PS3_TAG, "%s deinitialize controller failed: %s\n", __func__, esp_err_to_name(ret));
return;
}
#endif
}
/********************************************************************************/
/* L O C A L F U N C T I O N S */
/********************************************************************************/
/*******************************************************************************
**
** Function ps3_spp_callback
**
** Description Callback for SPP events, only used for the init event to
** configure the SPP server
**
** Returns void
**
*******************************************************************************/
static void ps3_spp_callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
if (event == ESP_SPP_INIT_EVT) {
ESP_LOGI(PS3_TAG, "ESP_SPP_INIT_EVT");
esp_bt_dev_set_device_name(PS3_DEVICE_NAME);
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
#else
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE);
#endif
esp_spp_start_srv(ESP_SPP_SEC_NONE,ESP_SPP_ROLE_SLAVE, 0, PS3_SERVER_NAME);
}
}

View File

@@ -0,0 +1,68 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef BT_TYPES_H
#define BT_TYPES_H
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t UINT8;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
typedef int8_t INT8;
typedef int16_t INT16;
typedef int32_t INT32;
typedef bool BOOLEAN;
/* Define the header of each buffer used in the Bluetooth stack.
*/
typedef struct {
uint16_t event;
uint16_t len;
uint16_t offset;
uint16_t layer_specific;
uint8_t data[];
} BT_HDR;
#define BT_PSM_HIDC 0x0011
#define BT_PSM_HIDI 0x0013
typedef struct {
UINT8 qos_flags; /* TBD */
UINT8 service_type; /* see below */
UINT32 token_rate; /* bytes/second */
UINT32 token_bucket_size; /* bytes */
UINT32 peak_bandwidth; /* bytes/second */
UINT32 latency; /* microseconds */
UINT32 delay_variation; /* microseconds */
} FLOW_SPEC;
/* bd addr length and type */
#ifndef BD_ADDR_LEN
#define BD_ADDR_LEN 6
typedef uint8_t BD_ADDR[BD_ADDR_LEN];
#endif
#endif

View File

@@ -0,0 +1,62 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* This file contains the Bluetooth Manager (BTM) API function external
* definitions.
*
******************************************************************************/
#ifndef BTM_API_H
#define BTM_API_H
#include "stack/bt_types.h"
#include "common/bt_target.h"
/* Security service definitions (BTM_SetSecurityLevel)
** Used for Authorization APIs
*/
/* Update these as services are added */
#define BTM_SEC_SERVICE_FIRST_EMPTY 51
#ifndef BTM_SEC_MAX_SERVICES
#define BTM_SEC_MAX_SERVICES 65
#endif
/*******************************************************************************
**
** Function BTM_SetSecurityLevel
**
** Description Register service security level with Security Manager. Each
** service must register its requirements regardless of the
** security level that is used. This API is called once for originators
** nad again for acceptors of connections.
**
** Returns TRUE if registered OK, else FALSE
**
*******************************************************************************/
//extern
BOOLEAN BTM_SetSecurityLevel (BOOLEAN is_originator, const char *p_name,
UINT8 service_id, UINT16 sec_level,
UINT16 psm, UINT32 mx_proto_id,
UINT32 mx_chan_id);
#endif /* BTM_API_H */

View File

@@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright (C) 2009-2013 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef GAP_API_H
#define GAP_API_H
#include "stack/profiles_api.h"
#include "stack/btm_api.h"
#include "stack/l2c_api.h"
/*****************************************************************************
** Constants
*****************************************************************************/
/*** GAP Error and Status Codes ***/
#define GAP_EVT_CONN_OPENED 0x0100
#define GAP_EVT_CONN_CLOSED 0x0101
#define GAP_EVT_CONN_DATA_AVAIL 0x0102
#define GAP_EVT_CONN_CONGESTED 0x0103
#define GAP_EVT_CONN_UNCONGESTED 0x01043
/*** used in connection variables and functions ***/
#define GAP_INVALID_HANDLE 0xFFFF
/*****************************************************************************
** Type Definitions
*****************************************************************************/
/*
** Callback function for connection services
*/
typedef void (tGAP_CONN_CALLBACK) (UINT16 gap_handle, UINT16 event);
/*****************************************************************************
** External Function Declarations
*****************************************************************************/
/*** Functions for L2CAP connection interface ***/
/*******************************************************************************
**
** Function GAP_ConnOpen
**
** Description This function is called to open a generic L2CAP connection.
**
** Returns handle of the connection if successful, else GAP_INVALID_HANDLE
**
*******************************************************************************/
extern UINT16 GAP_ConnOpen (const char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
BD_ADDR p_rem_bda, UINT16 psm, tL2CAP_CFG_INFO *p_cfg,
tL2CAP_ERTM_INFO *ertm_info,
UINT16 security, UINT8 chan_mode_mask, tGAP_CONN_CALLBACK *p_cb);
/*******************************************************************************
**
** Function GAP_ConnClose
**
** Description This function is called to close a connection.
**
** Returns BT_PASS - closed OK
** GAP_ERR_BAD_HANDLE - invalid handle
**
*******************************************************************************/
extern UINT16 GAP_ConnClose (UINT16 gap_handle);
/*******************************************************************************
**
** Function GAP_ConnBTRead
**
** Description GKI buffer aware applications will call this function after
** receiving an GAP_EVT_RXDATA event to process the incoming
** data buffer.
**
** Returns BT_PASS - data read
** GAP_ERR_BAD_HANDLE - invalid handle
** GAP_NO_DATA_AVAIL - no data available
**
*******************************************************************************/
extern UINT16 GAP_ConnBTRead (UINT16 gap_handle, BT_HDR **pp_buf);
/*******************************************************************************
**
** Function GAP_ConnBTWrite
**
** Description GKI buffer aware applications can call this function to write data
** by passing a pointer to the GKI buffer of data.
**
** Returns BT_PASS - data read
** GAP_ERR_BAD_HANDLE - invalid handle
** GAP_ERR_BAD_STATE - connection not established
** GAP_INVALID_BUF_OFFSET - buffer offset is invalid
*******************************************************************************/
extern UINT16 GAP_ConnBTWrite (UINT16 gap_handle, BT_HDR *p_buf);
/*******************************************************************************
**
** Function GAP_ConnGetL2CAPCid
**
** Description Returns the L2CAP channel id
**
** Parameters: handle - Handle of the connection
**
** Returns UINT16 - The L2CAP channel id
** 0, if error
**
*******************************************************************************/
extern UINT16 GAP_ConnGetL2CAPCid (UINT16 gap_handle);
#endif /* GAP_API_H */

View File

@@ -0,0 +1,36 @@
/******************************************************************************
*
* Copyright (C) 1999-2014 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef HCIDEFS_H
#define HCIDEFS_H
#include "stack/bt_types.h"
/* Define the extended flow specification fields used by AMP */
typedef struct {
UINT8 id;
UINT8 stype;
UINT16 max_sdu_size;
UINT32 sdu_inter_time;
UINT32 access_latency;
UINT32 flush_timeout;
} tHCI_EXT_FLOW_SPEC;
#endif

View File

@@ -0,0 +1,348 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
/******************************************************************************
*
* this file contains the L2CAP API definitions
*
******************************************************************************/
#ifndef L2C_API_H
#define L2C_API_H
#include <stdbool.h>
#include "stack/l2cdefs.h"
#include "stack/hcidefs.h"
/*****************************************************************************
** Constants
*****************************************************************************/
/* Define the minimum offset that L2CAP needs in a buffer. This is made up of
** HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9
*/
#define L2CAP_MIN_OFFSET 13 /* plus control(2), SDU length(2) */
/* result code for L2CA_DataWrite() */
#define L2CAP_DW_FAILED false
#define L2CAP_DW_SUCCESS true
#define L2CAP_DW_CONGESTED 2
/*****************************************************************************
** Type Definitions
*****************************************************************************/
typedef struct {
#define L2CAP_FCR_BASIC_MODE 0x00
#define L2CAP_FCR_ERTM_MODE 0x03
#define L2CAP_FCR_STREAM_MODE 0x04
UINT8 mode;
UINT8 tx_win_sz;
UINT8 max_transmit;
UINT16 rtrans_tout;
UINT16 mon_tout;
UINT16 mps;
} tL2CAP_FCR_OPTS;
/* Define a structure to hold the configuration parameters. Since the
** parameters are optional, for each parameter there is a boolean to
** use to signify its presence or absence.
*/
typedef struct {
UINT16 result; /* Only used in confirm messages */
BOOLEAN mtu_present;
UINT16 mtu;
BOOLEAN qos_present;
FLOW_SPEC qos;
BOOLEAN flush_to_present;
UINT16 flush_to;
BOOLEAN fcr_present;
tL2CAP_FCR_OPTS fcr;
BOOLEAN fcs_present; /* Optionally bypasses FCS checks */
UINT8 fcs; /* '0' if desire is to bypass FCS, otherwise '1' */
BOOLEAN ext_flow_spec_present;
tHCI_EXT_FLOW_SPEC ext_flow_spec;
UINT16 flags; /* bit 0: 0-no continuation, 1-continuation */
} tL2CAP_CFG_INFO;
/*********************************
** Callback Functions Prototypes
**********************************/
/* Connection indication callback prototype. Parameters are
** BD Address of remote
** Local CID assigned to the connection
** PSM that the remote wants to connect to
** Identifier that the remote sent
*/
typedef void (tL2CA_CONNECT_IND_CB) (BD_ADDR, UINT16, UINT16, UINT8);
/* Connection confirmation callback prototype. Parameters are
** Local CID
** Result - 0 = connected, non-zero means failure reason
*/
typedef void (tL2CA_CONNECT_CFM_CB) (UINT16, UINT16);
/* Connection pending callback prototype. Parameters are
** Local CID
*/
typedef void (tL2CA_CONNECT_PND_CB) (UINT16);
/* Configuration indication callback prototype. Parameters are
** Local CID assigned to the connection
** Pointer to configuration info
*/
typedef void (tL2CA_CONFIG_IND_CB) (UINT16, tL2CAP_CFG_INFO *);
/* Configuration confirm callback prototype. Parameters are
** Local CID assigned to the connection
** Pointer to configuration info
*/
typedef void (tL2CA_CONFIG_CFM_CB) (UINT16, tL2CAP_CFG_INFO *);
/* Disconnect indication callback prototype. Parameters are
** Local CID
** Boolean whether upper layer should ack this
*/
typedef void (tL2CA_DISCONNECT_IND_CB) (UINT16, BOOLEAN);
/* Disconnect confirm callback prototype. Parameters are
** Local CID
** Result
*/
typedef void (tL2CA_DISCONNECT_CFM_CB) (UINT16, UINT16);
/* QOS Violation indication callback prototype. Parameters are
** BD Address of violating device
*/
typedef void (tL2CA_QOS_VIOLATION_IND_CB) (BD_ADDR);
/* Data received indication callback prototype. Parameters are
** Local CID
** Address of buffer
*/
typedef void (tL2CA_DATA_IND_CB) (UINT16, BT_HDR *);
/* Congestion status callback protype. This callback is optional. If
** an application tries to send data when the transmit queue is full,
** the data will anyways be dropped. The parameter is:
** Local CID
** TRUE if congested, FALSE if uncongested
*/
typedef void (tL2CA_CONGESTION_STATUS_CB) (UINT16, BOOLEAN);
/* Transmit complete callback protype. This callback is optional. If
** set, L2CAP will call it when packets are sent or flushed. If the
** count is 0xFFFF, it means all packets are sent for that CID (eRTM
** mode only). The parameters are:
** Local CID
** Number of SDUs sent or dropped
*/
typedef void (tL2CA_TX_COMPLETE_CB) (UINT16, UINT16);
/* Define the structure that applications use to register with
** L2CAP. This structure includes callback functions. All functions
** MUST be provided, with the exception of the "connect pending"
** callback and "congestion status" callback.
*/
typedef struct {
tL2CA_CONNECT_IND_CB *pL2CA_ConnectInd_Cb;
tL2CA_CONNECT_CFM_CB *pL2CA_ConnectCfm_Cb;
tL2CA_CONNECT_PND_CB *pL2CA_ConnectPnd_Cb;
tL2CA_CONFIG_IND_CB *pL2CA_ConfigInd_Cb;
tL2CA_CONFIG_CFM_CB *pL2CA_ConfigCfm_Cb;
tL2CA_DISCONNECT_IND_CB *pL2CA_DisconnectInd_Cb;
tL2CA_DISCONNECT_CFM_CB *pL2CA_DisconnectCfm_Cb;
tL2CA_QOS_VIOLATION_IND_CB *pL2CA_QoSViolationInd_Cb;
tL2CA_DATA_IND_CB *pL2CA_DataInd_Cb;
tL2CA_CONGESTION_STATUS_CB *pL2CA_CongestionStatus_Cb;
tL2CA_TX_COMPLETE_CB *pL2CA_TxComplete_Cb;
} tL2CAP_APPL_INFO;
/* Define the structure that applications use to create or accept
** connections with enhanced retransmission mode.
*/
typedef struct {
UINT8 preferred_mode;
UINT8 allowed_modes;
UINT16 user_rx_buf_size;
UINT16 user_tx_buf_size;
UINT16 fcr_rx_buf_size;
UINT16 fcr_tx_buf_size;
} tL2CAP_ERTM_INFO;
#define L2CA_REGISTER(a,b,c) L2CA_Register(a,(tL2CAP_APPL_INFO *)b)
#define L2CA_DEREGISTER(a) L2CA_Deregister(a)
#define L2CA_CONNECT_REQ(a,b,c,d) L2CA_ErtmConnectReq(a,b,c)
#define L2CA_CONNECT_RSP(a,b,c,d,e,f,g) L2CA_ErtmConnectRsp(a,b,c,d,e,f)
#define L2CA_CONFIG_REQ(a,b) L2CA_ConfigReq(a,b)
#define L2CA_CONFIG_RSP(a,b) L2CA_ConfigRsp(a,b)
#define L2CA_DISCONNECT_REQ(a) L2CA_DisconnectReq(a)
#define L2CA_DISCONNECT_RSP(a) L2CA_DisconnectRsp(a)
#define L2CA_DATA_WRITE(a, b) L2CA_DataWrite(a, b)
/*****************************************************************************
** External Function Declarations
*****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
**
** Function L2CA_Register
**
** Description Other layers call this function to register for L2CAP
** services.
**
** Returns PSM to use or zero if error. Typically, the PSM returned
** is the same as was passed in, but for an outgoing-only
** connection to a dynamic PSM, a "virtual" PSM is returned
** and should be used in the calls to L2CA_ConnectReq() and
** BTM_SetSecurityLevel().
**
*******************************************************************************/
extern UINT16 L2CA_Register (UINT16 psm, tL2CAP_APPL_INFO *p_cb_info);
/*******************************************************************************
**
** Function L2CA_Deregister
**
** Description Other layers call this function to deregister for L2CAP
** services.
**
** Returns void
**
*******************************************************************************/
extern void L2CA_Deregister (UINT16 psm);
/*******************************************************************************
**
** Function L2CA_ErtmConnectReq
**
** Description Higher layers call this function to create an L2CAP connection
** that needs to use Enhanced Retransmission Mode.
** Note that the connection is not established at this time, but
** connection establishment gets started. The callback function
** will be invoked when connection establishes or fails.
**
** Returns the CID of the connection, or 0 if it failed to start
**
*******************************************************************************/
extern UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr,
tL2CAP_ERTM_INFO *p_ertm_info);
/*******************************************************************************
**
** Function L2CA_ErtmConnectRsp
**
** Description Higher layers call this function to accept an incoming
** L2CAP connection, for which they had gotten an connect
** indication callback, and for which the higher layer wants
** to use Enhanced Retransmission Mode.
**
** Returns TRUE for success, FALSE for failure
**
*******************************************************************************/
extern BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid,
UINT16 result, UINT16 status,
tL2CAP_ERTM_INFO *p_ertm_info);
/*******************************************************************************
**
** Function L2CA_ConfigReq
**
** Description Higher layers call this function to send configuration.
**
** Returns TRUE if configuration sent, else FALSE
**
*******************************************************************************/
extern BOOLEAN L2CA_ConfigReq (UINT16 cid, tL2CAP_CFG_INFO *p_cfg);
/*******************************************************************************
**
** Function L2CA_ConfigRsp
**
** Description Higher layers call this function to send a configuration
** response.
**
** Returns TRUE if configuration response sent, else FALSE
**
*******************************************************************************/
extern BOOLEAN L2CA_ConfigRsp (UINT16 cid, tL2CAP_CFG_INFO *p_cfg);
/*******************************************************************************
**
** Function L2CA_DisconnectReq
**
** Description Higher layers call this function to disconnect a channel.
**
** Returns TRUE if disconnect sent, else FALSE
**
*******************************************************************************/
extern BOOLEAN L2CA_DisconnectReq (UINT16 cid);
/*******************************************************************************
**
** Function L2CA_DisconnectRsp
**
** Description Higher layers call this function to acknowledge the
** disconnection of a channel.
**
** Returns void
**
*******************************************************************************/
extern BOOLEAN L2CA_DisconnectRsp (UINT16 cid);
/*******************************************************************************
**
** Function L2CA_DataWrite
**
** Description Higher layers call this function to write data.
**
** Returns L2CAP_DW_SUCCESS, if data accepted, else FALSE
** L2CAP_DW_CONGESTED, if data accepted and the channel is congested
** L2CAP_DW_FAILED, if error
**
*******************************************************************************/
extern UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data);
#ifdef __cplusplus
}
#endif
#endif /* L2C_API_H */

View File

@@ -0,0 +1,45 @@
/******************************************************************************
*
* Copyright (C) 1999-2012 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef L2CDEFS_H
#define L2CDEFS_H
/* Define the L2CAP connection result codes
*/
#define L2CAP_CONN_OK 0
#define L2CAP_CONN_PENDING 1
#define L2CAP_CONN_NO_PSM 2
#define L2CAP_CONN_SECURITY_BLOCK 3
#define L2CAP_CONN_NO_RESOURCES 4
#define L2CAP_CONN_BAD_CTLR_ID 5 /* AMP related */
#define L2CAP_CONN_TIMEOUT 0xEEEE
#define L2CAP_CONN_AMP_FAILED 254
#define L2CAP_CONN_NO_LINK 255 /* Add a couple of our own for internal use */
#define L2CAP_CONN_CANCEL 256 /* L2CAP connection cancelled */
/* Define the L2CAP configuration result codes
*/
#define L2CAP_CFG_OK 0
#define L2CAP_CFG_UNACCEPTABLE_PARAMS 1
#define L2CAP_CFG_FAILED_NO_REASON 2
#define L2CAP_CFG_UNKNOWN_OPTIONS 3
#define L2CAP_CFG_PENDING 4
#define L2CAP_CFG_FLOW_SPEC_REJECTED 5
#endif

View File

@@ -0,0 +1,27 @@
/******************************************************************************
*
* Copyright (C) 2009-2013 Broadcom Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
#ifndef PROFILES_API_H
#define PROFILES_API_H
/*****************************************************************************
** Constants
*****************************************************************************/
#define BT_PASS 0 /* Used for general successful function returns */
#endif /* PROFILES_API_H */