Merge branch 'feature/btdm_avrc' into 'master'

Feature/btdm avrc

The source branch "feature/btdm_avrc" includes classic Bluetooth profiles A2DP(sink role) and AVRCP(controller role); 
Menuconfig options to control whether to enable classic BT is added.

See merge request !591
This commit is contained in:
Jiang Jiang Jian 2017-04-13 14:36:58 +08:00
commit 6ace4f6fa4
189 changed files with 44183 additions and 415 deletions

View File

@ -3,7 +3,7 @@ menuconfig BT_ENABLED
help
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
config BLUEDROID_ENABLED
menuconfig BLUEDROID_ENABLED
bool "Bluedroid Bluetooth stack enabled"
depends on BT_ENABLED
default y
@ -12,25 +12,30 @@ config BLUEDROID_ENABLED
config BTC_TASK_STACK_SIZE
int "Bluetooth event (callback to application) task stack size"
depends on BT_ENABLED
depends on BLUEDROID_ENABLED
default 3072
help
This select btc task stack size
config BLUEDROID_MEM_DEBUG
bool "Bluedroid memory debug"
depends on BT_ENABLED
depends on BLUEDROID_ENABLED
default n
help
Bluedroid memory debug
config CLASSIC_BT_ENABLED
bool "Classic Bluetooth"
depends on BLUEDROID_ENABLED
default n
config BT_DRAM_RELEASE
bool "Release DRAM from Classic BT controller"
depends on BT_ENABLED
depends on BT_ENABLED && (!BLUEDROID_ENABLED || (BLUEDROID_ENABLED && !CLASSIC_BT_ENABLED))
default n
help
This option should only be used when BLE only.
Open this option will release about 30K DRAM from Classic BT.
Enabling this option will release about 30K DRAM from Classic BT.
The released DRAM will be used as system heap memory.
#disable now for app cpu due to a known issue
@ -49,7 +54,7 @@ config BTDM_CONTROLLER_RUN_CPU
menuconfig BT_HCI_UART
bool "HCI use UART as IO"
depends on BT_ENABLED
depends on BT_ENABLED && !BLUEDROID_ENABLED
default n
help
Default HCI use VHCI, if this option choose, HCI will use UART(0/1/2) as IO.

View File

@ -0,0 +1,133 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "bt_target.h"
#include <string.h>
#include "esp_err.h"
#include "esp_a2dp_api.h"
#include "esp_bt_main.h"
#include "btc_manage.h"
#include "btc_av.h"
#if BTC_AV_INCLUDED
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_A2DP, callback);
return ESP_OK;
}
esp_err_t esp_a2d_sink_init(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_INIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_deinit(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_DEINIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;
btc_av_args_t arg;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.data_cb = callback;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_msg_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_CONNECT_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
/* Switch to BTC context */
memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;
/* Switch to BTC context */
stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
#endif /* #if BTC_AV_INCLUDED */

View File

@ -0,0 +1,96 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "bt_target.h"
#include <string.h>
#include "esp_err.h"
#include "esp_avrc_api.h"
#include "esp_bt_main.h"
#include "btc_manage.h"
#include "btc_avrc.h"
#if BTC_AV_INCLUDED
esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_AVRC, callback);
return ESP_OK;
}
esp_err_t esp_avrc_ct_init(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC;
msg.act = BTC_AVRC_CTRL_API_INIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_avrc_ct_deinit(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC;
msg.act = BTC_AVRC_CTRL_API_DEINIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC;
msg.act = BTC_AVRC_CTRL_API_SND_PTCMD_EVT;
btc_avrc_args_t arg;
memset(&arg, 0, sizeof(btc_avrc_args_t));
arg.pt_cmd.tl = tl;
arg.pt_cmd.key_code = key_code;
arg.pt_cmd.key_state = key_state;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
#endif /* #if BTC_AV_INCLUDED */

View File

@ -12,10 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdlib.h>
#include <string.h>
#include "esp_bt_device.h"
#include "esp_bt_main.h"
#include "controller.h"
#include "btc_task.h"
#include "btc_dev.h"
const uint8_t *esp_bt_dev_get_address(void)
{
@ -24,3 +27,24 @@ const uint8_t *esp_bt_dev_get_address(void)
}
return controller_get_interface()->get_address()->address;
}
esp_err_t esp_bt_dev_set_device_name(const char *name)
{
btc_msg_t msg;
btc_dev_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (strlen(name) > ESP_DEV_DEVICE_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_DEV;
msg.act = BTC_DEV_ACT_SET_DEVICE_NAME;
strcpy(arg.set_dev_name.device_name, name);
return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@ -13,7 +13,7 @@
// limitations under the License.
#include <string.h>
#include "esp_bt_device.h"
#include "esp_bt_main.h"
#include "esp_gap_ble_api.h"
#include "bta_api.h"
@ -217,23 +217,7 @@ esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
esp_err_t esp_ble_gap_set_device_name(const char *name)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_ACT_SET_DEV_NAME;
strcpy(arg.set_dev_name.device_name, name);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
return esp_bt_dev_set_device_name(name);
}
uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)

View File

@ -0,0 +1,42 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "bt_target.h"
#include <string.h>
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "bt_trace.h"
#include "btc_manage.h"
#include "btc_gap_bt.h"
#if BTC_GAP_BT_INCLUDED
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode)
{
btc_msg_t msg;
btc_gap_bt_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BT;
msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE;
arg.set_scan_mode.mode = mode;
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* #if BTC_GAP_BT_INCLUDED */

View File

@ -0,0 +1,216 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __ESP_A2DP_API_H__
#define __ESP_A2DP_API_H__
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Media codec types supported by A2DP
#define ESP_A2D_MCT_SBC (0) /*!< SBC */
#define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */
#define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */
#define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */
#define ESP_A2D_MCT_NON_A2DP (0xff)
typedef uint8_t esp_a2d_mct_t;
/// A2DP media codec capabilities union
typedef struct {
esp_a2d_mct_t type; /*!< A2DP media codec type */
#define ESP_A2D_CIE_LEN_SBC (4)
#define ESP_A2D_CIE_LEN_M12 (4)
#define ESP_A2D_CIE_LEN_M24 (6)
#define ESP_A2D_CIE_LEN_ATRAC (7)
union {
uint8_t sbc[ESP_A2D_CIE_LEN_SBC];
uint8_t m12[ESP_A2D_CIE_LEN_M12];
uint8_t m24[ESP_A2D_CIE_LEN_M24];
uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC];
} cie; /*!< A2DP codec information element */
} __attribute__((packed)) esp_a2d_mcc_t;
/// Bluetooth A2DP connection states
typedef enum {
ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released */
ESP_A2D_CONNECTION_STATE_CONNECTING, /*!< connecting remote device */
ESP_A2D_CONNECTION_STATE_CONNECTED, /*!< connection established */
ESP_A2D_CONNECTION_STATE_DISCONNECTING /*!< disconnecting remote device */
} esp_a2d_connection_state_t;
/// Bluetooth A2DP disconnection reason
typedef enum {
ESP_A2D_DISC_RSN_NORMAL = 0, /*!< Finished disconnection that is initiated by local or remote device */
ESP_A2D_DISC_RSN_ABNORMAL /*!< Abnormal disconnection caused by signal loss */
} esp_a2d_disc_rsn_t;
/// Bluetooth A2DP datapath states
typedef enum {
ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */
ESP_A2D_AUDIO_STATE_STOPPED, /*!< audio stream datapath stopped */
ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */
} esp_a2d_audio_state_t;
/// A2DP callback events
typedef enum {
ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
ESP_A2D_AUDIO_STATE_EVT = 1, /*!< audio stream transmission state changed event */
ESP_A2D_AUDIO_CFG_EVT = 2 /*!< audio codec is configured */
} esp_a2d_cb_event_t;
/// A2DP state callback parameters
typedef union {
/**
* @brief ESP_A2D_CONNECTION_STATE_EVT
*/
struct a2d_conn_stat_param {
esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */
} conn_stat; /*!< A2DP connection status */
/**
* @brief ESP_A2D_AUDIO_STATE_EVT
*/
struct a2d_audio_stat_param {
esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} audio_stat; /*!< audio stream playing state */
/**
* @brief ESP_A2D_AUDIO_CFG_EVT
*/
struct a2d_audio_cfg_param {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */
} audio_cfg; /*!< media codec configuration infomation */
} esp_a2d_cb_param_t;
/**
* @brief A2DP profile callback function type
* @param event : Event type
* @param param : Pointer to callback parameter
*/
typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
/**
* @brief A2DP profile data callback function
*
* @param[in] buf : data received from A2DP source device and is PCM format decoder from SBC decoder;
* buf references to a static memory block and can be overwritten by upcoming data
*
* @param[in] len : size(in bytes) in buf
*
*/
typedef void (* esp_a2d_data_cb_t)(const uint8_t *buf, uint32_t len);
/**
* @brief Register application callback function to A2DP module. This function should be called
* only after esp_bluedroid_enable() completes successfully
*
* @param[in] callback: A2DP sink event callback function
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: if callback is a NULL function pointer
*
*/
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
/**
* @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
* from SBC format. This function should be called only after esp_bluedroid_enable()
* completes successfully
*
* @param[in] callback: A2DP data callback function
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: if callback is a NULL function pointer
*
*/
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback);
/**
*
* @brief Initialize the bluetooth A2DP sink module. This function should be called
* after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: if the initialization request is sent successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_sink_init(void);
/**
*
* @brief De-initialize for A2DP sink module. This function
* should be called only after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_sink_deinit(void);
/**
*
* @brief Connect the remote bluetooth device bluetooth, must after esp_a2d_sink_init()
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: connect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect the remote bluetooth device
*
* @param[in] remote_bda: remote bluetooth device address
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_A2DP_API_H__ */

View File

@ -0,0 +1,153 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __ESP_AVRC_API_H__
#define __ESP_AVRC_API_H__
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/// AVRC feature bit mask
typedef enum {
ESP_AVRC_FEAT_RCTG = 0x0001, /*!< remote control target */
ESP_AVRC_FEAT_RCCT = 0x0002, /*!< remote control controller */
ESP_AVRC_FEAT_VENDOR = 0x0008, /*!< remote control vendor dependent commands */
ESP_AVRC_FEAT_BROWSE = 0x0010, /*!< use browsing channel */
ESP_AVRC_FEAT_META_DATA = 0x0040, /*!< remote control metadata transfer command/response */
ESP_AVRC_FEAT_ADV_CTRL = 0x0200, /*!< remote control advanced control commmand/response */
} esp_avrc_features_t;
/// AVRC passthrough command code
typedef enum {
ESP_AVRC_PT_CMD_PLAY = 0x44, /*!< play */
ESP_AVRC_PT_CMD_STOP = 0x45, /*!< stop */
ESP_AVRC_PT_CMD_PAUSE = 0x46, /*!< pause */
ESP_AVRC_PT_CMD_FORWARD = 0x4B, /*!< forward */
ESP_AVRC_PT_CMD_BACKWARD = 0x4C /*!< backward */
} esp_avrc_pt_cmd_t;
/// AVRC passthrough command state
typedef enum {
ESP_AVRC_PT_CMD_STATE_PRESSED = 0, /*!< key pressed */
ESP_AVRC_PT_CMD_STATE_RELEASED = 1 /*!< key released */
} esp_avrc_pt_cmd_state_t;
/// AVRC Controller callback events
typedef enum {
ESP_AVRC_CT_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
ESP_AVRC_CT_PASSTHROUGH_RSP_EVT = 1, /*!< passthrough response event */
ESP_AVRC_CT_MAX_EVT
} esp_avrc_ct_cb_event_t;
/// AVRC controller callback parameters
typedef union {
/**
* @brief ESP_AVRC_CT_CONNECTION_STATE_EVT
*/
struct avrc_ct_conn_stat_param {
bool connected; /*!< whether AVRC connection is set up */
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} conn_stat; /*!< AVRC connection status */
/**
* @brief ESP_AVRC_CT_PASSTHROUGH_RSP_EVT
*/
struct avrc_ct_psth_rsp_param {
uint8_t tl; /*!< transaction label, 0 to 15 */
uint8_t key_code; /*!< passthrough command code */
uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */
} psth_rsp; /*!< passthrough command response */
} esp_avrc_ct_cb_param_t;
/**
* @brief AVRCP controller callback function type
* @param event : Event type
* @param param : Pointer to callback parameter union
*/
typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
/**
* @brief Register application callbacks to AVRCP module; for now only AVRCP Controller
* role is supported. This function should be called after esp_bluedroid_enable()
* completes successfully
*
* @param[in] callback: AVRCP controller callback function
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
/**
*
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
* after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_avrc_ct_init(void);
/**
*
* @brief De-initialize AVRCP controller module. This function should be called after
* after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*/
esp_err_t esp_avrc_ct_deinit(void);
/**
* @brief Send passthrough command to AVRCP target, This function should be called after
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
*
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
* @param[in] key_code : passthrough command code, e.g. ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STOP, etc.
* @param[in] key_state : passthrough command key state, ESP_AVRC_PT_CMD_STATE_PRESSED or
* ESP_AVRC_PT_CMD_STATE_PRESSED
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*/
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_AVRC_API_H__ */

View File

@ -17,6 +17,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
@ -30,6 +32,21 @@ extern "C" {
*/
const uint8_t *esp_bt_dev_get_address(void);
/**
* @brief Set bluetooth device name. This function should be called after esp_bluedroid_enable()
* completes successfully
*
* @param[in] name : device name to be set
*
* @return
* - ESP_OK : Succeed
* - ESP_ERR_INVALID_ARG : if name is NULL pointer or empty, or string length out of limit
* - ESP_INVALID_STATE : if bluetooth stack is not yet enabled
* - ESP_FAIL : others
*/
esp_err_t esp_bt_dev_set_device_name(const char *name);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,52 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __ESP_GAP_BT_API_H__
#define __ESP_GAP_BT_API_H__
#include <stdint.h>
#include "esp_err.h"
#include "esp_bt_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Discoverability and Connectability mode
typedef enum {
ESP_BT_SCAN_MODE_NONE = 0, /*!< Neither discoverable nor connectable */
ESP_BT_SCAN_MODE_CONNECTABLE, /*!< Connectable but not discoverable */
ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE /*!< both discoverable and connectaable */
} esp_bt_scan_mode_t;
/**
* @brief Set discoverability and connectability mode for legacy bluetooth. This function should
* be called after esp_bluedroid_enable() completes successfully
*
* @param[in] mode : one of the enums of bt_scan_mode_t
*
* @return
* - ESP_OK : Succeed
* - ESP_ERR_INVALID_ARG: if argument invalid
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*/
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* __ESP_GAP_BT_API_H__ */

View File

@ -0,0 +1,316 @@
/******************************************************************************
*
* Copyright (C) 2008-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 is the implementation for the audio/video registration module.
*
******************************************************************************/
#include "bt_target.h"
#include <string.h>
#include "bta_ar_api.h"
#include "bta_ar_int.h"
#if BTA_AR_INCLUDED
/* AV control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_AR_CB bta_ar_cb;
#endif
/*******************************************************************************
**
** Function bta_ar_id
**
** Description This function maps sys_id to ar id mask.
**
** Returns void
**
*******************************************************************************/
static UINT8 bta_ar_id(tBTA_SYS_ID sys_id)
{
UINT8 mask = 0;
if (sys_id == BTA_ID_AV) {
mask = BTA_AR_AV_MASK;
} else if (sys_id == BTA_ID_AVK) {
mask = BTA_AR_AVK_MASK;
}
return mask;
}
/*******************************************************************************
**
** Function bta_ar_init
**
** Description This function is called to register to AVDTP.
**
** Returns void
**
*******************************************************************************/
void bta_ar_init(void)
{
/* initialize control block */
memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
}
/*******************************************************************************
**
** Function bta_ar_reg_avdt
**
** Description This function is called to register to AVDTP.
**
** Returns void
**
*******************************************************************************/
static void bta_ar_avdt_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
{
/* route the AVDT registration callback to av or avk */
if (bta_ar_cb.p_av_conn_cback) {
(*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data);
}
if (bta_ar_cb.p_avk_conn_cback) {
(*bta_ar_cb.p_avk_conn_cback)(handle, bd_addr, event, p_data);
}
}
/*******************************************************************************
**
** Function bta_ar_reg_avdt
**
** Description AR module registration to AVDT.
**
** Returns void
**
*******************************************************************************/
void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id)
{
UINT8 mask = 0;
if (sys_id == BTA_ID_AV) {
bta_ar_cb.p_av_conn_cback = p_cback;
mask = BTA_AR_AV_MASK;
} else if (sys_id == BTA_ID_AVK) {
bta_ar_cb.p_avk_conn_cback = p_cback;
mask = BTA_AR_AVK_MASK;
}
#if (BTA_AR_DEBUG == TRUE)
else {
APPL_TRACE_ERROR("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
}
#endif
if (mask) {
if (bta_ar_cb.avdt_registered == 0) {
AVDT_Register(p_reg, bta_ar_avdt_cback);
}
bta_ar_cb.avdt_registered |= mask;
}
}
/*******************************************************************************
**
** Function bta_ar_dereg_avdt
**
** Description This function is called to de-register from AVDTP.
**
** Returns void
**
*******************************************************************************/
void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id)
{
UINT8 mask = 0;
if (sys_id == BTA_ID_AV) {
bta_ar_cb.p_av_conn_cback = NULL;
mask = BTA_AR_AV_MASK;
} else if (sys_id == BTA_ID_AVK) {
bta_ar_cb.p_avk_conn_cback = NULL;
mask = BTA_AR_AVK_MASK;
}
bta_ar_cb.avdt_registered &= ~mask;
if (bta_ar_cb.avdt_registered == 0) {
AVDT_Deregister();
}
}
/*******************************************************************************
**
** Function bta_ar_avdt_conn
**
** Description This function is called to let ar know that some AVDTP profile
** is connected for this sys_id.
** If the other sys modules started a timer for PENDING_EVT,
** the timer can be stopped now.
**
** Returns void
**
*******************************************************************************/
void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr)
{
UINT8 event = BTA_AR_AVDT_CONN_EVT;
tAVDT_CTRL data;
if (sys_id == BTA_ID_AV) {
if (bta_ar_cb.p_avk_conn_cback) {
(*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data);
}
} else if (sys_id == BTA_ID_AVK) {
if (bta_ar_cb.p_av_conn_cback) {
(*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data);
}
}
}
/*******************************************************************************
**
** Function bta_ar_reg_avct
**
** Description This function is called to register to AVCTP.
**
** Returns void
**
*******************************************************************************/
void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id)
{
UINT8 mask = bta_ar_id (sys_id);
if (mask) {
if (bta_ar_cb.avct_registered == 0) {
AVCT_Register(mtu, mtu_br, sec_mask);
}
bta_ar_cb.avct_registered |= mask;
}
}
/*******************************************************************************
**
** Function bta_ar_dereg_avct
**
** Description This function is called to deregister from AVCTP.
**
** Returns void
**
*******************************************************************************/
void bta_ar_dereg_avct(tBTA_SYS_ID sys_id)
{
UINT8 mask = bta_ar_id (sys_id);
bta_ar_cb.avct_registered &= ~mask;
if (bta_ar_cb.avct_registered == 0) {
AVCT_Deregister();
}
}
/******************************************************************************
**
** Function bta_ar_reg_avrc
**
** Description This function is called to register an SDP record for AVRCP.
**
** Returns void
**
******************************************************************************/
void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_name,
UINT16 categories, tBTA_SYS_ID sys_id)
{
UINT8 mask = bta_ar_id (sys_id);
UINT8 temp[8], *p;
if (!mask || !categories) {
return;
}
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
if (bta_ar_cb.sdp_tg_handle == 0) {
bta_ar_cb.tg_registered = mask;
bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle);
bta_sys_add_uuid(service_uuid);
}
/* only one TG is allowed (first-come, first-served).
* If sdp_tg_handle is non-0, ignore this request */
} else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
bta_ar_cb.ct_categories [mask - 1] = categories;
categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
if (bta_ar_cb.sdp_ct_handle == 0) {
bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle);
bta_sys_add_uuid(service_uuid);
} else {
/* multiple CTs are allowed.
* Change supported categories on the second one */
p = temp;
UINT16_TO_BE_STREAM(p, categories);
SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
(UINT32)2, (UINT8 *)temp);
}
}
}
/******************************************************************************
**
** Function bta_ar_dereg_avrc
**
** Description This function is called to de-register/delete an SDP record for AVRCP.
**
** Returns void
**
******************************************************************************/
void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id)
{
UINT8 mask = bta_ar_id (sys_id);
UINT16 categories = 0;
UINT8 temp[8], *p;
if (!mask) {
return;
}
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
bta_ar_cb.tg_registered = 0;
SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
bta_ar_cb.sdp_tg_handle = 0;
bta_sys_remove_uuid(service_uuid);
}
} else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
if (bta_ar_cb.sdp_ct_handle) {
bta_ar_cb.ct_categories [mask - 1] = 0;
categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
if (!categories) {
/* no CT is still registered - cleaup */
SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
bta_ar_cb.sdp_ct_handle = 0;
bta_sys_remove_uuid(service_uuid);
} else {
/* change supported categories to the remaning one */
p = temp;
UINT16_TO_BE_STREAM(p, categories);
SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
(UINT32)2, (UINT8 *)temp);
}
}
}
}
#endif /* #if BTA_AR_INCLUDED */

View File

@ -0,0 +1,63 @@
/******************************************************************************
*
* Copyright (C) 2008-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 is the private interface file for the BTA audio/video registration
* module.
*
******************************************************************************/
#ifndef BTA_AR_INT_H
#define BTA_AR_INT_H
#include "bta_av_api.h"
#ifndef BTA_AR_DEBUG
#define BTA_AR_DEBUG FALSE
#endif
#define BTA_AR_AV_MASK 0x01
#define BTA_AR_AVK_MASK 0x02
/* data associated with BTA_AR */
typedef struct {
tAVDT_CTRL_CBACK *p_av_conn_cback; /* av connection callback function */
tAVDT_CTRL_CBACK *p_avk_conn_cback; /* avk connection callback function */
UINT8 avdt_registered;
UINT8 avct_registered;
UINT32 sdp_tg_handle;
UINT32 sdp_ct_handle;
UINT16 ct_categories[2];
UINT8 tg_registered;
tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the connection. */
} tBTA_AR_CB;
/*****************************************************************************
** Global data
*****************************************************************************/
/* control block declaration */
#if BTA_DYNAMIC_MEMORY == FALSE
extern tBTA_AR_CB bta_ar_cb;
#else
extern tBTA_AR_CB *bta_ar_cb_ptr;
#define bta_ar_cb (*bta_ar_cb_ptr)
#endif
#endif /* BTA_AR_INT_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,573 @@
/******************************************************************************
*
* Copyright (C) 2011-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 is the implementation of the API for the advanced audio/video (AV)
* subsystem of BTA, Broadcom's Bluetooth application layer for mobile
* phones.
*
******************************************************************************/
#include "bt_target.h"
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_av_api.h"
#include "bta_av_int.h"
#include "gki.h"
#include <string.h>
/*****************************************************************************
** Constants
*****************************************************************************/
static const tBTA_SYS_REG bta_av_reg = {
bta_av_hdl_event,
BTA_AvDisable
};
/*******************************************************************************
**
** Function BTA_AvEnable
**
** Description Enable the advanced audio/video service. When the enable
** operation is complete the callback function will be
** called with a BTA_AV_ENABLE_EVT. This function must
** be called before other function in the AV API are
** called.
**
** Returns void
**
*******************************************************************************/
void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, tBTA_AV_CBACK *p_cback)
{
tBTA_AV_API_ENABLE *p_buf;
/* register with BTA system manager */
bta_sys_register(BTA_ID_AV, &bta_av_reg);
if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL) {
p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
p_buf->p_cback = p_cback;
p_buf->features = features;
p_buf->sec_mask = sec_mask;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvDisable
**
** Description Disable the advanced audio/video service.
**
** Returns void
**
*******************************************************************************/
void BTA_AvDisable(void)
{
BT_HDR *p_buf;
bta_sys_deregister(BTA_ID_AV);
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_AV_API_DISABLE_EVT;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvRegister
**
** Description Register the audio or video service to stack. When the
** operation is complete the callback function will be
** called with a BTA_AV_REGISTER_EVT. This function must
** be called before AVDT stream is open.
**
**
** Returns void
**
*******************************************************************************/
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos)
{
tBTA_AV_API_REG *p_buf;
if ((p_buf = (tBTA_AV_API_REG *) GKI_getbuf(sizeof(tBTA_AV_API_REG))) != NULL) {
p_buf->hdr.layer_specific = chnl;
p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
if (p_service_name) {
BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
p_buf->p_service_name[BTA_SERVICE_NAME_LEN - 1] = 0;
} else {
p_buf->p_service_name[0] = 0;
}
p_buf->app_id = app_id;
p_buf->p_app_data_cback = p_data_cback;
p_buf->bta_av_cos = bta_av_cos;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvDeregister
**
** Description Deregister the audio or video service
**
** Returns void
**
*******************************************************************************/
void BTA_AvDeregister(tBTA_AV_HNDL hndl)
{
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->layer_specific = hndl;
p_buf->event = BTA_AV_API_DEREGISTER_EVT;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvOpen
**
** Description Opens an advanced audio/video connection to a peer device.
** When connection is open callback function is called
** with a BTA_AV_OPEN_EVT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask,
UINT16 uuid)
{
tBTA_AV_API_OPEN *p_buf;
if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL) {
p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
p_buf->hdr.layer_specific = handle;
bdcpy(p_buf->bd_addr, bd_addr);
p_buf->use_rc = use_rc;
p_buf->sec_mask = sec_mask;
p_buf->switch_res = BTA_AV_RS_NONE;
p_buf->uuid = uuid;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvClose
**
** Description Close the current streams.
**
** Returns void
**
*******************************************************************************/
void BTA_AvClose(tBTA_AV_HNDL handle)
{
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_AV_API_CLOSE_EVT;
p_buf->layer_specific = handle;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvDisconnect
**
** Description Close the connection to the address.
**
** Returns void
**
*******************************************************************************/
void BTA_AvDisconnect(BD_ADDR bd_addr)
{
tBTA_AV_API_DISCNT *p_buf;
if ((p_buf = (tBTA_AV_API_DISCNT *) GKI_getbuf(sizeof(tBTA_AV_API_DISCNT))) != NULL) {
p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
bdcpy(p_buf->bd_addr, bd_addr);
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvStart
**
** Description Start audio/video stream data transfer.
**
** Returns void
**
*******************************************************************************/
void BTA_AvStart(void)
{
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_AV_API_START_EVT;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvEnable_Sink
**
** Description Enable/Disable A2DP Sink..
**
** Returns void
**
*******************************************************************************/
void BTA_AvEnable_Sink(int enable)
{
#if (BTA_AV_SINK_INCLUDED == TRUE)
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->event = BTA_AV_API_SINK_ENABLE_EVT;
p_buf->layer_specific = enable;
bta_sys_sendmsg(p_buf);
}
#else
return;
#endif
}
/*******************************************************************************
**
** Function BTA_AvStop
**
** Description Stop audio/video stream data transfer.
** If suspend is TRUE, this function sends AVDT suspend signal
** to the connected peer(s).
**
** Returns void
**
*******************************************************************************/
void BTA_AvStop(BOOLEAN suspend)
{
tBTA_AV_API_STOP *p_buf;
if ((p_buf = (tBTA_AV_API_STOP *) GKI_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL) {
p_buf->hdr.event = BTA_AV_API_STOP_EVT;
p_buf->flush = TRUE;
p_buf->suspend = suspend;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvReconfig
**
** Description Reconfigure the audio/video stream.
** If suspend is TRUE, this function tries the suspend/reconfigure
** procedure first.
** If suspend is FALSE or when suspend/reconfigure fails,
** this function closes and re-opens the AVDT connection.
**
** Returns void
**
*******************************************************************************/
void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info)
{
tBTA_AV_API_RCFG *p_buf;
if ((p_buf = (tBTA_AV_API_RCFG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL) {
p_buf->hdr.layer_specific = hndl;
p_buf->hdr.event = BTA_AV_API_RECONFIG_EVT;
p_buf->num_protect = num_protect;
p_buf->suspend = suspend;
p_buf->sep_info_idx = sep_info_idx;
p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvProtectReq
**
** Description Send a content protection request. This function can only
** be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len)
{
tBTA_AV_API_PROTECT_REQ *p_buf;
if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL) {
p_buf->hdr.layer_specific = hndl;
p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
p_buf->len = len;
if (p_data == NULL) {
p_buf->p_data = NULL;
} else {
p_buf->p_data = (UINT8 *) (p_buf + 1);
memcpy(p_buf->p_data, p_data, len);
}
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvProtectRsp
**
** Description Send a content protection response. This function must
** be called if a BTA_AV_PROTECT_REQ_EVT is received.
** This function can only be used if AV is enabled with
** feature BTA_AV_FEAT_PROTECT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len)
{
tBTA_AV_API_PROTECT_RSP *p_buf;
if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL) {
p_buf->hdr.layer_specific = hndl;
p_buf->hdr.event = BTA_AV_API_PROTECT_RSP_EVT;
p_buf->len = len;
p_buf->error_code = error_code;
if (p_data == NULL) {
p_buf->p_data = NULL;
} else {
p_buf->p_data = (UINT8 *) (p_buf + 1);
memcpy(p_buf->p_data, p_data, len);
}
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvRemoteCmd
**
** Description Send a remote control command. This function can only
** be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state)
{
tBTA_AV_API_REMOTE_CMD *p_buf;
if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) GKI_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL) {
p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
p_buf->hdr.layer_specific = rc_handle;
p_buf->msg.op_id = rc_id;
p_buf->msg.state = key_state;
p_buf->msg.p_pass_data = NULL;
p_buf->msg.pass_len = 0;
p_buf->label = label;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvVendorCmd
**
** Description Send a vendor dependent remote control command. This
** function can only be used if AV is enabled with feature
** BTA_AV_FEAT_VENDOR.
**
** Returns void
**
*******************************************************************************/
void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len)
{
tBTA_AV_API_VENDOR *p_buf;
if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) {
p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
p_buf->hdr.layer_specific = rc_handle;
p_buf->msg.hdr.ctype = cmd_code;
p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
p_buf->msg.hdr.subunit_id = 0;
p_buf->msg.company_id = p_bta_av_cfg->company_id;
p_buf->label = label;
p_buf->msg.vendor_len = len;
if (p_data == NULL) {
p_buf->msg.p_vendor_data = NULL;
} else {
p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
memcpy(p_buf->msg.p_vendor_data, p_data, len);
}
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvVendorRsp
**
** Description Send a vendor dependent remote control response.
** This function must be called if a BTA_AV_VENDOR_CMD_EVT
** is received. This function can only be used if AV is
** enabled with feature BTA_AV_FEAT_VENDOR.
**
** Returns void
**
*******************************************************************************/
void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id)
{
tBTA_AV_API_VENDOR *p_buf;
if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) {
p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
p_buf->hdr.layer_specific = rc_handle;
p_buf->msg.hdr.ctype = rsp_code;
p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
p_buf->msg.hdr.subunit_id = 0;
if (company_id) {
p_buf->msg.company_id = company_id;
} else {
p_buf->msg.company_id = p_bta_av_cfg->company_id;
}
p_buf->label = label;
p_buf->msg.vendor_len = len;
if (p_data == NULL) {
p_buf->msg.p_vendor_data = NULL;
} else {
p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
memcpy(p_buf->msg.p_vendor_data, p_data, len);
}
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvOpenRc
**
** Description Open an AVRCP connection toward the device with the
** specified handle
**
** Returns void
**
*******************************************************************************/
void BTA_AvOpenRc(tBTA_AV_HNDL handle)
{
tBTA_AV_API_OPEN_RC *p_buf;
if ((p_buf = (tBTA_AV_API_OPEN_RC *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL) {
p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
p_buf->hdr.layer_specific = handle;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvCloseRc
**
** Description Close an AVRCP connection
**
** Returns void
**
*******************************************************************************/
void BTA_AvCloseRc(UINT8 rc_handle)
{
tBTA_AV_API_CLOSE_RC *p_buf;
if ((p_buf = (tBTA_AV_API_CLOSE_RC *) GKI_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL) {
p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
p_buf->hdr.layer_specific = rc_handle;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function BTA_AvMetaRsp
**
** Description Send a Metadata/Advanced Control response. The message contained
** in p_pkt can be composed with AVRC utility functions.
** This function can only be used if AV is enabled with feature
** BTA_AV_FEAT_METADATA.
**
** Returns void
**
*******************************************************************************/
void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
BT_HDR *p_pkt)
{
tBTA_AV_API_META_RSP *p_buf;
if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) {
p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
p_buf->hdr.layer_specific = rc_handle;
p_buf->rsp_code = rsp_code;
p_buf->p_pkt = p_pkt;
p_buf->is_rsp = TRUE;
p_buf->label = label;
bta_sys_sendmsg(p_buf);
} else if (p_pkt) {
GKI_freebuf(p_pkt);
}
}
/*******************************************************************************
**
** Function BTA_AvMetaCmd
**
** Description Send a Metadata/Advanced Control command. The message contained
** in p_pkt can be composed with AVRC utility functions.
** This function can only be used if AV is enabled with feature
** BTA_AV_FEAT_METADATA.
** This message is sent only when the peer supports the TG role.
*8 The only command makes sense right now is the absolute volume command.
**
** Returns void
**
*******************************************************************************/
void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt)
{
tBTA_AV_API_META_RSP *p_buf;
if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) {
p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
p_buf->hdr.layer_specific = rc_handle;
p_buf->p_pkt = p_pkt;
p_buf->rsp_code = cmd_code;
p_buf->is_rsp = FALSE;
p_buf->label = label;
bta_sys_sendmsg(p_buf);
}
}
#endif /* BTA_AV_INCLUDED */

View File

@ -0,0 +1,208 @@
/******************************************************************************
*
* Copyright (C) 2005-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 compile-time configurable constants for advanced
* audio/video
*
******************************************************************************/
#include <stddef.h>
#include "bt_target.h"
#include "gki.h"
#include "bta_api.h"
#include "bta_av_int.h"
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
#ifndef BTA_AV_RC_PASS_RSP_CODE
#define BTA_AV_RC_PASS_RSP_CODE BTA_AV_RSP_NOT_IMPL
#endif
const UINT32 bta_av_meta_caps_co_ids[] = {
AVRC_CO_METADATA,
AVRC_CO_BROADCOM
};
/* AVRCP cupported categories */
#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT2)
/* Added to modify
** 1. flush timeout
** 2. Remove Group navigation support in SupportedFeatures
** 3. GetCapabilities supported event_ids list
** 4. GetCapabilities supported event_ids count
*/
/* Flushing partial avdtp packets can cause some headsets to disconnect the link
if receiving partial a2dp frames */
const UINT16 bta_av_audio_flush_to[] = {
0, /* 1 stream */
0, /* 2 streams */
0, /* 3 streams */
0, /* 4 streams */
0 /* 5 streams */
}; /* AVDTP audio transport channel flush timeout */
/* Note: Android doesnt support AVRC_SUPF_TG_GROUP_NAVI */
/* Note: if AVRC_SUPF_TG_GROUP_NAVI is set, bta_av_cfg.avrc_group should be TRUE */
#if AVRC_METADATA_INCLUDED == TRUE
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
#else
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1)
#endif
/*
* If the number of event IDs is changed in this array, BTA_AV_ NUM_RC_EVT_IDS also needs to be changed.
*/
const UINT8 bta_av_meta_caps_evt_ids[] = {
AVRC_EVT_PLAY_STATUS_CHANGE,
AVRC_EVT_TRACK_CHANGE,
AVRC_EVT_PLAY_POS_CHANGED,
/* TODO: Add support for these events
AVRC_EVT_APP_SETTING_CHANGE,
*/
};
#ifndef BTA_AV_NUM_RC_EVT_IDS
#define BTA_AV_NUM_RC_EVT_IDS (sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
#endif /* BTA_AV_NUM_RC_EVT_IDS */
/* the MTU for the AVRCP browsing channel */
#ifndef BTA_AV_MAX_RC_BR_MTU
#define BTA_AV_MAX_RC_BR_MTU 1008
#endif
const tBTA_AV_CFG bta_av_cfg = {
AVRC_CO_BROADCOM, /* AVRCP Company ID */
#if AVRC_METADATA_INCLUDED == TRUE
512, /* AVRCP MTU at L2CAP for control channel */
#else
48, /* AVRCP MTU at L2CAP for control channel */
#endif
BTA_AV_MAX_RC_BR_MTU, /* AVRCP MTU at L2CAP for browsing channel */
BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
BTA_AV_RC_SUPF_TG, /* AVRCP target categories */
672, /* AVDTP signaling channel MTU at L2CAP */
BTA_AV_MAX_A2DP_MTU, /* AVDTP audio transport channel MTU at L2CAP */
bta_av_audio_flush_to, /* AVDTP audio transport channel flush timeout */
6, /* AVDTP audio channel max data queue size */
BTA_AV_MAX_VDP_MTU, /* AVDTP video transport channel MTU at L2CAP */
600, /* AVDTP video transport channel flush timeout */
FALSE, /* TRUE, to accept AVRC 1.3 group nevigation command */
2, /* company id count in p_meta_co_ids */
BTA_AV_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
BTA_AV_RC_PASS_RSP_CODE,/* the default response code for pass through commands */
bta_av_meta_caps_co_ids,/* the metadata Get Capabilities response for company id */
bta_av_meta_caps_evt_ids,/* the the metadata Get Capabilities response for event id */
NULL, /* the action function table for VDP stream */
NULL, /* action function to register VDP */
{0}, /* Default AVRCP controller name */
{0}, /* Default AVRCP target name */
};
tBTA_AV_CFG *p_bta_av_cfg = (tBTA_AV_CFG *) &bta_av_cfg;
const UINT16 bta_av_rc_id[] = {
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
12=FAV_MENU, 13=EXIT */
0, /* not used */
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
4=4, 5=5, 6=6, 7=7,
8=8, 9=9, 10=DOT, 11=ENTER,
12=CLEAR */
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
8=PAGE_DOWN */
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
/* btui_app provides an example of how to leave the decision of rejecting a command or not
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
* If the decision is per player for a particular rc_id, the related bit is clear (not set) */
0x0070, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
12=BACKWARD */
#else
#if (defined BTA_AVRCP_FF_RW_SUPPORT) && (BTA_AVRCP_FF_RW_SUPPORT == TRUE)
0x1b70, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
12=BACKWARD */
#else
0x1870, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
12=BACKWARD */
#endif
#endif
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
0, /* not used */
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
4=F4, 5=F5 */
};
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
const UINT16 bta_av_rc_id_ac[] = {
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
12=FAV_MENU, 13=EXIT */
0, /* not used */
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
4=4, 5=5, 6=6, 7=7,
8=8, 9=9, 10=DOT, 11=ENTER,
12=CLEAR */
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
8=PAGE_DOWN */
/* btui_app provides an example of how to leave the decision of rejecting a command or not
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
* If the decision is per player for a particular rc_id, the related bit is set */
0x1800, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
12=BACKWARD */
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
0, /* not used */
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
4=F4, 5=F5 */
};
UINT16 *p_bta_av_rc_id_ac = (UINT16 *) bta_av_rc_id_ac;
#else
UINT16 *p_bta_av_rc_id_ac = NULL;
#endif
UINT16 *p_bta_av_rc_id = (UINT16 *) bta_av_rc_id;
#endif /* if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */

View File

@ -0,0 +1,97 @@
/******************************************************************************
*
* Copyright (C) 2005-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 is the implementation file for advanced audio/video call-in
* functions.
*
******************************************************************************/
#include "bt_target.h"
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_av_int.h"
#include "bta_av_ci.h"
#include <string.h>
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
/*******************************************************************************
**
** Function bta_av_ci_src_data_ready
**
** Description This function sends an event to the AV indicating that
** the phone has audio stream data ready to send and AV
** should call bta_av_co_audio_src_data_path() or
** bta_av_co_video_src_data_path().
**
** Returns void
**
*******************************************************************************/
void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl)
{
BT_HDR *p_buf;
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
p_buf->layer_specific = chnl;
p_buf->event = BTA_AV_CI_SRC_DATA_READY_EVT;
bta_sys_sendmsg(p_buf);
}
}
/*******************************************************************************
**
** Function bta_av_ci_setconfig
**
** Description This function must be called in response to function
** bta_av_co_audio_setconfig() or bta_av_co_video_setconfig.
** Parameter err_code is set to an AVDTP status value;
** AVDT_SUCCESS if the codec configuration is ok,
** otherwise error.
**
** Returns void
**
*******************************************************************************/
void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code, UINT8 category,
UINT8 num_seid, UINT8 *p_seid, BOOLEAN recfg_needed, UINT8 avdt_handle)
{
tBTA_AV_CI_SETCONFIG *p_buf;
if ((p_buf = (tBTA_AV_CI_SETCONFIG *) GKI_getbuf(sizeof(tBTA_AV_CI_SETCONFIG))) != NULL) {
p_buf->hdr.layer_specific = hndl;
p_buf->hdr.event = (err_code == AVDT_SUCCESS) ?
BTA_AV_CI_SETCONFIG_OK_EVT : BTA_AV_CI_SETCONFIG_FAIL_EVT;
p_buf->err_code = err_code;
p_buf->category = category;
p_buf->recfg_needed = recfg_needed;
p_buf->num_seid = num_seid;
p_buf->avdt_handle = avdt_handle;
if (p_seid && num_seid) {
p_buf->p_seid = (UINT8 *)(p_buf + 1);
memcpy(p_buf->p_seid, p_seid, num_seid);
} else {
p_buf->p_seid = NULL;
p_buf->num_seid = 0;
}
bta_sys_sendmsg(p_buf);
}
}
#endif /* #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */

View File

@ -0,0 +1,704 @@
/******************************************************************************
*
* Copyright (C) 2004-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 is the private interface file for the BTA advanced audio/video.
*
******************************************************************************/
#ifndef BTA_AV_INT_H
#define BTA_AV_INT_H
#include "bta_sys.h"
#include "bta_api.h"
#include "bta_av_api.h"
#include "avdt_api.h"
#include "bta_av_co.h"
#include "list.h"
#define BTA_AV_DEBUG TRUE
/*****************************************************************************
** Constants
*****************************************************************************/
enum {
/* these events are handled by the AV main state machine */
BTA_AV_API_DISABLE_EVT = BTA_SYS_EVT_START(BTA_ID_AV),
BTA_AV_API_REMOTE_CMD_EVT,
BTA_AV_API_VENDOR_CMD_EVT,
BTA_AV_API_VENDOR_RSP_EVT,
BTA_AV_API_META_RSP_EVT,
BTA_AV_API_RC_CLOSE_EVT,
BTA_AV_AVRC_OPEN_EVT,
BTA_AV_AVRC_MSG_EVT,
BTA_AV_AVRC_NONE_EVT,
/* these events are handled by the AV stream state machine */
BTA_AV_API_OPEN_EVT,
BTA_AV_API_CLOSE_EVT,
BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as the *API_*EVT */
BTA_AV_AP_STOP_EVT,
BTA_AV_API_RECONFIG_EVT,
BTA_AV_API_PROTECT_REQ_EVT,
BTA_AV_API_PROTECT_RSP_EVT,
BTA_AV_API_RC_OPEN_EVT,
BTA_AV_SRC_DATA_READY_EVT,
BTA_AV_CI_SETCONFIG_OK_EVT,
BTA_AV_CI_SETCONFIG_FAIL_EVT,
BTA_AV_SDP_DISC_OK_EVT,
BTA_AV_SDP_DISC_FAIL_EVT,
BTA_AV_STR_DISC_OK_EVT,
BTA_AV_STR_DISC_FAIL_EVT,
BTA_AV_STR_GETCAP_OK_EVT,
BTA_AV_STR_GETCAP_FAIL_EVT,
BTA_AV_STR_OPEN_OK_EVT,
BTA_AV_STR_OPEN_FAIL_EVT,
BTA_AV_STR_START_OK_EVT,
BTA_AV_STR_START_FAIL_EVT,
BTA_AV_STR_CLOSE_EVT,
BTA_AV_STR_CONFIG_IND_EVT,
BTA_AV_STR_SECURITY_IND_EVT,
BTA_AV_STR_SECURITY_CFM_EVT,
BTA_AV_STR_WRITE_CFM_EVT,
BTA_AV_STR_SUSPEND_CFM_EVT,
BTA_AV_STR_RECONFIG_CFM_EVT,
BTA_AV_AVRC_TIMER_EVT,
BTA_AV_AVDT_CONNECT_EVT,
BTA_AV_AVDT_DISCONNECT_EVT,
BTA_AV_ROLE_CHANGE_EVT,
BTA_AV_AVDT_DELAY_RPT_EVT,
BTA_AV_ACP_CONNECT_EVT,
/* these events are handled outside of the state machine */
BTA_AV_API_ENABLE_EVT,
BTA_AV_API_REGISTER_EVT,
BTA_AV_API_DEREGISTER_EVT,
BTA_AV_API_DISCONNECT_EVT,
BTA_AV_CI_SRC_DATA_READY_EVT,
BTA_AV_SIG_CHG_EVT,
BTA_AV_SIG_TIMER_EVT,
BTA_AV_SDP_AVRC_DISC_EVT,
BTA_AV_AVRC_CLOSE_EVT,
BTA_AV_CONN_CHG_EVT,
BTA_AV_DEREG_COMP_EVT,
#if (BTA_AV_SINK_INCLUDED == TRUE)
BTA_AV_API_SINK_ENABLE_EVT,
#endif
#if (AVDT_REPORTING == TRUE)
BTA_AV_AVDT_RPT_CONN_EVT,
#endif
BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as the *AP_*EVT */
BTA_AV_API_STOP_EVT
};
/* events for AV control block state machine */
#define BTA_AV_FIRST_SM_EVT BTA_AV_API_DISABLE_EVT
#define BTA_AV_LAST_SM_EVT BTA_AV_AVRC_NONE_EVT
/* events for AV stream control block state machine */
#define BTA_AV_FIRST_SSM_EVT BTA_AV_API_OPEN_EVT
/* events that do not go through state machine */
#define BTA_AV_FIRST_NSM_EVT BTA_AV_API_ENABLE_EVT
#define BTA_AV_LAST_NSM_EVT BTA_AV_API_STOP_EVT
/* API events passed to both SSMs (by bta_av_api_to_ssm) */
#define BTA_AV_FIRST_A2S_API_EVT BTA_AV_API_START_EVT
#define BTA_AV_FIRST_A2S_SSM_EVT BTA_AV_AP_START_EVT
#define BTA_AV_LAST_EVT BTA_AV_API_STOP_EVT
/* maximum number of SEPS in stream discovery results */
#define BTA_AV_NUM_SEPS 32
/* initialization value for AVRC handle */
#define BTA_AV_RC_HANDLE_NONE 0xFF
/* size of database for service discovery */
#define BTA_AV_DISC_BUF_SIZE 1000
/* offset of media type in codec info byte array */
#define BTA_AV_MEDIA_TYPE_IDX 1
/* maximum length of AVDTP security data */
#define BTA_AV_SECURITY_MAX_LEN 400
/* check number of buffers queued at L2CAP when this amount of buffers are queued to L2CAP */
#define BTA_AV_QUEUE_DATA_CHK_NUM L2CAP_HIGH_PRI_MIN_XMIT_QUOTA
/* the number of ACL links with AVDT */
#define BTA_AV_NUM_LINKS AVDT_NUM_LINKS
#define BTA_AV_CO_ID_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
#define BTA_AV_BE_STREAM_TO_CO_ID(u32, p) {u32 = (((UINT32)(*((p) + 2))) + (((UINT32)(*((p) + 1))) << 8) + (((UINT32)(*(p))) << 16)); (p) += 3;}
/* these bits are defined for bta_av_cb.multi_av */
#define BTA_AV_MULTI_AV_SUPPORTED 0x01
#define BTA_AV_MULTI_AV_IN_USE 0x02
/*****************************************************************************
** Data types
*****************************************************************************/
#if 0
/* function types for call-out functions */
typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
UINT8 *p_num_protect, UINT8 *p_protect_info);
typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
UINT8 num_protect, UINT8 *p_protect_info,
UINT8 t_local_sep, UINT8 avdt_handle);
typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl,
tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
UINT16 mtu);
typedef void (*tBTA_AV_CO_CLOSE) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu);
typedef void (*tBTA_AV_CO_START) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
typedef void (*tBTA_AV_CO_STOP) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type,
UINT32 *p_len, UINT32 *p_timestamp);
typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay);
/* the call-out functions for one stream */
typedef struct {
tBTA_AV_CO_INIT init;
tBTA_AV_CO_DISC_RES disc_res;
tBTA_AV_CO_GETCFG getcfg;
tBTA_AV_CO_SETCFG setcfg;
tBTA_AV_CO_OPEN open;
tBTA_AV_CO_CLOSE close;
tBTA_AV_CO_START start;
tBTA_AV_CO_STOP stop;
tBTA_AV_CO_DATAPATH data;
tBTA_AV_CO_DELAY delay;
} tBTA_AV_CO_FUNCTS;
#endif
/* data type for BTA_AV_API_ENABLE_EVT */
typedef struct {
BT_HDR hdr;
tBTA_AV_CBACK *p_cback;
tBTA_AV_FEAT features;
tBTA_SEC sec_mask;
} tBTA_AV_API_ENABLE;
/* data type for BTA_AV_API_REG_EVT */
typedef struct {
BT_HDR hdr;
char p_service_name[BTA_SERVICE_NAME_LEN + 1];
UINT8 app_id;
tBTA_AV_DATA_CBACK *p_app_data_cback;
tBTA_AV_CO_FUNCTS *bta_av_cos;
} tBTA_AV_API_REG;
enum {
BTA_AV_RS_NONE, /* straight API call */
BTA_AV_RS_OK, /* the role switch result - successful */
BTA_AV_RS_FAIL, /* the role switch result - failed */
BTA_AV_RS_DONE /* the role switch is done - continue */
};
typedef UINT8 tBTA_AV_RS_RES;
/* data type for BTA_AV_API_OPEN_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
BOOLEAN use_rc;
tBTA_SEC sec_mask;
tBTA_AV_RS_RES switch_res;
UINT16 uuid; /* uuid of initiator */
} tBTA_AV_API_OPEN;
/* data type for BTA_AV_API_STOP_EVT */
typedef struct {
BT_HDR hdr;
BOOLEAN suspend;
BOOLEAN flush;
} tBTA_AV_API_STOP;
/* data type for BTA_AV_API_DISCONNECT_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
} tBTA_AV_API_DISCNT;
/* data type for BTA_AV_API_PROTECT_REQ_EVT */
typedef struct {
BT_HDR hdr;
UINT8 *p_data;
UINT16 len;
} tBTA_AV_API_PROTECT_REQ;
/* data type for BTA_AV_API_PROTECT_RSP_EVT */
typedef struct {
BT_HDR hdr;
UINT8 *p_data;
UINT16 len;
UINT8 error_code;
} tBTA_AV_API_PROTECT_RSP;
/* data type for BTA_AV_API_REMOTE_CMD_EVT */
typedef struct {
BT_HDR hdr;
tAVRC_MSG_PASS msg;
UINT8 label;
} tBTA_AV_API_REMOTE_CMD;
/* data type for BTA_AV_API_VENDOR_CMD_EVT and RSP */
typedef struct {
BT_HDR hdr;
tAVRC_MSG_VENDOR msg;
UINT8 label;
} tBTA_AV_API_VENDOR;
/* data type for BTA_AV_API_RC_OPEN_EVT */
typedef struct {
BT_HDR hdr;
} tBTA_AV_API_OPEN_RC;
/* data type for BTA_AV_API_RC_CLOSE_EVT */
typedef struct {
BT_HDR hdr;
} tBTA_AV_API_CLOSE_RC;
/* data type for BTA_AV_API_META_RSP_EVT */
typedef struct {
BT_HDR hdr;
BOOLEAN is_rsp;
UINT8 label;
tBTA_AV_CODE rsp_code;
BT_HDR *p_pkt;
} tBTA_AV_API_META_RSP;
/* data type for BTA_AV_API_RECONFIG_EVT */
typedef struct {
BT_HDR hdr;
UINT8 codec_info[AVDT_CODEC_SIZE]; /* codec configuration */
UINT8 *p_protect_info;
UINT8 num_protect;
BOOLEAN suspend;
UINT8 sep_info_idx;
} tBTA_AV_API_RCFG;
/* data type for BTA_AV_CI_SETCONFIG_OK_EVT and BTA_AV_CI_SETCONFIG_FAIL_EVT */
typedef struct {
BT_HDR hdr;
tBTA_AV_HNDL hndl;
UINT8 err_code;
UINT8 category;
UINT8 num_seid;
UINT8 *p_seid;
BOOLEAN recfg_needed;
UINT8 avdt_handle; /* local sep type for which this stream will be set up */
} tBTA_AV_CI_SETCONFIG;
/* data type for all stream events from AVDTP */
typedef struct {
BT_HDR hdr;
tAVDT_CFG cfg; /* configuration/capabilities parameters */
tAVDT_CTRL msg; /* AVDTP callback message parameters */
BD_ADDR bd_addr; /* bd address */
UINT8 handle;
UINT8 avdt_event;
BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */
} tBTA_AV_STR_MSG;
/* data type for BTA_AV_AVRC_MSG_EVT */
typedef struct {
BT_HDR hdr;
tAVRC_MSG msg;
UINT8 handle;
UINT8 label;
UINT8 opcode;
} tBTA_AV_RC_MSG;
/* data type for BTA_AV_AVRC_OPEN_EVT, BTA_AV_AVRC_CLOSE_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR peer_addr;
UINT8 handle;
} tBTA_AV_RC_CONN_CHG;
/* data type for BTA_AV_CONN_CHG_EVT */
typedef struct {
BT_HDR hdr;
BD_ADDR peer_addr;
BOOLEAN is_up;
} tBTA_AV_CONN_CHG;
/* data type for BTA_AV_ROLE_CHANGE_EVT */
typedef struct {
BT_HDR hdr;
UINT8 new_role;
UINT8 hci_status;
} tBTA_AV_ROLE_RES;
/* data type for BTA_AV_SDP_DISC_OK_EVT */
typedef struct {
BT_HDR hdr;
UINT16 avdt_version; /* AVDTP protocol version */
} tBTA_AV_SDP_RES;
/* type for SEP control block */
typedef struct {
UINT8 av_handle; /* AVDTP handle */
tBTA_AV_CODEC codec_type; /* codec type */
UINT8 tsep; /* SEP type of local SEP */
tBTA_AV_DATA_CBACK *p_app_data_cback; /* Application callback for media packets */
} tBTA_AV_SEP;
/* initiator/acceptor role for adaption */
#define BTA_AV_ROLE_AD_INT 0x00 /* initiator */
#define BTA_AV_ROLE_AD_ACP 0x01 /* acceptor */
/* initiator/acceptor signaling roles */
#define BTA_AV_ROLE_START_ACP 0x00
#define BTA_AV_ROLE_START_INT 0x10 /* do not change this value */
#define BTA_AV_ROLE_SUSPEND 0x20 /* suspending on start */
#define BTA_AV_ROLE_SUSPEND_OPT 0x40 /* Suspend on Start option is set */
/* union of all event datatypes */
typedef union {
BT_HDR hdr;
tBTA_AV_API_ENABLE api_enable;
tBTA_AV_API_REG api_reg;
tBTA_AV_API_OPEN api_open;
tBTA_AV_API_STOP api_stop;
tBTA_AV_API_DISCNT api_discnt;
tBTA_AV_API_PROTECT_REQ api_protect_req;
tBTA_AV_API_PROTECT_RSP api_protect_rsp;
tBTA_AV_API_REMOTE_CMD api_remote_cmd;
tBTA_AV_API_VENDOR api_vendor;
tBTA_AV_API_RCFG api_reconfig;
tBTA_AV_CI_SETCONFIG ci_setconfig;
tBTA_AV_STR_MSG str_msg;
tBTA_AV_RC_MSG rc_msg;
tBTA_AV_RC_CONN_CHG rc_conn_chg;
tBTA_AV_CONN_CHG conn_chg;
tBTA_AV_ROLE_RES role_res;
tBTA_AV_SDP_RES sdp_res;
tBTA_AV_API_META_RSP api_meta_rsp;
} tBTA_AV_DATA;
typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb);
typedef struct {
tBTA_AV_VDP_DATA_ACT *p_act;
UINT8 *p_frame;
UINT16 buf_size;
UINT32 len;
UINT32 offset;
UINT32 timestamp;
} tBTA_AV_VF_INFO;
typedef union {
tBTA_AV_VF_INFO vdp; /* used for video channels only */
tBTA_AV_API_OPEN open; /* used only before open and role switch
is needed on another AV channel */
} tBTA_AV_Q_INFO;
#define BTA_AV_Q_TAG_OPEN 0x01 /* after API_OPEN, before STR_OPENED */
#define BTA_AV_Q_TAG_START 0x02 /* before start sending media packets */
#define BTA_AV_Q_TAG_STREAM 0x03 /* during streaming */
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retriving the peer capabilities */
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retriving peer capabilities */
#define BTA_AV_WAIT_ROLE_SW_RES_OPEN 0x04 /* waiting for role switch result after API_OPEN, before STR_OPENED */
#define BTA_AV_WAIT_ROLE_SW_RES_START 0x08 /* waiting for role switch result before streaming */
#define BTA_AV_WAIT_ROLE_SW_STARTED 0x10 /* started while waiting for role switch result */
#define BTA_AV_WAIT_ROLE_SW_RETRY 0x20 /* set when retry on timeout */
#define BTA_AV_WAIT_CHECK_RC 0x40 /* set when the timer is used by role switch */
#define BTA_AV_WAIT_ROLE_SW_FAILED 0x80 /* role switch failed */
#define BTA_AV_WAIT_ROLE_SW_BITS (BTA_AV_WAIT_ROLE_SW_RES_OPEN|BTA_AV_WAIT_ROLE_SW_RES_START|BTA_AV_WAIT_ROLE_SW_STARTED|BTA_AV_WAIT_ROLE_SW_RETRY)
/* Bitmap for collision, coll_mask */
#define BTA_AV_COLL_INC_TMR 0x01 /* Timer is running for incoming L2C connection */
#define BTA_AV_COLL_API_CALLED 0x02 /* API open was called while incoming timer is running */
/* type for AV stream control block */
typedef struct {
const tBTA_AV_ACT *p_act_tbl; /* the action table for stream state machine */
const tBTA_AV_CO_FUNCTS *p_cos; /* the associated callout functions */
tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
tBTA_AV_SEP seps[BTA_AV_MAX_SEPS];
tAVDT_CFG *p_cap; /* buffer used for get capabilities */
list_t *a2d_list; /* used for audio channels only */
tBTA_AV_Q_INFO q_info;
tAVDT_SEP_INFO sep_info[BTA_AV_NUM_SEPS]; /* stream discovery results */
tAVDT_CFG cfg; /* local SEP configuration */
TIMER_LIST_ENT timer; /* delay timer for AVRC CT */
BD_ADDR peer_addr; /* peer BD address */
UINT16 l2c_cid; /* L2CAP channel ID */
UINT16 stream_mtu; /* MTU of stream */
UINT16 avdt_version; /* the avdt version of peer device */
tBTA_SEC sec_mask; /* security mask */
tBTA_AV_CODEC codec_type; /* codec type */
UINT8 media_type; /* Media type */
BOOLEAN cong; /* TRUE if AVDTP congested */
tBTA_AV_STATUS open_status; /* open failure status */
tBTA_AV_CHNL chnl; /* the channel: audio/video */
tBTA_AV_HNDL hndl; /* the handle: ((hdi + 1)|chnl) */
UINT16 cur_psc_mask; /* Protocol service capabilities mask for current connection */
UINT8 avdt_handle; /* AVDTP handle */
UINT8 hdi; /* the index to SCB[] */
UINT8 num_seps; /* number of seps returned by stream discovery */
UINT8 num_disc_snks; /* number of discovered snks */
UINT8 num_disc_srcs; /* number of discovered srcs */
UINT8 sep_info_idx; /* current index into sep_info */
UINT8 sep_idx; /* current index into local seps[] */
UINT8 rcfg_idx; /* reconfig requested index into sep_info */
UINT8 state; /* state machine state */
UINT8 avdt_label; /* AVDTP label */
UINT8 app_id; /* application id */
UINT8 num_recfg; /* number of reconfigure sent */
UINT8 role;
UINT8 l2c_bufs; /* the number of buffers queued to L2CAP */
UINT8 rc_handle; /* connected AVRCP handle */
BOOLEAN use_rc; /* TRUE if AVRCP is allowed */
BOOLEAN started; /* TRUE if stream started */
UINT8 co_started; /* non-zero, if stream started from call-out perspective */
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successfull, else False if command fails */
BOOLEAN suspend_sup; /* TRUE if Suspend stream is supported, else FALSE if suspend command fails */
BOOLEAN deregistring; /* TRUE if deregistering */
BOOLEAN sco_suspend; /* TRUE if SUSPEND is issued automatically for SCO */
UINT8 coll_mask; /* Mask to check incoming and outgoing collision */
tBTA_AV_API_OPEN open_api; /* Saved OPEN api message */
UINT8 wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
UINT8 q_tag; /* identify the associated q_info union member */
BOOLEAN no_rtp_hdr; /* TRUE if add no RTP header*/
UINT8 disc_rsn; /* disconenction reason */
UINT16 uuid_int; /*intended UUID of Initiator to connect to */
} tBTA_AV_SCB;
#define BTA_AV_RC_ROLE_MASK 0x10
#define BTA_AV_RC_ROLE_INT 0x00
#define BTA_AV_RC_ROLE_ACP 0x10
#define BTA_AV_RC_CONN_MASK 0x20
/* type for AV RCP control block */
/* index to this control block is the rc handle */
typedef struct {
UINT8 status;
UINT8 handle;
UINT8 shdl; /* stream handle (hdi + 1) */
UINT8 lidx; /* (index+1) to LCB */
tBTA_AV_FEAT peer_features; /* peer features mask */
} tBTA_AV_RCB;
#define BTA_AV_NUM_RCB (BTA_AV_NUM_STRS + 2)
enum {
BTA_AV_LCB_FREE,
BTA_AV_LCB_FIND
};
/* type for AV ACL Link control block */
typedef struct {
BD_ADDR addr; /* peer BD address */
UINT8 conn_msk; /* handle mask of connected stream handle */
UINT8 lidx; /* index + 1 */
} tBTA_AV_LCB;
/* type for stream state machine action functions */
typedef void (*tBTA_AV_SACT)(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
/* type for AV control block */
typedef struct {
tBTA_AV_SCB *p_scb[BTA_AV_NUM_STRS]; /* stream control block */
tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
tBTA_AV_CBACK *p_cback; /* application callback function */
tBTA_AV_RCB rcb[BTA_AV_NUM_RCB]; /* RCB control block */
tBTA_AV_LCB lcb[BTA_AV_NUM_LINKS + 1]; /* link control block */
TIMER_LIST_ENT sig_tmr; /* link timer */
TIMER_LIST_ENT acp_sig_tmr; /* timer to monitor signalling when accepting */
UINT32 sdp_a2d_handle; /* SDP record handle for audio src */
#if (BTA_AV_SINK_INCLUDED == TRUE)
UINT32 sdp_a2d_snk_handle; /* SDP record handle for audio snk */
#endif
UINT32 sdp_vdp_handle; /* SDP record handle for video src */
tBTA_AV_FEAT features; /* features mask */
tBTA_SEC sec_mask; /* security mask */
tBTA_AV_HNDL handle; /* the handle for SDP activity */
BOOLEAN disabling; /* TRUE if api disabled called */
UINT8 disc; /* (hdi+1) or (rc_handle|BTA_AV_CHNL_MSK) if p_disc_db is in use */
UINT8 state; /* state machine state */
UINT8 conn_rc; /* handle mask of connected RCP channels */
UINT8 conn_audio; /* handle mask of connected audio channels */
UINT8 conn_video; /* handle mask of connected video channels */
UINT8 conn_lcb; /* index mask of used LCBs */
UINT8 audio_open_cnt; /* number of connected audio channels */
UINT8 reg_audio; /* handle mask of registered audio channels */
UINT8 reg_video; /* handle mask of registered video channels */
UINT8 rc_acp_handle;
UINT8 rc_acp_idx; /* (index + 1) to RCB */
UINT8 rs_idx; /* (index + 1) to SCB for the one waiting for RS on open */
BOOLEAN sco_occupied; /* TRUE if SCO is being used or call is in progress */
UINT8 audio_streams; /* handle mask of streaming audio channels */
UINT8 video_streams; /* handle mask of streaming video channels */
} tBTA_AV_CB;
/*****************************************************************************
** Global data
*****************************************************************************/
/* control block declaration */
#if BTA_DYNAMIC_MEMORY == FALSE
extern tBTA_AV_CB bta_av_cb;
#else
extern tBTA_AV_CB *bta_av_cb_ptr;
#define bta_av_cb (*bta_av_cb_ptr)
#endif
/* config struct */
extern tBTA_AV_CFG *p_bta_av_cfg;
/* rc id config struct */
extern UINT16 *p_bta_av_rc_id;
extern UINT16 *p_bta_av_rc_id_ac;
extern const tBTA_AV_SACT bta_av_a2d_action[];
// extern const tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
extern const tBTA_AV_SACT bta_av_vdp_action[];
extern tAVDT_CTRL_CBACK *const bta_av_dt_cback[];
extern void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
/*****************************************************************************
** Function prototypes
*****************************************************************************/
/* utility functions */
extern tBTA_AV_SCB *bta_av_hndl_to_scb(UINT16 handle);
extern BOOLEAN bta_av_chk_start(tBTA_AV_SCB *p_scb);
extern void bta_av_restore_switch (void);
extern UINT16 bta_av_chk_mtu(tBTA_AV_SCB *p_scb, UINT16 mtu);
extern void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
extern UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx);
extern void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started);
extern BOOLEAN bta_av_is_scb_opening (tBTA_AV_SCB *p_scb);
extern BOOLEAN bta_av_is_scb_incoming (tBTA_AV_SCB *p_scb);
extern void bta_av_set_scb_sst_init (tBTA_AV_SCB *p_scb);
extern BOOLEAN bta_av_is_scb_init (tBTA_AV_SCB *p_scb);
extern void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb);
extern tBTA_AV_LCB *bta_av_find_lcb(BD_ADDR addr, UINT8 op);
/* main functions */
extern void bta_av_api_deregister(tBTA_AV_DATA *p_data);
extern void bta_av_dup_audio_buf(tBTA_AV_SCB *p_scb, BT_HDR *p_buf);
extern void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data);
extern void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data);
extern BOOLEAN bta_av_hdl_event(BT_HDR *p_msg);
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
extern char *bta_av_evt_code(UINT16 evt_code);
#endif
extern BOOLEAN bta_av_switch_if_needed(tBTA_AV_SCB *p_scb);
extern BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits);
extern BOOLEAN bta_av_is_rcfg_sst(tBTA_AV_SCB *p_scb);
/* nsm action functions */
extern void bta_av_api_disconnect(tBTA_AV_DATA *p_data);
extern void bta_av_sig_chg(tBTA_AV_DATA *p_data);
extern void bta_av_sig_timer(tBTA_AV_DATA *p_data);
extern void bta_av_rc_disc_done(tBTA_AV_DATA *p_data);
extern void bta_av_rc_closed(tBTA_AV_DATA *p_data);
extern void bta_av_rc_disc(UINT8 disc);
extern void bta_av_conn_chg(tBTA_AV_DATA *p_data);
extern void bta_av_dereg_comp(tBTA_AV_DATA *p_data);
/* sm action functions */
extern void bta_av_disable (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_opened (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_remote_cmd (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_vendor_cmd (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_vendor_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_meta_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_free_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
extern tBTA_AV_RCB *bta_av_get_rcb_by_shdl(UINT8 shdl);
extern void bta_av_del_rc(tBTA_AV_RCB *p_rcb);
/* ssm action functions */
extern void bta_av_do_disc_a2d (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_cleanup (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_free_sdb (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_config_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_disconnect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_security_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_security_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_security_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_security_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_do_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_connect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_sdp_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_disc_res_as_acp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_open_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_discover_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_conn_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_do_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_reconfig (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_data_path (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_start_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_clr_cong (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_str_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_connect (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_discntd (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_suspend_cont (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rcfg_open (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_security_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_open_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_chk_2nd_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_save_caps (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rej_conn (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_rej_conn (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_set_use_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_cco_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_switch_role (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
/* ssm action functions - vdp specific */
extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_vdp_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
extern void bta_av_reg_vdp (tAVDT_CS *p_cs, char *p_service_name, void *p_data);
#endif /* BTA_AV_INT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,614 @@
/******************************************************************************
*
* Copyright (C) 2004-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 module contains utility functions for dealing with SBC data frames
* and codec capabilities.
*
******************************************************************************/
#include "bt_target.h"
#include "a2d_api.h"
#include "a2d_sbc.h"
#include "bta_av_sbc.h"
#include "utl.h"
#include "bt_utils.h"
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
typedef int (tBTA_AV_SBC_ACT)(void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
typedef struct {
INT32 cur_pos; /* current position */
UINT32 src_sps; /* samples per second (source audio data) */
UINT32 dst_sps; /* samples per second (converted audio data) */
tBTA_AV_SBC_ACT *p_act; /* the action function to do the conversion */
UINT16 bits; /* number of bits per pcm sample */
UINT16 n_channels; /* number of channels (i.e. mono(1), stereo(2)...) */
INT16 worker1;
INT16 worker2;
UINT8 div;
} tBTA_AV_SBC_UPS_CB;
tBTA_AV_SBC_UPS_CB bta_av_sbc_ups_cb;
/*******************************************************************************
**
** Function bta_av_sbc_init_up_sample
**
** Description initialize the up sample
**
** src_sps: samples per second (source audio data)
** dst_sps: samples per second (converted audio data)
** bits: number of bits per pcm sample
** n_channels: number of channels (i.e. mono(1), stereo(2)...)
**
** Returns none
**
*******************************************************************************/
void bta_av_sbc_init_up_sample (UINT32 src_sps, UINT32 dst_sps, UINT16 bits, UINT16 n_channels)
{
bta_av_sbc_ups_cb.cur_pos = -1;
bta_av_sbc_ups_cb.src_sps = src_sps;
bta_av_sbc_ups_cb.dst_sps = dst_sps;
bta_av_sbc_ups_cb.bits = bits;
bta_av_sbc_ups_cb.n_channels = n_channels;
if (n_channels == 1) {
/* mono */
if (bits == 8) {
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8m;
bta_av_sbc_ups_cb.div = 1;
} else {
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16m;
bta_av_sbc_ups_cb.div = 2;
}
} else {
/* stereo */
if (bits == 8) {
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8s;
bta_av_sbc_ups_cb.div = 2;
} else {
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16s;
bta_av_sbc_ups_cb.div = 4;
}
}
}
/*******************************************************************************
**
** Function bta_av_sbc_up_sample
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (number of bytes)
** dst_samples: The size of p_dst (number of bytes)
**
** Note: An AE reported an issue with this function.
** When called with bta_av_sbc_up_sample(src, uint8_array_dst..)
** the byte before uint8_array_dst may get overwritten.
** Using uint16_array_dst avoids the problem.
** This issue is related to endian-ness and is hard to resolve
** in a generic manner.
** **************** Please use uint16 array as dst.
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
int bta_av_sbc_up_sample (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret)
{
UINT32 src;
UINT32 dst;
if (bta_av_sbc_ups_cb.p_act) {
src = src_samples / bta_av_sbc_ups_cb.div;
dst = dst_samples / bta_av_sbc_ups_cb.div;
return (*bta_av_sbc_ups_cb.p_act)(p_src, p_dst, src, dst, p_ret);
} else {
*p_ret = 0;
return 0;
}
}
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_16s (16bits-stereo)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 4 bytes)
** dst_samples: The size of p_dst (in uint of 4 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
int bta_av_sbc_up_sample_16s (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret)
{
INT16 *p_src_tmp = (INT16 *)p_src;
INT16 *p_dst_tmp = (INT16 *)p_dst;
INT16 *p_worker1 = &bta_av_sbc_ups_cb.worker1;
INT16 *p_worker2 = &bta_av_sbc_ups_cb.worker2;
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
*p_dst_tmp++ = *p_worker1;
*p_dst_tmp++ = *p_worker2;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
}
bta_av_sbc_ups_cb.cur_pos = dst_sps;
while (src_samples-- && dst_samples) {
*p_worker1 = *p_src_tmp++;
*p_worker2 = *p_src_tmp++;
do {
*p_dst_tmp++ = *p_worker1;
*p_dst_tmp++ = *p_worker2;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
bta_av_sbc_ups_cb.cur_pos += dst_sps;
}
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
bta_av_sbc_ups_cb.cur_pos = 0;
}
*p_ret = ((char *)p_src_tmp - (char *)p_src);
return ((char *)p_dst_tmp - (char *)p_dst);
}
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_16m (16bits-mono)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 2 bytes)
** dst_samples: The size of p_dst (in uint of 2 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
int bta_av_sbc_up_sample_16m (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret)
{
INT16 *p_src_tmp = (INT16 *)p_src;
INT16 *p_dst_tmp = (INT16 *)p_dst;
INT16 *p_worker = &bta_av_sbc_ups_cb.worker1;
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
*p_dst_tmp++ = *p_worker;
*p_dst_tmp++ = *p_worker;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
dst_samples--;
}
bta_av_sbc_ups_cb.cur_pos = dst_sps;
while (src_samples-- && dst_samples) {
*p_worker = *p_src_tmp++;
do {
*p_dst_tmp++ = *p_worker;
*p_dst_tmp++ = *p_worker;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
dst_samples--;
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
bta_av_sbc_ups_cb.cur_pos += dst_sps;
}
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
bta_av_sbc_ups_cb.cur_pos = 0;
}
*p_ret = ((char *)p_src_tmp - (char *)p_src);
return ((char *)p_dst_tmp - (char *)p_dst);
}
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_8s (8bits-stereo)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 2 bytes)
** dst_samples: The size of p_dst (in uint of 2 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
int bta_av_sbc_up_sample_8s (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret)
{
UINT8 *p_src_tmp = (UINT8 *)p_src;
INT16 *p_dst_tmp = (INT16 *)p_dst;
INT16 *p_worker1 = &bta_av_sbc_ups_cb.worker1;
INT16 *p_worker2 = &bta_av_sbc_ups_cb.worker2;
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
*p_dst_tmp++ = *p_worker1;
*p_dst_tmp++ = *p_worker2;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
dst_samples--;
}
bta_av_sbc_ups_cb.cur_pos = dst_sps;
while (src_samples -- && dst_samples) {
*p_worker1 = *(UINT8 *)p_src_tmp++;
*p_worker1 -= 0x80;
*p_worker1 <<= 8;
*p_worker2 = *(UINT8 *)p_src_tmp++;
*p_worker2 -= 0x80;
*p_worker2 <<= 8;
do {
*p_dst_tmp++ = *p_worker1;
*p_dst_tmp++ = *p_worker2;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples--;
dst_samples--;
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
bta_av_sbc_ups_cb.cur_pos += dst_sps;
}
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
bta_av_sbc_ups_cb.cur_pos = 0;
}
*p_ret = ((char *)p_src_tmp - (char *)p_src);
return ((char *)p_dst_tmp - (char *)p_dst);
}
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_8m (8bits-mono)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (number of bytes)
** dst_samples: The size of p_dst (number of bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
int bta_av_sbc_up_sample_8m (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret)
{
UINT8 *p_src_tmp = (UINT8 *)p_src;
INT16 *p_dst_tmp = (INT16 *)p_dst;
INT16 *p_worker = &bta_av_sbc_ups_cb.worker1;
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
*p_dst_tmp++ = *p_worker;
*p_dst_tmp++ = *p_worker;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples -= 4;
}
bta_av_sbc_ups_cb.cur_pos = dst_sps;
while (src_samples-- && dst_samples) {
*p_worker = *(UINT8 *)p_src_tmp++;
*p_worker -= 0x80;
*p_worker <<= 8;
do {
*p_dst_tmp++ = *p_worker;
*p_dst_tmp++ = *p_worker;
bta_av_sbc_ups_cb.cur_pos -= src_sps;
dst_samples -= 4;
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
bta_av_sbc_ups_cb.cur_pos += dst_sps;
}
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
bta_av_sbc_ups_cb.cur_pos = 0;
}
*p_ret = ((char *)p_src_tmp - (char *)p_src);
return ((char *)p_dst_tmp - (char *)p_dst);
}
/*******************************************************************************
**
** Function bta_av_sbc_cfg_for_cap
**
** Description Determine the preferred SBC codec configuration for the
** given codec capabilities. The function is passed the
** preferred codec configuration and the peer codec
** capabilities for the stream. The function attempts to
** match the preferred capabilities with the configuration
** as best it can. The resulting codec configuration is
** returned in the same memory used for the capabilities.
**
** Returns 0 if ok, nonzero if error.
** Codec configuration in p_cap.
**
*******************************************************************************/
UINT8 bta_av_sbc_cfg_for_cap(UINT8 *p_peer, tA2D_SBC_CIE *p_cap, tA2D_SBC_CIE *p_pref)
{
UINT8 status = A2D_SUCCESS;
tA2D_SBC_CIE peer_cie;
UNUSED(p_cap);
/* parse peer capabilities */
if ((status = A2D_ParsSbcInfo(&peer_cie, p_peer, TRUE)) != 0) {
return status;
}
/* Check if the peer supports our channel mode */
if (peer_cie.ch_mode & p_pref->ch_mode) {
peer_cie.ch_mode = p_pref->ch_mode;
} else {
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: ch_mode(0x%02X) not supported", p_pref->ch_mode);
return A2D_FAIL;
}
/* Check if the peer supports our sampling freq */
if (peer_cie.samp_freq & p_pref->samp_freq) {
peer_cie.samp_freq = p_pref->samp_freq;
} else {
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: samp_freq(0x%02X) not supported", p_pref->samp_freq);
return A2D_FAIL;
}
/* Check if the peer supports our block len */
if (peer_cie.block_len & p_pref->block_len) {
peer_cie.block_len = p_pref->block_len;
} else {
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: block_len(0x%02X) not supported", p_pref->block_len);
return A2D_FAIL;
}
/* Check if the peer supports our num subbands */
if (peer_cie.num_subbands & p_pref->num_subbands) {
peer_cie.num_subbands = p_pref->num_subbands;
} else {
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: num_subbands(0x%02X) not supported", p_pref->num_subbands);
return A2D_FAIL;
}
/* Check if the peer supports our alloc method */
if (peer_cie.alloc_mthd & p_pref->alloc_mthd) {
peer_cie.alloc_mthd = p_pref->alloc_mthd;
} else {
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: alloc_mthd(0x%02X) not supported", p_pref->alloc_mthd);
return A2D_FAIL;
}
/* max bitpool */
if (p_pref->max_bitpool != 0 && p_pref->max_bitpool < peer_cie.max_bitpool) {
peer_cie.max_bitpool = p_pref->max_bitpool;
}
/* min bitpool */
if (p_pref->min_bitpool != 0 && p_pref->min_bitpool > peer_cie.min_bitpool) {
peer_cie.min_bitpool = p_pref->min_bitpool;
}
if (status == A2D_SUCCESS) {
/* build configuration */
A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &peer_cie, p_peer);
}
return status;
}
/*******************************************************************************
**
** Function bta_av_sbc_cfg_matches_cap
**
** Description This function checks whether an SBC codec configuration
** matched with capabilities. Here we check subset.
**
** Returns 0 if ok, nonzero if error.
**
*******************************************************************************/
UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
{
UINT8 status = 0;
tA2D_SBC_CIE cfg_cie;
/* parse configuration */
if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, TRUE)) != 0) {
APPL_TRACE_ERROR(" bta_av_sbc_cfg_matches_cap Parsing Failed %d", status);
return status;
}
/* verify that each parameter is in range */
APPL_TRACE_DEBUG(" FREQ peer: 0%x, capability 0%x", cfg_cie.samp_freq, p_cap->samp_freq);
APPL_TRACE_DEBUG(" CH_MODE peer: 0%x, capability 0%x", cfg_cie.ch_mode, p_cap->ch_mode);
APPL_TRACE_DEBUG(" BLOCK_LEN peer: 0%x, capability 0%x", cfg_cie.block_len, p_cap->block_len);
APPL_TRACE_DEBUG(" SUB_BAND peer: 0%x, capability 0%x", cfg_cie.num_subbands, p_cap->num_subbands);
APPL_TRACE_DEBUG(" ALLOC_MTHD peer: 0%x, capability 0%x", cfg_cie.alloc_mthd, p_cap->alloc_mthd);
APPL_TRACE_DEBUG(" MAX_BitPool peer: 0%x, capability 0%x", cfg_cie.max_bitpool, p_cap->max_bitpool);
APPL_TRACE_DEBUG(" Min_bitpool peer: 0%x, capability 0%x", cfg_cie.min_bitpool, p_cap->min_bitpool);
/* sampling frequency */
if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
status = A2D_NS_SAMP_FREQ;
}
/* channel mode */
else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
status = A2D_NS_CH_MODE;
}
/* block length */
else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
status = A2D_BAD_BLOCK_LEN;
}
/* subbands */
else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
status = A2D_NS_SUBBANDS;
}
/* allocation method */
else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
status = A2D_NS_ALLOC_MTHD;
}
/* max bitpool */
else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
status = A2D_NS_MAX_BITPOOL;
}
/* min bitpool */
else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
status = A2D_NS_MIN_BITPOOL;
}
return status;
}
/*******************************************************************************
**
** Function bta_av_sbc_cfg_in_cap
**
** Description This function checks whether an SBC codec configuration
** is allowable for the given codec capabilities.
**
** Returns 0 if ok, nonzero if error.
**
*******************************************************************************/
UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
{
UINT8 status = 0;
tA2D_SBC_CIE cfg_cie;
/* parse configuration */
if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, FALSE)) != 0) {
return status;
}
/* verify that each parameter is in range */
/* sampling frequency */
if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
status = A2D_NS_SAMP_FREQ;
}
/* channel mode */
else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
status = A2D_NS_CH_MODE;
}
/* block length */
else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
status = A2D_BAD_BLOCK_LEN;
}
/* subbands */
else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
status = A2D_NS_SUBBANDS;
}
/* allocation method */
else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
status = A2D_NS_ALLOC_MTHD;
}
/* max bitpool */
else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
status = A2D_NS_MAX_BITPOOL;
}
/* min bitpool */
else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
status = A2D_NS_MIN_BITPOOL;
}
return status;
}
/*******************************************************************************
**
** Function bta_av_sbc_bld_hdr
**
** Description This function builds the packet header for MPF1.
**
** Returns void
**
*******************************************************************************/
void bta_av_sbc_bld_hdr(BT_HDR *p_buf, UINT16 fr_per_pkt)
{
UINT8 *p;
p_buf->offset -= BTA_AV_SBC_HDR_SIZE;
p = (UINT8 *) (p_buf + 1) + p_buf->offset;
p_buf->len += BTA_AV_SBC_HDR_SIZE;
A2D_BldSbcMplHdr(p, FALSE, FALSE, FALSE, (UINT8) fr_per_pkt);
}
#endif /* #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */

View File

@ -0,0 +1,580 @@
/******************************************************************************
*
* Copyright (C) 2004-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 is the stream state machine for the BTA advanced audio/video.
*
******************************************************************************/
#include "bt_target.h"
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
#include <string.h>
#include "bta_av_co.h"
#include "bta_av_int.h"
/*****************************************************************************
** Constants and types
*****************************************************************************/
/* state machine states */
enum {
BTA_AV_INIT_SST,
BTA_AV_INCOMING_SST,
BTA_AV_OPENING_SST,
BTA_AV_OPEN_SST,
BTA_AV_RCFG_SST,
BTA_AV_CLOSING_SST
};
/* state machine action enumeration list */
enum {
BTA_AV_DO_DISC,
BTA_AV_CLEANUP,
BTA_AV_FREE_SDB,
BTA_AV_CONFIG_IND,
BTA_AV_DISCONNECT_REQ,
BTA_AV_SECURITY_REQ,
BTA_AV_SECURITY_RSP,
BTA_AV_SETCONFIG_RSP,
BTA_AV_ST_RC_TIMER,
BTA_AV_STR_OPENED,
BTA_AV_SECURITY_IND,
BTA_AV_SECURITY_CFM,
BTA_AV_DO_CLOSE,
BTA_AV_CONNECT_REQ,
BTA_AV_SDP_FAILED,
BTA_AV_DISC_RESULTS,
BTA_AV_DISC_RES_AS_ACP,
BTA_AV_OPEN_FAILED,
BTA_AV_GETCAP_RESULTS,
BTA_AV_SETCONFIG_REJ,
BTA_AV_DISCOVER_REQ,
BTA_AV_CONN_FAILED,
BTA_AV_DO_START,
BTA_AV_STR_STOPPED,
BTA_AV_RECONFIG,
BTA_AV_DATA_PATH,
BTA_AV_START_OK,
BTA_AV_START_FAILED,
BTA_AV_STR_CLOSED,
BTA_AV_CLR_CONG,
BTA_AV_SUSPEND_CFM,
BTA_AV_RCFG_STR_OK,
BTA_AV_RCFG_FAILED,
BTA_AV_RCFG_CONNECT,
BTA_AV_RCFG_DISCNTD,
BTA_AV_SUSPEND_CONT,
BTA_AV_RCFG_CFM,
BTA_AV_RCFG_OPEN,
BTA_AV_SECURITY_REJ,
BTA_AV_OPEN_RC,
BTA_AV_CHK_2ND_START,
BTA_AV_SAVE_CAPS,
BTA_AV_SET_USE_RC,
BTA_AV_CCO_CLOSE,
BTA_AV_SWITCH_ROLE,
BTA_AV_ROLE_RES,
BTA_AV_DELAY_CO,
BTA_AV_OPEN_AT_INC,
BTA_AV_NUM_SACTIONS
};
#define BTA_AV_SIGNORE BTA_AV_NUM_SACTIONS
/* state table information */
/* #define BTA_AV_SACTION_COL 0 position of actions */
#define BTA_AV_SACTIONS 2 /* number of actions */
#define BTA_AV_SNEXT_STATE 2 /* position of next state */
#define BTA_AV_NUM_COLS 3 /* number of columns in state tables */
/* state table for init state */
static const UINT8 bta_av_sst_init[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_DO_DISC, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AP_CLOSE_EVT */ {BTA_AV_CLEANUP, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_CLOSE_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }
};
/* state table for incoming state */
static const UINT8 bta_av_sst_incoming[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_OPEN_AT_INC, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AP_CLOSE_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_DISCONNECT_REQ, BTA_AV_CLOSING_SST },
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SETCONFIG_RSP, BTA_AV_ST_RC_TIMER, BTA_AV_INCOMING_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RES_AS_ACP, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_SAVE_CAPS, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_STR_OPENED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_CLOSE_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_CONFIG_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }
};
/* state table for opening state */
static const UINT8 bta_av_sst_opening[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_CONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_CONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RESULTS, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_GETCAP_RESULTS, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_ST_RC_TIMER, BTA_AV_STR_OPENED, BTA_AV_OPEN_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_CLOSE_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_CONFIG_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_SWITCH_ROLE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_DISCOVER_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_CONN_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_ROLE_RES, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }
};
/* state table for open state */
static const UINT8 bta_av_sst_open[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_START_EVT */ {BTA_AV_DO_START, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* AP_STOP_EVT */ {BTA_AV_STR_STOPPED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* API_RECONFIG_EVT */ {BTA_AV_RECONFIG, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SET_USE_RC, BTA_AV_OPEN_RC, BTA_AV_OPEN_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_DATA_PATH, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_SAVE_CAPS, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_START_OK_EVT */ {BTA_AV_START_OK, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_START_FAILED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_CLOSE_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_CLR_CONG, BTA_AV_DATA_PATH, BTA_AV_OPEN_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SUSPEND_CFM, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_OPEN_RC, BTA_AV_CHK_2ND_START, BTA_AV_OPEN_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_ROLE_RES, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }
};
/* state table for reconfig state */
static const UINT8 bta_av_sst_rcfg[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RESULTS, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_GETCAP_RESULTS, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_RCFG_STR_OK, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_RCFG_FAILED, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_CLOSE_EVT */ {BTA_AV_RCFG_CONNECT, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SUSPEND_CONT, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_RCFG_CFM, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_RCFG_OPEN, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_RCFG_DISCNTD, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }
};
/* state table for closing state */
static const UINT8 bta_av_sst_closing[][BTA_AV_NUM_COLS] = {
/* Event Action 1 Action 2 Next state */
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* SDP_DISC_OK_EVT */ {BTA_AV_SDP_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* SDP_DISC_FAIL_EVT */ {BTA_AV_SDP_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_GETCAP_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_OPEN_OK_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_OPEN_FAIL_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_REJ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AVDT_DISCONNECT_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }
};
/* type for state table */
typedef const UINT8 (*tBTA_AV_SST_TBL)[BTA_AV_NUM_COLS];
/* state table */
static const tBTA_AV_SST_TBL bta_av_sst_tbl[] = {
bta_av_sst_init,
bta_av_sst_incoming,
bta_av_sst_opening,
bta_av_sst_open,
bta_av_sst_rcfg,
bta_av_sst_closing
};
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
static char *bta_av_sst_code(UINT8 state);
#endif
/*******************************************************************************
**
** Function bta_av_is_rcfg_sst
**
** Description Check if stream state machine is in reconfig state.
**
**
** Returns TRUE if stream state machine is in reconfig state.
**
*******************************************************************************/
BOOLEAN bta_av_is_rcfg_sst (tBTA_AV_SCB *p_scb)
{
BOOLEAN is_rcfg_sst = FALSE;
if (p_scb != NULL) {
if (p_scb->state == BTA_AV_RCFG_SST) {
is_rcfg_sst = TRUE;
}
}
return is_rcfg_sst;
}
/*******************************************************************************
**
** Function bta_av_ssm_execute
**
** Description Stream state machine event handling function for AV
**
**
** Returns void
**
*******************************************************************************/
void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data)
{
tBTA_AV_SST_TBL state_table;
UINT8 action;
int i, xx;
if (p_scb == NULL) {
/* this stream is not registered */
APPL_TRACE_EVENT("AV channel not registered");
return;
}
/* In case incoming connection is for VDP, we need to swap scb. */
/* When ACP_CONNECT_EVT was received, we put first available scb to */
/* to Incoming state. Later, when STR_CONFIG_IND_EVT is coming, we */
/* know if it is A2DP or VDP. */
if ((p_scb->state == BTA_AV_INIT_SST) && (event == BTA_AV_STR_CONFIG_IND_EVT)) {
for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
if (bta_av_cb.p_scb[xx]) {
if (bta_av_cb.p_scb[xx]->state == BTA_AV_INCOMING_SST) {
bta_av_cb.p_scb[xx]->state = BTA_AV_INIT_SST;
bta_av_cb.p_scb[xx]->coll_mask = 0;
p_scb->state = BTA_AV_INCOMING_SST;
break;
}
}
}
}
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
APPL_TRACE_VERBOSE("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
p_scb->hndl, event, bta_av_evt_code(event), p_scb->state, bta_av_sst_code(p_scb->state));
#else
APPL_TRACE_VERBOSE("AV Sevent=0x%x state=%d", event, p_scb->state);
#endif
/* look up the state table for the current state */
state_table = bta_av_sst_tbl[p_scb->state];
event -= BTA_AV_FIRST_SSM_EVT;
/* set next state */
p_scb->state = state_table[event][BTA_AV_SNEXT_STATE];
/* execute action functions */
for (i = 0; i < BTA_AV_SACTIONS; i++) {
if ((action = state_table[event][i]) != BTA_AV_SIGNORE) {
(*p_scb->p_act_tbl[action])(p_scb, p_data);
} else {
break;
}
}
}
/*******************************************************************************
**
** Function bta_av_is_scb_opening
**
** Description Returns TRUE is scb is in opening state.
**
**
** Returns TRUE if scb is in opening state.
**
*******************************************************************************/
BOOLEAN bta_av_is_scb_opening (tBTA_AV_SCB *p_scb)
{
BOOLEAN is_opening = FALSE;
if (p_scb) {
if (p_scb->state == BTA_AV_OPENING_SST) {
is_opening = TRUE;
}
}
return is_opening;
}
/*******************************************************************************
**
** Function bta_av_is_scb_incoming
**
** Description Returns TRUE is scb is in incoming state.
**
**
** Returns TRUE if scb is in incoming state.
**
*******************************************************************************/
BOOLEAN bta_av_is_scb_incoming (tBTA_AV_SCB *p_scb)
{
BOOLEAN is_incoming = FALSE;
if (p_scb) {
if (p_scb->state == BTA_AV_INCOMING_SST) {
is_incoming = TRUE;
}
}
return is_incoming;
}
/*******************************************************************************
**
** Function bta_av_set_scb_sst_init
**
** Description Set SST state to INIT.
** Use this function to change SST outside of state machine.
**
** Returns None
**
*******************************************************************************/
void bta_av_set_scb_sst_init (tBTA_AV_SCB *p_scb)
{
if (p_scb) {
p_scb->state = BTA_AV_INIT_SST;
}
}
/*******************************************************************************
**
** Function bta_av_is_scb_init
**
** Description Returns TRUE is scb is in init state.
**
**
** Returns TRUE if scb is in incoming state.
**
*******************************************************************************/
BOOLEAN bta_av_is_scb_init (tBTA_AV_SCB *p_scb)
{
BOOLEAN is_init = FALSE;
if (p_scb) {
if (p_scb->state == BTA_AV_INIT_SST) {
is_init = TRUE;
}
}
return is_init;
}
/*******************************************************************************
**
** Function bta_av_set_scb_sst_incoming
**
** Description Set SST state to incoming.
** Use this function to change SST outside of state machine.
**
** Returns None
**
*******************************************************************************/
void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb)
{
if (p_scb) {
p_scb->state = BTA_AV_INCOMING_SST;
}
}
/*****************************************************************************
** Debug Functions
*****************************************************************************/
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
/*******************************************************************************
**
** Function bta_av_sst_code
**
** Description
**
** Returns char *
**
*******************************************************************************/
static char *bta_av_sst_code(UINT8 state)
{
switch (state) {
case BTA_AV_INIT_SST: return "INIT";
case BTA_AV_INCOMING_SST: return "INCOMING";
case BTA_AV_OPENING_SST: return "OPENING";
case BTA_AV_OPEN_SST: return "OPEN";
case BTA_AV_RCFG_SST: return "RCFG";
case BTA_AV_CLOSING_SST: return "CLOSING";
default: return "unknown";
}
}
#endif
#endif /* BTA_AV_INCLUDED */

View File

@ -65,7 +65,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
/* Extended Inquiry Response */
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
static void bta_dm_set_eir (char *local_name);
@ -2714,6 +2716,7 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
return BTM_SUCCESS;
}
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
/*******************************************************************************
**
** Function bta_dm_sp_cback
@ -2868,6 +2871,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
APPL_TRACE_EVENT("dm status: %d", status);
return status;
}
#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
/*******************************************************************************
**
@ -4108,7 +4112,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
switch (event) {
case BTM_LE_IO_REQ_EVT:
#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
// #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
bta_dm_co_ble_io_req(bda,
&p_data->io_req.io_cap,
@ -4117,7 +4121,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
&p_data->io_req.max_key_size,
&p_data->io_req.init_keys,
&p_data->io_req.resp_keys);
#endif
// #endif
#if BTM_OOB_INCLUDED == FALSE
status = BTM_SUCCESS;
#endif

View File

@ -152,6 +152,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1]
#endif
};
#define BTA_DM_PM_SPEC_TO_OFFSET (197) /* timeout offset to avoid conflict with other bluedroid host */
tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
/* AG : 0 */
{
@ -160,15 +161,15 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
{{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
{{BTA_DM_PM_RETRY, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
},
@ -179,15 +180,15 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open park */
{{BTA_DM_PM_PARK, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open park */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close park */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
{{BTA_DM_PM_PARK, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close park */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
{{BTA_DM_PM_RETRY, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
},
@ -198,13 +199,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
{{BTA_DM_PM_SNIFF, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF, 1000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF, 1000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -217,13 +218,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR3), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -236,13 +237,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -255,14 +256,14 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR1), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
},
@ -280,7 +281,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -299,7 +300,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -312,7 +313,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
@ -337,7 +338,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -356,7 +357,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
@ -370,15 +371,15 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_SNIFF3, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF3, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
{{BTA_DM_PM_RETRY, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
},
@ -389,13 +390,13 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_SNIFF, 3000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF4, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF4, 3000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
@ -409,18 +410,18 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
(BTA_DM_PM_SSR2), /* the SSR entry */
#endif
{
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
#endif
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
{{BTA_DM_PM_RETRY, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
}
/* GATTS : 14 */
@ -441,7 +442,7 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
#endif
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
{{BTA_DM_PM_RETRY, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
}
}

View File

@ -0,0 +1,140 @@
/******************************************************************************
*
* Copyright (C) 2004-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 is the public interface file for the simulatenous advanced
* audio/video streaming (AV) source and sink of BTA, Broadcom's Bluetooth
* application layer for mobile phones.
*
******************************************************************************/
#ifndef BTA_AR_API_H
#define BTA_AR_API_H
#include "avdt_api.h"
#include "avct_api.h"
#include "avrc_api.h"
#include "sdp_api.h"
#include "bta_av_api.h"
#include "bta_sys.h"
/*****************************************************************************
** Constants and data types
*****************************************************************************/
/* This event signal to AR user that other profile is connected */
#define BTA_AR_AVDT_CONN_EVT (AVDT_MAX_EVT + 1)
/*******************************************************************************
**
** Function bta_ar_init
**
** Description This function is called from bta_sys_init().
** to initialize the control block
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_init(void);
/*******************************************************************************
**
** Function bta_ar_reg_avdt
**
** Description This function is called to register to AVDTP.
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id);
/*******************************************************************************
**
** Function bta_ar_dereg_avdt
**
** Description This function is called to de-register from AVDTP.
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id);
/*******************************************************************************
**
** Function bta_ar_avdt_conn
**
** Description This function is called to let ar know that some AVDTP profile
** is connected for this sys_id.
** If the other sys modules started a timer for PENDING_EVT,
** the timer can be stopped now.
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr);
/*******************************************************************************
**
** Function bta_ar_reg_avct
**
** Description This function is called to register to AVCTP.
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id);
/*******************************************************************************
**
** Function bta_ar_dereg_avct
**
** Description This function is called to deregister from AVCTP.
**
** Returns void
**
*******************************************************************************/
extern void bta_ar_dereg_avct(tBTA_SYS_ID sys_id);
/******************************************************************************
**
** Function bta_ar_reg_avrc
**
** Description This function is called to register an SDP record for AVRCP.
**
** Returns void
**
******************************************************************************/
extern void bta_ar_reg_avrc(UINT16 service_uuid, char *p_service_name,
char *p_provider_name, UINT16 categories, tBTA_SYS_ID sys_id);
/******************************************************************************
**
** Function bta_ar_dereg_avrc
**
** Description This function is called to de-register/delete an SDP record for AVRCP.
**
** Returns void
**
******************************************************************************/
extern void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id);
#ifdef __cplusplus
}
#endif
#endif /* BTA_AR_API_H */

View File

@ -0,0 +1,808 @@
/******************************************************************************
*
* Copyright (C) 2004-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 is the public interface file for the advanced audio/video streaming
* (AV) subsystem of BTA, Broadcom's Bluetooth application layer for mobile
* phones.
*
******************************************************************************/
#ifndef BTA_AV_API_H
#define BTA_AV_API_H
#include "avrc_api.h"
#include "avdt_api.h"
#include "a2d_api.h"
#include "bta_api.h"
/*****************************************************************************
** Constants and data types
*****************************************************************************/
/* Set to TRUE if seperate authorization prompt desired for AVCTP besides A2DP authorization */
/* Typically FALSE when AVRCP is used in conjunction with A2DP */
#ifndef BTA_AV_WITH_AVCTP_AUTHORIZATION
#define BTA_AV_WITH_AVCTP_AUTHORIZATION FALSE
#endif
/* AV status values */
#define BTA_AV_SUCCESS 0 /* successful operation */
#define BTA_AV_FAIL 1 /* generic failure */
#define BTA_AV_FAIL_SDP 2 /* service not found */
#define BTA_AV_FAIL_STREAM 3 /* stream connection failed */
#define BTA_AV_FAIL_RESOURCES 4 /* no resources */
#define BTA_AV_FAIL_ROLE 5 /* failed due to role management related issues */
#define BTA_AV_FAIL_GET_CAP 6 /* get capability failed due to no SEP availale on the peer */
typedef UINT8 tBTA_AV_STATUS;
/* AV features masks */
#define BTA_AV_FEAT_RCTG 0x0001 /* remote control target */
#define BTA_AV_FEAT_RCCT 0x0002 /* remote control controller */
#define BTA_AV_FEAT_PROTECT 0x0004 /* streaming media contect protection */
#define BTA_AV_FEAT_VENDOR 0x0008 /* remote control vendor dependent commands */
#define BTA_AV_FEAT_REPORT 0x0020 /* use reporting service for VDP */
#define BTA_AV_FEAT_METADATA 0x0040 /* remote control Metadata Transfer command/response */
#define BTA_AV_FEAT_MULTI_AV 0x0080 /* use multi-av, if controller supports it */
#define BTA_AV_FEAT_BROWSE 0x0010 /* use browsing channel */
#define BTA_AV_FEAT_MASTER 0x0100 /* stream only as master role */
#define BTA_AV_FEAT_ADV_CTRL 0x0200 /* remote control Advanced Control command/response */
#define BTA_AV_FEAT_DELAY_RPT 0x0400 /* allow delay reporting */
#define BTA_AV_FEAT_ACP_START 0x0800 /* start stream when 2nd SNK was accepted */
/* Internal features */
#define BTA_AV_FEAT_NO_SCO_SSPD 0x8000 /* Do not suspend av streaming as to AG events(SCO or Call) */
typedef UINT16 tBTA_AV_FEAT;
/* AV channel values */
#define BTA_AV_CHNL_MSK 0xC0
#define BTA_AV_CHNL_AUDIO 0x40 /* audio channel */
#define BTA_AV_CHNL_VIDEO 0x80 /* video channel */
typedef UINT8 tBTA_AV_CHNL;
#define BTA_AV_HNDL_MSK 0x3F
typedef UINT8 tBTA_AV_HNDL;
/* handle index to mask */
#define BTA_AV_HNDL_TO_MSK(h) ((UINT8)(1 << (h)))
/* tBTA_AV_HNDL to mask */
#define BTA_AV_HNDL_TYPE_TO_MSK(h) ((UINT8)(1 << (h&BTA_AV_HNDL_MSK)))
/* offset of codec type in codec info byte array */
#define BTA_AV_CODEC_TYPE_IDX AVDT_CODEC_TYPE_INDEX /* 2 */
/* maximum number of streams created: 1 for audio, 1 for video */
#ifndef BTA_AV_NUM_STRS
#define BTA_AV_NUM_STRS 2
#endif
#ifndef BTA_AV_MAX_SEPS
#define BTA_AV_MAX_SEPS 2
#endif
#ifndef BTA_AV_MAX_A2DP_MTU
/*#define BTA_AV_MAX_A2DP_MTU 668 //224 (DM5) * 3 - 4(L2CAP header) */
#define BTA_AV_MAX_A2DP_MTU 1008
#endif
#ifndef BTA_AV_MAX_VDP_MTU
#define BTA_AV_MAX_VDP_MTU 1008
#endif
/* codec type */
#define BTA_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */
#define BTA_AV_CODEC_M12 A2D_MEDIA_CT_M12 /* MPEG-1, 2 Audio media codec type */
#define BTA_AV_CODEC_M24 A2D_MEDIA_CT_M24 /* MPEG-2, 4 AAC media codec type */
#define BTA_AV_CODEC_ATRAC A2D_MEDIA_CT_ATRAC /* ATRAC family media codec type */
#define BTA_AV_CODEC_H263_P0 VDP_MEDIA_CT_H263_P0 /* H.263 baseline (profile 0) */
#define BTA_AV_CODEC_MPEG4 VDP_MEDIA_CT_MPEG4 /* MPEG-4 Visual Simple Profile */
#define BTA_AV_CODEC_H263_P3 VDP_MEDIA_CT_H263_P3 /* H.263 profile 3 */
#define BTA_AV_CODEC_H263_P8 VDP_MEDIA_CT_H263_P8 /* H.263 profile 8 */
#define BTA_AV_CODEC_VEND VDP_MEDIA_CT_VEND /* Non-VDP */
typedef UINT8 tBTA_AV_CODEC;
/* Company ID in BT assigned numbers */
#define BTA_AV_BT_VENDOR_ID VDP_BT_VENDOR_ID /* Broadcom Corporation */
/* vendor specific codec ID */
#define BTA_AV_CODEC_ID_H264 VDP_CODEC_ID_H264 /* Non-VDP codec ID - H.264 */
#define BTA_AV_CODEC_ID_IMG VDP_CODEC_ID_IMG /* Non-VDP codec ID - images/slideshow */
/* operation id list for BTA_AvRemoteCmd */
#define BTA_AV_RC_SELECT AVRC_ID_SELECT /* select */
#define BTA_AV_RC_UP AVRC_ID_UP /* up */
#define BTA_AV_RC_DOWN AVRC_ID_DOWN /* down */
#define BTA_AV_RC_LEFT AVRC_ID_LEFT /* left */
#define BTA_AV_RC_RIGHT AVRC_ID_RIGHT /* right */
#define BTA_AV_RC_RIGHT_UP AVRC_ID_RIGHT_UP /* right-up */
#define BTA_AV_RC_RIGHT_DOWN AVRC_ID_RIGHT_DOWN /* right-down */
#define BTA_AV_RC_LEFT_UP AVRC_ID_LEFT_UP /* left-up */
#define BTA_AV_RC_LEFT_DOWN AVRC_ID_LEFT_DOWN /* left-down */
#define BTA_AV_RC_ROOT_MENU AVRC_ID_ROOT_MENU /* root menu */
#define BTA_AV_RC_SETUP_MENU AVRC_ID_SETUP_MENU /* setup menu */
#define BTA_AV_RC_CONT_MENU AVRC_ID_CONT_MENU /* contents menu */
#define BTA_AV_RC_FAV_MENU AVRC_ID_FAV_MENU /* favorite menu */
#define BTA_AV_RC_EXIT AVRC_ID_EXIT /* exit */
#define BTA_AV_RC_0 AVRC_ID_0 /* 0 */
#define BTA_AV_RC_1 AVRC_ID_1 /* 1 */
#define BTA_AV_RC_2 AVRC_ID_2 /* 2 */
#define BTA_AV_RC_3 AVRC_ID_3 /* 3 */
#define BTA_AV_RC_4 AVRC_ID_4 /* 4 */
#define BTA_AV_RC_5 AVRC_ID_5 /* 5 */
#define BTA_AV_RC_6 AVRC_ID_6 /* 6 */
#define BTA_AV_RC_7 AVRC_ID_7 /* 7 */
#define BTA_AV_RC_8 AVRC_ID_8 /* 8 */
#define BTA_AV_RC_9 AVRC_ID_9 /* 9 */
#define BTA_AV_RC_DOT AVRC_ID_DOT /* dot */
#define BTA_AV_RC_ENTER AVRC_ID_ENTER /* enter */
#define BTA_AV_RC_CLEAR AVRC_ID_CLEAR /* clear */
#define BTA_AV_RC_CHAN_UP AVRC_ID_CHAN_UP /* channel up */
#define BTA_AV_RC_CHAN_DOWN AVRC_ID_CHAN_DOWN /* channel down */
#define BTA_AV_RC_PREV_CHAN AVRC_ID_PREV_CHAN /* previous channel */
#define BTA_AV_RC_SOUND_SEL AVRC_ID_SOUND_SEL /* sound select */
#define BTA_AV_RC_INPUT_SEL AVRC_ID_INPUT_SEL /* input select */
#define BTA_AV_RC_DISP_INFO AVRC_ID_DISP_INFO /* display information */
#define BTA_AV_RC_HELP AVRC_ID_HELP /* help */
#define BTA_AV_RC_PAGE_UP AVRC_ID_PAGE_UP /* page up */
#define BTA_AV_RC_PAGE_DOWN AVRC_ID_PAGE_DOWN /* page down */
#define BTA_AV_RC_POWER AVRC_ID_POWER /* power */
#define BTA_AV_RC_VOL_UP AVRC_ID_VOL_UP /* volume up */
#define BTA_AV_RC_VOL_DOWN AVRC_ID_VOL_DOWN /* volume down */
#define BTA_AV_RC_MUTE AVRC_ID_MUTE /* mute */
#define BTA_AV_RC_PLAY AVRC_ID_PLAY /* play */
#define BTA_AV_RC_STOP AVRC_ID_STOP /* stop */
#define BTA_AV_RC_PAUSE AVRC_ID_PAUSE /* pause */
#define BTA_AV_RC_RECORD AVRC_ID_RECORD /* record */
#define BTA_AV_RC_REWIND AVRC_ID_REWIND /* rewind */
#define BTA_AV_RC_FAST_FOR AVRC_ID_FAST_FOR /* fast forward */
#define BTA_AV_RC_EJECT AVRC_ID_EJECT /* eject */
#define BTA_AV_RC_FORWARD AVRC_ID_FORWARD /* forward */
#define BTA_AV_RC_BACKWARD AVRC_ID_BACKWARD /* backward */
#define BTA_AV_RC_ANGLE AVRC_ID_ANGLE /* angle */
#define BTA_AV_RC_SUBPICT AVRC_ID_SUBPICT /* subpicture */
#define BTA_AV_RC_F1 AVRC_ID_F1 /* F1 */
#define BTA_AV_RC_F2 AVRC_ID_F2 /* F2 */
#define BTA_AV_RC_F3 AVRC_ID_F3 /* F3 */
#define BTA_AV_RC_F4 AVRC_ID_F4 /* F4 */
#define BTA_AV_RC_F5 AVRC_ID_F5 /* F5 */
#define BTA_AV_VENDOR AVRC_ID_VENDOR /* vendor unique */
typedef UINT8 tBTA_AV_RC;
/* state flag for pass through command */
#define BTA_AV_STATE_PRESS AVRC_STATE_PRESS /* key pressed */
#define BTA_AV_STATE_RELEASE AVRC_STATE_RELEASE /* key released */
typedef UINT8 tBTA_AV_STATE;
/* command codes for BTA_AvVendorCmd */
#define BTA_AV_CMD_CTRL AVRC_CMD_CTRL
#define BTA_AV_CMD_STATUS AVRC_CMD_STATUS
#define BTA_AV_CMD_SPEC_INQ AVRC_CMD_SPEC_INQ
#define BTA_AV_CMD_NOTIF AVRC_CMD_NOTIF
#define BTA_AV_CMD_GEN_INQ AVRC_CMD_GEN_INQ
typedef UINT8 tBTA_AV_CMD;
/* response codes for BTA_AvVendorRsp */
#define BTA_AV_RSP_NOT_IMPL AVRC_RSP_NOT_IMPL
#define BTA_AV_RSP_ACCEPT AVRC_RSP_ACCEPT
#define BTA_AV_RSP_REJ AVRC_RSP_REJ
#define BTA_AV_RSP_IN_TRANS AVRC_RSP_IN_TRANS
#define BTA_AV_RSP_IMPL_STBL AVRC_RSP_IMPL_STBL
#define BTA_AV_RSP_CHANGED AVRC_RSP_CHANGED
#define BTA_AV_RSP_INTERIM AVRC_RSP_INTERIM
typedef UINT8 tBTA_AV_CODE;
/* error codes for BTA_AvProtectRsp */
#define BTA_AV_ERR_NONE A2D_SUCCESS /* Success, no error */
#define BTA_AV_ERR_BAD_STATE AVDT_ERR_BAD_STATE /* Message cannot be processed in this state */
#define BTA_AV_ERR_RESOURCE AVDT_ERR_RESOURCE /* Insufficient resources */
#define BTA_AV_ERR_BAD_CP_TYPE A2D_BAD_CP_TYPE /* The requested Content Protection Type is not supported */
#define BTA_AV_ERR_BAD_CP_FORMAT A2D_BAD_CP_FORMAT /* The format of Content Protection Data is not correct */
typedef UINT8 tBTA_AV_ERR;
/* AV callback events */
#define BTA_AV_ENABLE_EVT 0 /* AV enabled */
#define BTA_AV_REGISTER_EVT 1 /* registered to AVDT */
#define BTA_AV_OPEN_EVT 2 /* connection opened */
#define BTA_AV_CLOSE_EVT 3 /* connection closed */
#define BTA_AV_START_EVT 4 /* stream data transfer started */
#define BTA_AV_STOP_EVT 5 /* stream data transfer stopped */
#define BTA_AV_PROTECT_REQ_EVT 6 /* content protection request */
#define BTA_AV_PROTECT_RSP_EVT 7 /* content protection response */
#define BTA_AV_RC_OPEN_EVT 8 /* remote control channel open */
#define BTA_AV_RC_CLOSE_EVT 9 /* remote control channel closed */
#define BTA_AV_REMOTE_CMD_EVT 10 /* remote control command */
#define BTA_AV_REMOTE_RSP_EVT 11 /* remote control response */
#define BTA_AV_VENDOR_CMD_EVT 12 /* vendor dependent remote control command */
#define BTA_AV_VENDOR_RSP_EVT 13 /* vendor dependent remote control response */
#define BTA_AV_RECONFIG_EVT 14 /* reconfigure response */
#define BTA_AV_SUSPEND_EVT 15 /* suspend response */
#define BTA_AV_PENDING_EVT 16 /* incoming connection pending:
* signal channel is open and stream is not open
* after BTA_AV_SIG_TIME_VAL ms */
#define BTA_AV_META_MSG_EVT 17 /* metadata messages */
#define BTA_AV_REJECT_EVT 18 /* incoming connection rejected */
#define BTA_AV_RC_FEAT_EVT 19 /* remote control channel peer supported features update */
#define BTA_AV_MEDIA_SINK_CFG_EVT 20 /* command to configure codec */
#define BTA_AV_MEDIA_DATA_EVT 21 /* sending data to Media Task */
/* Max BTA event */
#define BTA_AV_MAX_EVT 22
/* function types for call-out functions */
typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
UINT8 *p_num_protect, UINT8 *p_protect_info);
typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
UINT8 num_protect, UINT8 *p_protect_info,
UINT8 t_local_sep, UINT8 avdt_handle);
typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl,
tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
UINT16 mtu);
typedef void (*tBTA_AV_CO_CLOSE) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu);
typedef void (*tBTA_AV_CO_START) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
typedef void (*tBTA_AV_CO_STOP) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type,
UINT32 *p_len, UINT32 *p_timestamp);
typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay);
/* the call-out functions for one stream */
typedef struct {
tBTA_AV_CO_INIT init;
tBTA_AV_CO_DISC_RES disc_res;
tBTA_AV_CO_GETCFG getcfg;
tBTA_AV_CO_SETCFG setcfg;
tBTA_AV_CO_OPEN open;
tBTA_AV_CO_CLOSE close;
tBTA_AV_CO_START start;
tBTA_AV_CO_STOP stop;
tBTA_AV_CO_DATAPATH data;
tBTA_AV_CO_DELAY delay;
} tBTA_AV_CO_FUNCTS;
typedef UINT8 tBTA_AV_EVT;
/* Event associated with BTA_AV_ENABLE_EVT */
typedef struct {
tBTA_AV_FEAT features;
} tBTA_AV_ENABLE;
/* Event associated with BTA_AV_REGISTER_EVT */
typedef struct {
tBTA_AV_CHNL chnl; /* audio/video */
tBTA_AV_HNDL hndl; /* Handle associated with the stream. */
UINT8 app_id; /* ID associated with call to BTA_AvRegister() */
tBTA_AV_STATUS status;
tBTA_AV_CO_FUNCTS *p_bta_av_cos;
} tBTA_AV_REGISTER;
/* data associated with BTA_AV_OPEN_EVT */
#define BTA_AV_EDR_2MBPS 0x01
#define BTA_AV_EDR_3MBPS 0x02
typedef UINT8 tBTA_AV_EDR;
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
BD_ADDR bd_addr;
tBTA_AV_STATUS status;
BOOLEAN starting;
tBTA_AV_EDR edr; /* 0, if peer device does not support EDR */
UINT8 sep; /* sep type of peer device */
} tBTA_AV_OPEN;
/* data associated with BTA_AV_CLOSE_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
UINT8 disc_rsn; /* disconnection reason */
} tBTA_AV_CLOSE;
/* data associated with BTA_AV_START_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
tBTA_AV_STATUS status;
BOOLEAN initiator; /* TRUE, if local device initiates the START */
BOOLEAN suspending;
} tBTA_AV_START;
/* data associated with BTA_AV_SUSPEND_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */
tBTA_AV_STATUS status;
} tBTA_AV_SUSPEND;
/* data associated with BTA_AV_RECONFIG_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
tBTA_AV_STATUS status;
} tBTA_AV_RECONFIG;
/* data associated with BTA_AV_PROTECT_REQ_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
UINT8 *p_data;
UINT16 len;
} tBTA_AV_PROTECT_REQ;
/* data associated with BTA_AV_PROTECT_RSP_EVT */
typedef struct {
tBTA_AV_CHNL chnl;
tBTA_AV_HNDL hndl;
UINT8 *p_data;
UINT16 len;
tBTA_AV_ERR err_code;
} tBTA_AV_PROTECT_RSP;
/* data associated with BTA_AV_RC_OPEN_EVT */
typedef struct {
UINT8 rc_handle;
tBTA_AV_FEAT peer_features;
BD_ADDR peer_addr;
tBTA_AV_STATUS status;
} tBTA_AV_RC_OPEN;
/* data associated with BTA_AV_RC_CLOSE_EVT */
typedef struct {
UINT8 rc_handle;
BD_ADDR peer_addr;
} tBTA_AV_RC_CLOSE;
/* data associated with BTA_AV_RC_FEAT_EVT */
typedef struct {
UINT8 rc_handle;
tBTA_AV_FEAT peer_features;
} tBTA_AV_RC_FEAT;
/* data associated with BTA_AV_REMOTE_CMD_EVT */
typedef struct {
UINT8 rc_handle;
tBTA_AV_RC rc_id;
tBTA_AV_STATE key_state;
UINT8 len;
UINT8 *p_data;
tAVRC_HDR hdr; /* Message header. */
UINT8 label;
} tBTA_AV_REMOTE_CMD;
/* data associated with BTA_AV_REMOTE_RSP_EVT */
typedef struct {
UINT8 rc_handle;
tBTA_AV_RC rc_id;
tBTA_AV_STATE key_state;
UINT8 len;
UINT8 *p_data;
tBTA_AV_CODE rsp_code;
UINT8 label;
} tBTA_AV_REMOTE_RSP;
/* data associated with BTA_AV_VENDOR_CMD_EVT, BTA_AV_VENDOR_RSP_EVT */
typedef struct {
UINT8 rc_handle;
UINT16 len; /* Max vendor dependent message is 512 */
UINT8 label;
tBTA_AV_CODE code;
UINT32 company_id;
UINT8 *p_data;
} tBTA_AV_VENDOR;
/* data associated with BTA_AV_META_MSG_EVT */
typedef struct {
UINT8 rc_handle;
UINT16 len;
UINT8 label;
tBTA_AV_CODE code;
UINT32 company_id;
UINT8 *p_data;
tAVRC_MSG *p_msg;
} tBTA_AV_META_MSG;
/* data associated with BTA_AV_PENDING_EVT */
typedef struct {
BD_ADDR bd_addr;
} tBTA_AV_PEND;
/* data associated with BTA_AV_REJECT_EVT */
typedef struct {
BD_ADDR bd_addr;
tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the connection. */
} tBTA_AV_REJECT;
/* union of data associated with AV callback */
typedef union {
tBTA_AV_CHNL chnl;
tBTA_AV_ENABLE enable;
tBTA_AV_REGISTER registr;
tBTA_AV_OPEN open;
tBTA_AV_CLOSE close;
tBTA_AV_START start;
tBTA_AV_PROTECT_REQ protect_req;
tBTA_AV_PROTECT_RSP protect_rsp;
tBTA_AV_RC_OPEN rc_open;
tBTA_AV_RC_CLOSE rc_close;
tBTA_AV_REMOTE_CMD remote_cmd;
tBTA_AV_REMOTE_RSP remote_rsp;
tBTA_AV_VENDOR vendor_cmd;
tBTA_AV_VENDOR vendor_rsp;
tBTA_AV_RECONFIG reconfig;
tBTA_AV_SUSPEND suspend;
tBTA_AV_PEND pend;
tBTA_AV_META_MSG meta_msg;
tBTA_AV_REJECT reject;
tBTA_AV_RC_FEAT rc_feat;
} tBTA_AV;
/* union of data associated with AV Media callback */
typedef union {
BT_HDR *p_data;
UINT8 *codec_info;
} tBTA_AV_MEDIA;
#define BTA_AVC_PACKET_LEN AVRC_PACKET_LEN
#define BTA_VENDOR_DATA_OFFSET 6
#define BTA_VENDOR_HEADER_LEN 4
#define BTA_MAX_VENDOR_DEPENDENT_DATA_LEN (BTA_AVC_PACKET_LEN-BTA_VENDOR_DATA_OFFSET-BTA_VENDOR_HEADER_LEN)
#define BTA_GROUP_NAVI_MSG_OP_DATA_LEN 5
#define BTA_ERROR_INVALID_CMD AVRC_STS_BAD_CMD
#define BTA_ERROR_INVALID_PARAM AVRC_STS_BAD_PARAM
#define BTA_ERROR_BAD_CONTENTS AVRC_STS_NOT_FOUND
#define BTA_ERROR_INTERNAL AVRC_STS_INTERNAL_ERR
#define BTA_AV_META_SINGLE_PACKET AVRC_PKT_SINGLE
#define BTA_AV_CO_METADATA AVRC_CO_METADATA
/* AV callback */
typedef void (tBTA_AV_CBACK)(tBTA_AV_EVT event, tBTA_AV *p_data);
typedef void (tBTA_AV_DATA_CBACK)(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data);
/* type for stream state machine action functions */
typedef void (*tBTA_AV_ACT)(void *p_cb, void *p_data);
/* type for registering VDP */
typedef void (tBTA_AV_REG) (tAVDT_CS *p_cs, char *p_service_name, void *p_data);
/* AV configuration structure */
typedef struct {
UINT32 company_id; /* AVRCP Company ID */
UINT16 avrc_mtu; /* AVRCP MTU at L2CAP for control channel */
UINT16 avrc_br_mtu; /* AVRCP MTU at L2CAP for browsing channel */
UINT16 avrc_ct_cat; /* AVRCP controller categories */
UINT16 avrc_tg_cat; /* AVRCP target categories */
UINT16 sig_mtu; /* AVDTP signaling channel MTU at L2CAP */
UINT16 audio_mtu; /* AVDTP audio transport channel MTU at L2CAP */
const UINT16 *p_audio_flush_to;/* AVDTP audio transport channel flush timeout */
UINT16 audio_mqs; /* AVDTP audio channel max data queue size */
UINT16 video_mtu; /* AVDTP video transport channel MTU at L2CAP */
UINT16 video_flush_to; /* AVDTP video transport channel flush timeout */
BOOLEAN avrc_group; /* TRUE, to accept AVRC 1.3 group nevigation command */
UINT8 num_co_ids; /* company id count in p_meta_co_ids */
UINT8 num_evt_ids; /* event id count in p_meta_evt_ids */
tBTA_AV_CODE rc_pass_rsp; /* the default response code for pass through commands */
const UINT32 *p_meta_co_ids;/* the metadata Get Capabilities response for company id */
const UINT8 *p_meta_evt_ids;/* the the metadata Get Capabilities response for event id */
const tBTA_AV_ACT *p_act_tbl;/* the action function table for VDP stream */
tBTA_AV_REG *p_reg; /* action function to register VDP */
char avrc_controller_name[BTA_SERVICE_NAME_LEN]; /* Default AVRCP controller name */
char avrc_target_name[BTA_SERVICE_NAME_LEN]; /* Default AVRCP target name*/
} tBTA_AV_CFG;
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
** External Function Declarations
*****************************************************************************/
/*******************************************************************************
**
** Function BTA_AvEnable
**
** Description Enable the advanced audio/video service. When the enable
** operation is complete the callback function will be
** called with a BTA_AV_ENABLE_EVT. This function must
** be called before other function in the AV API are
** called.
**
** Returns void
**
*******************************************************************************/
void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features,
tBTA_AV_CBACK *p_cback);
/*******************************************************************************
**
** Function BTA_AvDisable
**
** Description Disable the advanced audio/video service.
**
**
** Returns void
**
*******************************************************************************/
void BTA_AvDisable(void);
/*******************************************************************************
**
** Function BTA_AvRegister
**
** Description Register the audio or video service to stack. When the
** operation is complete the callback function will be
** called with a BTA_AV_REGISTER_EVT. This function must
** be called before AVDT stream is open.
**
**
** Returns void
**
*******************************************************************************/
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name,
UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos);
/*******************************************************************************
**
** Function BTA_AvDeregister
**
** Description Deregister the audio or video service
**
** Returns void
**
*******************************************************************************/
void BTA_AvDeregister(tBTA_AV_HNDL hndl);
/*******************************************************************************
**
** Function BTA_AvOpen
**
** Description Opens an advanced audio/video connection to a peer device.
** When connection is open callback function is called
** with a BTA_AV_OPEN_EVT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle,
BOOLEAN use_rc, tBTA_SEC sec_mask, UINT16 uuid);
/*******************************************************************************
**
** Function BTA_AvClose
**
** Description Close the current streams.
**
** Returns void
**
*******************************************************************************/
void BTA_AvClose(tBTA_AV_HNDL handle);
/*******************************************************************************
**
** Function BTA_AvDisconnect
**
** Description Close the connection to the address.
**
** Returns void
**
*******************************************************************************/
void BTA_AvDisconnect(BD_ADDR bd_addr);
/*******************************************************************************
**
** Function BTA_AvEnable_Sink
**
** Description Enable/Disable A2DP Sink.
**
** Returns void
**
*******************************************************************************/
void BTA_AvEnable_Sink(int enable);
/*******************************************************************************
**
** Function BTA_AvStart
**
** Description Start audio/video stream data transfer.
**
** Returns void
**
*******************************************************************************/
void BTA_AvStart(void);
/*******************************************************************************
**
** Function BTA_AvStop
**
** Description Stop audio/video stream data transfer.
** If suspend is TRUE, this function sends AVDT suspend signal
** to the connected peer(s).
**
** Returns void
**
*******************************************************************************/
void BTA_AvStop(BOOLEAN suspend);
/*******************************************************************************
**
** Function BTA_AvReconfig
**
** Description Reconfigure the audio/video stream.
** If suspend is TRUE, this function tries the suspend/reconfigure
** procedure first.
** If suspend is FALSE or when suspend/reconfigure fails,
** this function closes and re-opens the AVDT connection.
**
** Returns void
**
*******************************************************************************/
void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info);
/*******************************************************************************
**
** Function BTA_AvProtectReq
**
** Description Send a content protection request. This function can only
** be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len);
/*******************************************************************************
**
** Function BTA_AvProtectRsp
**
** Description Send a content protection response. This function must
** be called if a BTA_AV_PROTECT_REQ_EVT is received.
** This function can only be used if AV is enabled with
** feature BTA_AV_FEAT_PROTECT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data,
UINT16 len);
/*******************************************************************************
**
** Function BTA_AvRemoteCmd
**
** Description Send a remote control command. This function can only
** be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
**
** Returns void
**
*******************************************************************************/
void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id,
tBTA_AV_STATE key_state);
/*******************************************************************************
**
** Function BTA_AvVendorCmd
**
** Description Send a vendor dependent remote control command. This
** function can only be used if AV is enabled with feature
** BTA_AV_FEAT_VENDOR.
**
** Returns void
**
*******************************************************************************/
void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code,
UINT8 *p_data, UINT16 len);
/*******************************************************************************
**
** Function BTA_AvVendorRsp
**
** Description Send a vendor dependent remote control response.
** This function must be called if a BTA_AV_VENDOR_CMD_EVT
** is received. This function can only be used if AV is
** enabled with feature BTA_AV_FEAT_VENDOR.
**
** Returns void
**
*******************************************************************************/
void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
UINT8 *p_data, UINT16 len, UINT32 company_id);
/*******************************************************************************
**
** Function BTA_AvOpenRc
**
** Description Open an AVRCP connection toward the device with the
** specified handle
**
** Returns void
**
*******************************************************************************/
void BTA_AvOpenRc(tBTA_AV_HNDL handle);
/*******************************************************************************
**
** Function BTA_AvCloseRc
**
** Description Close an AVRCP connection
**
** Returns void
**
*******************************************************************************/
void BTA_AvCloseRc(UINT8 rc_handle);
/*******************************************************************************
**
** Function BTA_AvMetaRsp
**
** Description Send a Metadata command/response. The message contained
** in p_pkt can be composed with AVRC utility functions.
** This function can only be used if AV is enabled with feature
** BTA_AV_FEAT_METADATA.
**
** Returns void
**
*******************************************************************************/
void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
BT_HDR *p_pkt);
/*******************************************************************************
**
** Function BTA_AvMetaCmd
**
** Description Send a Metadata/Advanced Control command. The message contained
** in p_pkt can be composed with AVRC utility functions.
** This function can only be used if AV is enabled with feature
** BTA_AV_FEAT_METADATA.
** This message is sent only when the peer supports the TG role.
*8 The only command makes sense right now is the absolute volume command.
**
** Returns void
**
*******************************************************************************/
void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt);
#ifdef __cplusplus
}
#endif
#endif /* BTA_AV_API_H */

View File

@ -0,0 +1,73 @@
/******************************************************************************
*
* Copyright (C) 2005-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 is the interface file for advanced audio/video call-in functions.
*
******************************************************************************/
#ifndef BTA_AV_CI_H
#define BTA_AV_CI_H
#include "bta_av_api.h"
/*****************************************************************************
** Function Declarations
*****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
**
** Function bta_av_ci_src_data_ready
**
** Description This function sends an event to the AV indicating that
** the phone has audio stream data ready to send and AV
** should call bta_av_co_audio_src_data_path() or
** bta_av_co_video_src_data_path().
**
** Returns void
**
*******************************************************************************/
extern void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl);
/*******************************************************************************
**
** Function bta_av_ci_setconfig
**
** Description This function must be called in response to function
** bta_av_co_audio_setconfig() or bta_av_co_video_setconfig.
** Parameter err_code is set to an AVDTP status value;
** AVDT_SUCCESS if the codec configuration is ok,
** otherwise error.
**
** Returns void
**
*******************************************************************************/
extern void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code,
UINT8 category, UINT8 num_seid, UINT8 *p_seid,
BOOLEAN recfg_needed, UINT8 avdt_handle);
#ifdef __cplusplus
}
#endif
#endif /* BTA_AV_CI_H */

View File

@ -0,0 +1,389 @@
/******************************************************************************
*
* Copyright (C) 2003-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 is the interface file for advanced audio/video call-out functions.
*
******************************************************************************/
#ifndef BTA_AV_CO_H
#define BTA_AV_CO_H
#include "l2c_api.h"
#include "bta_av_api.h"
/*****************************************************************************
** Constants and data types
*****************************************************************************/
/* TRUE to use SCMS-T content protection */
#ifndef BTA_AV_CO_CP_SCMS_T
#define BTA_AV_CO_CP_SCMS_T FALSE
#endif
/* the content protection IDs assigned by BT SIG */
#define BTA_AV_CP_SCMS_T_ID 0x0002
#define BTA_AV_CP_DTCP_ID 0x0001
#define BTA_AV_CP_LOSC 2
#define BTA_AV_CP_INFO_LEN 3
#define BTA_AV_CP_SCMS_COPY_MASK 3
#define BTA_AV_CP_SCMS_COPY_FREE 2
#define BTA_AV_CP_SCMS_COPY_ONCE 1
#define BTA_AV_CP_SCMS_COPY_NEVER 0
#define BTA_AV_CO_DEFAULT_AUDIO_OFFSET AVDT_MEDIA_OFFSET
enum {
BTA_AV_CO_ST_INIT,
BTA_AV_CO_ST_IN,
BTA_AV_CO_ST_OUT,
BTA_AV_CO_ST_OPEN,
BTA_AV_CO_ST_STREAM
};
/* data type for the Audio Codec Information*/
typedef struct {
UINT16 bit_rate; /* SBC encoder bit rate in kbps */
UINT16 bit_rate_busy; /* SBC encoder bit rate in kbps */
UINT16 bit_rate_swampd;/* SBC encoder bit rate in kbps */
UINT8 busy_level; /* Busy level indicating the bit-rate to be used */
UINT8 codec_info[AVDT_CODEC_SIZE];
UINT8 codec_type; /* Codec type */
} tBTA_AV_AUDIO_CODEC_INFO;
/*******************************************************************************
**
** Function bta_av_co_audio_init
**
** Description This callout function is executed by AV when it is
** started by calling BTA_AvEnable(). This function can be
** used by the phone to initialize audio paths or for other
** initialization purposes.
**
**
** Returns Stream codec and content protection capabilities info.
**
*******************************************************************************/
extern BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info,
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
/*******************************************************************************
**
** Function bta_av_co_audio_disc_res
**
** Description This callout function is executed by AV to report the
** number of stream end points (SEP) were found during the
** AVDT stream discovery process.
**
**
** Returns void.
**
*******************************************************************************/
extern void bta_av_co_audio_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps,
UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
/*******************************************************************************
**
** Function bta_av_co_video_disc_res
**
** Description This callout function is executed by AV to report the
** number of stream end points (SEP) were found during the
** AVDT stream discovery process.
**
**
** Returns void.
**
*******************************************************************************/
extern void bta_av_co_video_disc_res(tBTA_AV_HNDL hndl, UINT8 num_seps,
UINT8 num_snk, BD_ADDR addr);
/*******************************************************************************
**
** Function bta_av_co_audio_getconfig
**
** Description This callout function is executed by AV to retrieve the
** desired codec and content protection configuration for the
** audio stream.
**
**
** Returns Stream codec and content protection configuration info.
**
*******************************************************************************/
extern UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
UINT8 *p_num_protect, UINT8 *p_protect_info);
/*******************************************************************************
**
** Function bta_av_co_video_getconfig
**
** Description This callout function is executed by AV to retrieve the
** desired codec and content protection configuration for the
** video stream.
**
**
** Returns Stream codec and content protection configuration info.
**
*******************************************************************************/
extern UINT8 bta_av_co_video_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
UINT8 *p_num_protect, UINT8 *p_protect_info);
/*******************************************************************************
**
** Function bta_av_co_audio_setconfig
**
** Description This callout function is executed by AV to set the
** codec and content protection configuration of the audio stream.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
UINT8 num_protect, UINT8 *p_protect_info, UINT8 t_local_sep, UINT8 avdt_handle);
/*******************************************************************************
**
** Function bta_av_co_video_setconfig
**
** Description This callout function is executed by AV to set the
** codec and content protection configuration of the video stream.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
UINT8 num_protect, UINT8 *p_protect_info);
/*******************************************************************************
**
** Function bta_av_co_audio_open
**
** Description This function is called by AV when the audio stream connection
** is opened.
** BTA-AV maintains the MTU of A2DP streams.
** If this is the 2nd audio stream, mtu is the smaller of the 2
** streams.
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_open(tBTA_AV_HNDL hndl,
tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
UINT16 mtu);
/*******************************************************************************
**
** Function bta_av_co_video_open
**
** Description This function is called by AV when the video stream connection
** is opened.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_open(tBTA_AV_HNDL hndl,
tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
UINT16 mtu);
/*******************************************************************************
**
** Function bta_av_co_audio_close
**
** Description This function is called by AV when the audio stream connection
** is closed.
** BTA-AV maintains the MTU of A2DP streams.
** When one stream is closed and no other audio stream is open,
** mtu is reported as 0.
** Otherwise, the MTU remains open is reported.
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT16 mtu);
/*******************************************************************************
**
** Function bta_av_co_video_close
**
** Description This function is called by AV when the video stream connection
** is closed.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_close(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT16 mtu);
/*******************************************************************************
**
** Function bta_av_co_audio_start
**
** Description This function is called by AV when the audio streaming data
** transfer is started.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
/*******************************************************************************
**
** Function bta_av_co_video_start
**
** Description This function is called by AV when the video streaming data
** transfer is started.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_start(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
/*******************************************************************************
**
** Function bta_av_co_audio_stop
**
** Description This function is called by AV when the audio streaming data
** transfer is stopped.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
/*******************************************************************************
**
** Function bta_av_co_video_stop
**
** Description This function is called by AV when the video streaming data
** transfer is stopped.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
/*******************************************************************************
**
** Function bta_av_co_audio_src_data_path
**
** Description This function is called to get the next data buffer from
** the audio codec
**
** Returns NULL if data is not ready.
** Otherwise, a GKI buffer (BT_HDR*) containing the audio data.
**
*******************************************************************************/
extern void *bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type,
UINT32 *p_len, UINT32 *p_timestamp);
/*******************************************************************************
**
** Function bta_av_co_video_src_data_path
**
** Description This function is called to get the next data buffer from
** the video codec.
**
** Returns NULL if data is not ready.
** Otherwise, a video data buffer (UINT8*).
**
*******************************************************************************/
extern void *bta_av_co_video_src_data_path(tBTA_AV_CODEC codec_type,
UINT32 *p_len, UINT32 *p_timestamp);
/*******************************************************************************
**
** Function bta_av_co_audio_drop
**
** Description An Audio packet is dropped. .
** It's very likely that the connected headset with this handle
** is moved far away. The implementation may want to reduce
** the encoder bit rate setting to reduce the packet size.
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_drop(tBTA_AV_HNDL hndl);
/*******************************************************************************
**
** Function bta_av_co_video_report_conn
**
** Description This function is called by AV when the reporting channel is
** opened (open=TRUE) or closed (open=FALSE).
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_report_conn (BOOLEAN open, UINT8 avdt_handle);
/*******************************************************************************
**
** Function bta_av_co_video_report_rr
**
** Description This function is called by AV when a Receiver Report is
** received
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_report_rr (UINT32 packet_lost);
/*******************************************************************************
**
** Function bta_av_co_audio_delay
**
** Description This function is called by AV when the audio stream connection
** needs to send the initial delay report to the connected SRC.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_audio_delay(tBTA_AV_HNDL hndl, UINT16 delay);
/*******************************************************************************
**
** Function bta_av_co_video_delay
**
** Description This function is called by AV when the video stream connection
** needs to send the initial delay report to the connected SRC.
**
**
** Returns void
**
*******************************************************************************/
extern void bta_av_co_video_delay(tBTA_AV_HNDL hndl, UINT16 delay);
#endif /* BTA_AV_CO_H */

View File

@ -0,0 +1,219 @@
/******************************************************************************
*
* Copyright (C) 2004-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 is the interface to utility functions for dealing with SBC data
* frames and codec capabilities.
*
******************************************************************************/
#ifndef BTA_AV_SBC_H
#define BTA_AV_SBC_H
/*****************************************************************************
** constants
*****************************************************************************/
/* SBC packet header size */
#define BTA_AV_SBC_HDR_SIZE A2D_SBC_MPL_HDR_LEN
/*******************************************************************************
**
** Function bta_av_sbc_init_up_sample
**
** Description initialize the up sample
**
** src_sps: samples per second (source audio data)
** dst_sps: samples per second (converted audio data)
** bits: number of bits per pcm sample
** n_channels: number of channels (i.e. mono(1), stereo(2)...)
**
** Returns none
**
*******************************************************************************/
extern void bta_av_sbc_init_up_sample (UINT32 src_sps, UINT32 dst_sps,
UINT16 bits, UINT16 n_channels);
/*******************************************************************************
**
** Function bta_av_sbc_up_sample
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (number of bytes)
** dst_samples: The size of p_dst (number of bytes)
**
** Note: An AE reported an issue with this function.
** When called with bta_av_sbc_up_sample(src, uint8_array_dst..)
** the byte before uint8_array_dst may get overwritten.
** Using uint16_array_dst avoids the problem.
** This issue is related to endian-ness and is hard to resolve
** in a generic manner.
** **************** Please use uint16 array as dst.
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
extern int bta_av_sbc_up_sample (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_16s (16bits-stereo)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 4 bytes)
** dst_samples: The size of p_dst (in uint of 4 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
extern int bta_av_sbc_up_sample_16s (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_16m (16bits-mono)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 2 bytes)
** dst_samples: The size of p_dst (in uint of 2 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
extern int bta_av_sbc_up_sample_16m (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_8s (8bits-stereo)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (in uint of 2 bytes)
** dst_samples: The size of p_dst (in uint of 2 bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
extern int bta_av_sbc_up_sample_8s (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
/*******************************************************************************
**
** Function bta_av_sbc_up_sample_8m (8bits-mono)
**
** Description Given the source (p_src) audio data and
** source speed (src_sps, samples per second),
** This function converts it to audio data in the desired format
**
** p_src: the data buffer that holds the source audio data
** p_dst: the data buffer to hold the converted audio data
** src_samples: The number of source samples (number of bytes)
** dst_samples: The size of p_dst (number of bytes)
**
** Returns The number of bytes used in p_dst
** The number of bytes used in p_src (in *p_ret)
**
*******************************************************************************/
extern int bta_av_sbc_up_sample_8m (void *p_src, void *p_dst,
UINT32 src_samples, UINT32 dst_samples,
UINT32 *p_ret);
/*******************************************************************************
**
** Function bta_av_sbc_cfg_for_cap
**
** Description Determine the preferred SBC codec configuration for the
** given codec capabilities. The function is passed the
** preferred codec configuration and the peer codec
** capabilities for the stream. The function attempts to
** match the preferred capabilities with the configuration
** as best it can. The resulting codec configuration is
** returned in the same memory used for the capabilities.
**
** Returns 0 if ok, nonzero if error.
** Codec configuration in p_cap.
**
*******************************************************************************/
extern UINT8 bta_av_sbc_cfg_for_cap(UINT8 *p_peer, tA2D_SBC_CIE *p_cap, tA2D_SBC_CIE *p_pref);
/*******************************************************************************
**
** Function bta_av_sbc_cfg_in_cap
**
** Description This function checks whether an SBC codec configuration
** is allowable for the given codec capabilities.
**
** Returns 0 if ok, nonzero if error.
**
*******************************************************************************/
extern UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap);
/*******************************************************************************
**
** Function bta_av_sbc_cfg_matches_cap
**
** Description This function checks whether an SBC codec configuration
** matched with capabilities. Here we check subset.
**
** Returns 0 if ok, nonzero if error.
**
*******************************************************************************/
extern UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap);
/*******************************************************************************
**
** Function bta_av_sbc_bld_hdr
**
** Description This function builds the packet header for MPF1.
**
** Returns void
**
*******************************************************************************/
extern void bta_av_sbc_bld_hdr(BT_HDR *p_buf, UINT16 fr_per_pkt);
#endif /* BTA_AV_SBC_H */

View File

@ -23,12 +23,14 @@
******************************************************************************/
#include <stdlib.h>
#include "bt_target.h"
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_sdp_api.h"
#include "bta_sdp_int.h"
#if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE)
/*****************************************************************************
** Constants and types
*****************************************************************************/
@ -75,3 +77,5 @@ BOOLEAN bta_sdp_sm_execute(BT_HDR *p_msg)
return (ret);
}
#endif /* #if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE) */

View File

@ -26,7 +26,7 @@
#include "bt_defs.h"
#include <stdlib.h>
#include <string.h>
#include "bt_target.h"
#include "allocator.h"
#include "bt_types.h"
#include "gki.h"
@ -39,6 +39,7 @@
#include "btm_int.h"
#include "sdp_api.h"
#if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE)
/*****************************************************************************
** Constants
*****************************************************************************/
@ -543,3 +544,5 @@ void bta_sdp_remove_record(tBTA_SDP_MSG *p_data)
bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, p_data->record.user_data);
}
}
#endif /* #if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE) */

View File

@ -22,6 +22,7 @@
*
******************************************************************************/
#include "bt_target.h"
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_sdp_api.h"
@ -31,6 +32,7 @@
// #include "port_api.h"
#include "sdp_api.h"
#if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE)
/*****************************************************************************
** Constants
*****************************************************************************/
@ -165,3 +167,4 @@ tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data)
}
#endif /* #if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE) */

View File

@ -20,12 +20,15 @@
* This file contains compile-time configurable constants for SDP Search
******************************************************************************/
#include "bt_target.h"
#include "gki.h"
#include "bta_api.h"
#include "bta_sdp_api.h"
#if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE)
#ifndef BTA_SDP_DB_SIZE
#define BTA_SDP_DB_SIZE 4500
#define BTA_SDP_DB_SIZE 1500
#endif
static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE];
@ -37,3 +40,5 @@ const tBTA_SDP_CFG bta_sdp_cfg = {
};
tBTA_SDP_CFG *p_bta_sdp_cfg = (tBTA_SDP_CFG *) &bta_sdp_cfg;
#endif /* #if defined(BTA_SDP_INCLUDED) && (BTA_SDP_INCLUDED == TRUE) */

View File

@ -0,0 +1,439 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "bt_defs.h"
#include "bt_trace.h"
#include "alarm.h"
#include "allocator.h"
#include "bdaddr.h"
#include "btc_config.h"
#include "btc_util.h"
#include "config.h"
#include "osi.h"
#include "bt_types.h"
static const char *CONFIG_FILE_PATH = "bt_config.conf";
static const period_ms_t CONFIG_SETTLE_PERIOD_MS = 3000;
static void timer_config_save(void *data);
// TODO(zachoverflow): Move these two functions out, because they are too specific for this file
// {grumpy-cat/no, monty-python/you-make-me-sad}
bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
{
if (p_device_type == NULL) {
return FALSE;
}
bt_bdaddr_t bda;
bdcpy(bda.address, bd_addr);
bdstr_t bd_addr_str;
bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
if (!btc_config_get_int(bd_addr_str, "DevType", p_device_type)) {
return FALSE;
}
LOG_DEBUG("%s: Device [%s] type %d\n", __FUNCTION__, bd_addr_str, *p_device_type);
return TRUE;
}
bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
{
if (p_addr_type == NULL) {
return FALSE;
}
bt_bdaddr_t bda;
bdcpy(bda.address, bd_addr);
bdstr_t bd_addr_str;
bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
if (!btc_config_get_int(bd_addr_str, "AddrType", p_addr_type)) {
return FALSE;
}
LOG_DEBUG("%s: Device [%s] address type %d\n", __FUNCTION__, bd_addr_str, *p_addr_type);
return TRUE;
}
static pthread_mutex_t lock; // protects operations on |config|.
static config_t *config;
static osi_alarm_t *alarm_timer;
// Module lifecycle functions
bool btc_config_init(void)
{
pthread_mutex_init(&lock, NULL);
config = config_new(CONFIG_FILE_PATH);
if (!config) {
LOG_WARN("%s unable to load config file; starting unconfigured.\n", __func__);
config = config_new_empty();
if (!config) {
LOG_ERROR("%s unable to allocate a config object.\n", __func__);
goto error;
}
}
if (config_save(config, CONFIG_FILE_PATH)) {
// unlink(LEGACY_CONFIG_FILE_PATH);
}
// TODO(sharvil): use a non-wake alarm for this once we have
// API support for it. There's no need to wake the system to
// write back to disk.
alarm_timer = osi_alarm_new("btc_config", timer_config_save, NULL, CONFIG_SETTLE_PERIOD_MS);
if (!alarm_timer) {
LOG_ERROR("%s unable to create alarm.\n", __func__);
goto error;
}
return true;
error:;
osi_alarm_free(alarm_timer);
config_free(config);
pthread_mutex_destroy(&lock);
alarm_timer = NULL;
config = NULL;
LOG_ERROR("%s failed\n", __func__);
return false;
}
bool btc_config_shut_down(void)
{
btc_config_flush();
return true;
}
bool btc_config_clean_up(void)
{
btc_config_flush();
osi_alarm_free(alarm_timer);
config_free(config);
pthread_mutex_destroy(&lock);
alarm_timer = NULL;
config = NULL;
return true;
}
bool btc_config_has_section(const char *section)
{
assert(config != NULL);
assert(section != NULL);
pthread_mutex_lock(&lock);
bool ret = config_has_section(config, section);
pthread_mutex_unlock(&lock);
return ret;
}
bool btc_config_exist(const char *section, const char *key)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
bool ret = config_has_key(config, section, key);
pthread_mutex_unlock(&lock);
return ret;
}
bool btc_config_get_int(const char *section, const char *key, int *value)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
assert(value != NULL);
pthread_mutex_lock(&lock);
bool ret = config_has_key(config, section, key);
if (ret) {
*value = config_get_int(config, section, key, *value);
}
pthread_mutex_unlock(&lock);
return ret;
}
bool btc_config_set_int(const char *section, const char *key, int value)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
config_set_int(config, section, key, value);
pthread_mutex_unlock(&lock);
return true;
}
bool btc_config_get_str(const char *section, const char *key, char *value, int *size_bytes)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
assert(value != NULL);
assert(size_bytes != NULL);
pthread_mutex_lock(&lock);
const char *stored_value = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!stored_value) {
return false;
}
strlcpy(value, stored_value, *size_bytes);
*size_bytes = strlen(value) + 1;
return true;
}
bool btc_config_set_str(const char *section, const char *key, const char *value)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
assert(value != NULL);
pthread_mutex_lock(&lock);
config_set_string(config, section, key, value, false);
pthread_mutex_unlock(&lock);
return true;
}
bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
assert(value != NULL);
assert(length != NULL);
pthread_mutex_lock(&lock);
const char *value_str = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!value_str) {
return false;
}
size_t value_len = strlen(value_str);
if ((value_len % 2) != 0 || *length < (value_len / 2)) {
return false;
}
for (size_t i = 0; i < value_len; ++i)
if (!isxdigit((unsigned char)value_str[i])) {
return false;
}
for (*length = 0; *value_str; value_str += 2, *length += 1) {
unsigned int val;
sscanf(value_str, "%02x", &val);
value[*length] = (uint8_t)(val);
}
return true;
}
size_t btc_config_get_bin_length(const char *section, const char *key)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
const char *value_str = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!value_str) {
return 0;
}
size_t value_len = strlen(value_str);
return ((value_len % 2) != 0) ? 0 : (value_len / 2);
}
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length)
{
const char *lookup = "0123456789abcdef";
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
if (length > 0) {
assert(value != NULL);
}
char *str = (char *)osi_calloc(length * 2 + 1);
if (!str) {
return false;
}
for (size_t i = 0; i < length; ++i) {
str[(i * 2) + 0] = lookup[(value[i] >> 4) & 0x0F];
str[(i * 2) + 1] = lookup[value[i] & 0x0F];
}
pthread_mutex_lock(&lock);
config_set_string(config, section, key, str, false);
pthread_mutex_unlock(&lock);
osi_free(str);
return true;
}
const btc_config_section_iter_t *btc_config_section_begin(void)
{
assert(config != NULL);
return (const btc_config_section_iter_t *)config_section_begin(config);
}
const btc_config_section_iter_t *btc_config_section_end(void)
{
assert(config != NULL);
return (const btc_config_section_iter_t *)config_section_end(config);
}
const btc_config_section_iter_t *btc_config_section_next(const btc_config_section_iter_t *section)
{
assert(config != NULL);
assert(section != NULL);
return (const btc_config_section_iter_t *)config_section_next((const config_section_node_t *)section);
}
const char *btc_config_section_name(const btc_config_section_iter_t *section)
{
assert(config != NULL);
assert(section != NULL);
return config_section_name((const config_section_node_t *)section);
}
bool btc_config_remove(const char *section, const char *key)
{
assert(config != NULL);
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
bool ret = config_remove_key(config, section, key);
pthread_mutex_unlock(&lock);
return ret;
}
void btc_config_save(void)
{
assert(alarm_timer != NULL);
assert(config != NULL);
osi_alarm_set(alarm_timer, CONFIG_SETTLE_PERIOD_MS);
}
void btc_config_flush(void)
{
assert(config != NULL);
assert(alarm_timer != NULL);
osi_alarm_cancel(alarm_timer);
pthread_mutex_lock(&lock);
config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
}
int btc_config_clear(void)
{
assert(config != NULL);
assert(alarm_timer != NULL);
osi_alarm_cancel(alarm_timer);
pthread_mutex_lock(&lock);
config_free(config);
config = config_new_empty();
if (config == NULL) {
pthread_mutex_unlock(&lock);
return false;
}
int ret = config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
return ret;
}
static void timer_config_save(UNUSED_ATTR void *data)
{
assert(config != NULL);
assert(alarm_timer != NULL);
// Garbage collection process: the config file accumulates
// cached information about remote devices during regular
// inquiry scans. We remove some of these junk entries
// so the file doesn't grow indefinitely. We have to take care
// to make sure we don't remove information about bonded
// devices (hence the check for link keys).
static const size_t CACHE_MAX = 256;
const char *keys[CACHE_MAX];
size_t num_keys = 0;
size_t total_candidates = 0;
pthread_mutex_lock(&lock);
for (const config_section_node_t *snode = config_section_begin(config); snode != config_section_end(config); snode = config_section_next(snode)) {
const char *section = config_section_name(snode);
if (!string_is_bdaddr(section)) {
continue;
}
if (config_has_key(config, section, "LinkKey") ||
config_has_key(config, section, "LE_KEY_PENC") ||
config_has_key(config, section, "LE_KEY_PID") ||
config_has_key(config, section, "LE_KEY_PCSRK") ||
config_has_key(config, section, "LE_KEY_LENC") ||
config_has_key(config, section, "LE_KEY_LCSRK")) {
continue;
}
if (num_keys < CACHE_MAX) {
keys[num_keys++] = section;
}
++total_candidates;
}
if (total_candidates > CACHE_MAX * 2)
while (num_keys > 0) {
config_remove_section(config, keys[--num_keys]);
}
config_save(config, CONFIG_FILE_PATH);
pthread_mutex_unlock(&lock);
}

View File

@ -0,0 +1,34 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include <string.h>
#include "bta_api.h"
#include "btc_task.h"
#include "btc_manage.h"
#include "btc_dev.h"
void btc_dev_call_handler(btc_msg_t *msg)
{
btc_dev_args_t *arg = (btc_dev_args_t *)msg->arg;
LOG_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
switch (msg->act) {
case BTC_DEV_ACT_SET_DEVICE_NAME:
BTA_DmSetDeviceName(arg->set_dev_name.device_name);
break;
default:
break;
}
}

View File

@ -0,0 +1,317 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "bt_target.h"
#include <stdlib.h>
#include <string.h>
#include "btc_common.h"
#include "btc_dm.h"
#include "btc_main.h"
#include "bt_trace.h"
#include "bt_target.h"
#include "btc_storage.h"
#include "bta_api.h"
/******************************************************************************
** Constants & Macros
******************************************************************************/
#define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id))
/******************************************************************************
** Static variables
******************************************************************************/
static tBTA_SERVICE_MASK btc_enabled_services = 0;
/******************************************************************************
** Static functions
******************************************************************************/
/******************************************************************************
** Externs
******************************************************************************/
#if BTC_AV_INCLUDED
extern bt_status_t btc_av_execute_service(BOOLEAN b_enable);
extern bt_status_t btc_av_sink_execute_service(BOOLEAN b_enable);
#endif
/******************************************************************************
** Functions
******************************************************************************/
static void btc_dm_sec_arg_deep_free(btc_msg_t *msg)
{
btc_dm_sec_args_t *arg = (btc_dm_sec_args_t *)(msg->arg);
if (msg->act == BTA_DM_BLE_KEY_EVT) {
osi_free(arg->sec.ble_key.p_key_value);
}
}
void btc_dm_sec_arg_deep_copy(btc_msg_t *msg, void *dst, void *src)
{
tBTA_DM_SEC *dst_dm_sec = (tBTA_DM_SEC *)dst;
tBTA_DM_SEC *src_dm_sec = (tBTA_DM_SEC *)src;
if (!src_dm_sec) {
return;
}
assert(dst_dm_sec);
memcpy(dst_dm_sec, src_dm_sec, sizeof(tBTA_DM_SEC));
if (msg->act == BTA_DM_BLE_KEY_EVT) {
dst_dm_sec->ble_key.p_key_value = osi_malloc(sizeof(tBTM_LE_KEY_VALUE));
assert(src_dm_sec->ble_key.p_key_value);
assert(dst_dm_sec->ble_key.p_key_value);
memcpy(dst_dm_sec->ble_key.p_key_value, src_dm_sec->ble_key.p_key_value, sizeof(tBTM_LE_KEY_VALUE));
}
}
/*******************************************************************************
**
** Function btc_dm_evt
**
** Description Switches context from BTE to BTC for all DM events
**
** Returns void
**
*******************************************************************************/
void btc_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *data)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_DM_SEC;
msg.act = event;
btc_transfer_context(&msg, (btc_dm_sec_args_t *)data, sizeof(btc_dm_sec_args_t), btc_dm_sec_arg_deep_copy);
}
static void btc_enable_bluetooth_evt(tBTA_STATUS status)
{
if (status == BTA_SUCCESS) {
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_SUCCESS);
} else {
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_FAIL);
}
}
static void btc_disable_bluetooth_evt(void)
{
LOG_DEBUG("%s", __FUNCTION__);
future_ready(*btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE), FUTURE_SUCCESS);
}
static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
{
/* Save link key, if not temporary */
bt_bdaddr_t bd_addr;
bt_status_t status;
LOG_DEBUG("%s: bond state success %d, present %d, type%d\n", __func__, p_auth_cmpl->success,
p_auth_cmpl->key_present, p_auth_cmpl->key_type);
bdcpy(bd_addr.address, p_auth_cmpl->bd_addr);
if ( (p_auth_cmpl->success == TRUE) && (p_auth_cmpl->key_present) ) {
#if 0
if ((p_auth_cmpl->key_type < HCI_LKEY_TYPE_DEBUG_COMB) ||
(p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB) ||
(p_auth_cmpl->key_type == HCI_LKEY_TYPE_CHANGED_COMB) ||
(p_auth_cmpl->key_type == HCI_LKEY_TYPE_AUTH_COMB_P_256)
)
#endif
if (1) {
bt_status_t ret;
LOG_DEBUG("%s: Storing link key. key_type=0x%x",
__FUNCTION__, p_auth_cmpl->key_type);
ret = btc_storage_add_bonded_device(&bd_addr,
p_auth_cmpl->key, p_auth_cmpl->key_type,
16);
BTC_ASSERTC(ret == BT_STATUS_SUCCESS, "storing link key failed", ret);
} else {
LOG_DEBUG("%s: Temporary key. Not storing. key_type=0x%x",
__FUNCTION__, p_auth_cmpl->key_type);
}
}
// Skip SDP for certain HID Devices
if (p_auth_cmpl->success) {
} else {
// Map the HCI fail reason to bt status
switch (p_auth_cmpl->fail_reason) {
case HCI_ERR_PAGE_TIMEOUT:
LOG_WARN("%s() - Pairing timeout; retrying () ...", __FUNCTION__);
return;
/* Fall-through */
case HCI_ERR_CONNECTION_TOUT:
status = BT_STATUS_RMT_DEV_DOWN;
break;
case HCI_ERR_PAIRING_NOT_ALLOWED:
status = BT_STATUS_AUTH_REJECTED;
break;
case HCI_ERR_LMP_RESPONSE_TIMEOUT:
status = BT_STATUS_AUTH_FAILURE;
break;
/* map the auth failure codes, so we can retry pairing if necessary */
case HCI_ERR_AUTH_FAILURE:
case HCI_ERR_KEY_MISSING:
btc_storage_remove_bonded_device(&bd_addr);
case HCI_ERR_HOST_REJECT_SECURITY:
case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
case HCI_ERR_UNIT_KEY_USED:
case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
case HCI_ERR_INSUFFCIENT_SECURITY:
case HCI_ERR_PEER_USER:
case HCI_ERR_UNSPECIFIED:
LOG_DEBUG(" %s() Authentication fail reason %d",
__FUNCTION__, p_auth_cmpl->fail_reason);
/* if autopair attempts are more than 1, or not attempted */
status = BT_STATUS_AUTH_FAILURE;
break;
default:
status = BT_STATUS_FAIL;
}
}
(void) status;
}
tBTA_SERVICE_MASK btc_get_enabled_services_mask(void)
{
return btc_enabled_services;
}
void btc_clear_services_mask(void)
{
btc_enabled_services = 0;
}
static bt_status_t btc_in_execute_service_request(tBTA_SERVICE_ID service_id,
BOOLEAN b_enable)
{
LOG_DEBUG("%s service_id: %d\n", __FUNCTION__, service_id);
/* Check the service_ID and invoke the profile's BT state changed API */
switch (service_id) {
#if BTC_AV_INCLUDED
case BTA_A2DP_SOURCE_SERVICE_ID:
btc_av_execute_service(b_enable);
break;
case BTA_A2DP_SINK_SERVICE_ID:
btc_av_sink_execute_service(b_enable);
break;
#endif
default:
LOG_ERROR("%s: Unknown service being enabled\n", __FUNCTION__);
return BT_STATUS_FAIL;
}
return BT_STATUS_SUCCESS;
}
void btc_dm_execute_service_request(BOOLEAN enable, char *p_param)
{
btc_in_execute_service_request(*((tBTA_SERVICE_ID *)p_param), enable);
}
bt_status_t btc_dm_enable_service(tBTA_SERVICE_ID service_id)
{
tBTA_SERVICE_ID *p_id = &service_id;
btc_enabled_services |= (1 << service_id);
LOG_DEBUG("%s: current services:0x%x", __FUNCTION__, btc_enabled_services);
btc_dm_execute_service_request(TRUE, (char *)p_id);
return BT_STATUS_SUCCESS;
}
bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id)
{
tBTA_SERVICE_ID *p_id = &service_id;
btc_enabled_services &= (tBTA_SERVICE_MASK)(~(1 << service_id));
LOG_DEBUG("%s: Current Services:0x%x", __FUNCTION__, btc_enabled_services);
btc_dm_execute_service_request(FALSE, (char *)p_id);
return BT_STATUS_SUCCESS;
}
void btc_dm_sec_cb_handler(btc_msg_t *msg)
{
btc_dm_sec_args_t *arg = (btc_dm_sec_args_t *)(msg->arg);
tBTA_DM_SEC *p_data = &(arg->sec);
// tBTA_SERVICE_MASK service_mask;
LOG_DEBUG("btc_dm_upstreams_cback ev: %d\n", msg->act);
switch (msg->act) {
case BTA_DM_ENABLE_EVT: {
btc_clear_services_mask();
btc_storage_load_bonded_devices();
btc_enable_bluetooth_evt(p_data->enable.status);
break;
}
case BTA_DM_DISABLE_EVT: {
tBTA_SERVICE_MASK service_mask = btc_get_enabled_services_mask();
for (int i = 0; i <= BTA_MAX_SERVICE_ID; i++) {
if (service_mask &
(tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) {
btc_in_execute_service_request(i, FALSE);
}
}
btc_disable_bluetooth_evt();
break;
}
case BTA_DM_PIN_REQ_EVT:
break;
case BTA_DM_AUTH_CMPL_EVT:
btc_dm_auth_cmpl_evt(&p_data->auth_cmpl);
break;
case BTA_DM_BOND_CANCEL_CMPL_EVT:
case BTA_DM_SP_CFM_REQ_EVT:
case BTA_DM_SP_KEY_NOTIF_EVT:
case BTA_DM_DEV_UNPAIRED_EVT:
case BTA_DM_BUSY_LEVEL_EVT:
case BTA_DM_LINK_UP_EVT:
case BTA_DM_LINK_DOWN_EVT:
case BTA_DM_HW_ERROR_EVT:
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
case BTA_DM_BLE_KEY_EVT:
case BTA_DM_BLE_SEC_REQ_EVT:
case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
case BTA_DM_BLE_PASSKEY_REQ_EVT:
case BTA_DM_BLE_NC_REQ_EVT:
case BTA_DM_BLE_OOB_REQ_EVT:
case BTA_DM_BLE_LOCAL_IR_EVT:
case BTA_DM_BLE_LOCAL_ER_EVT:
case BTA_DM_BLE_AUTH_CMPL_EVT:
case BTA_DM_LE_FEATURES_READ:
case BTA_DM_ENER_INFO_READ:
#endif
case BTA_DM_AUTHORIZE_EVT:
case BTA_DM_SIG_STRENGTH_EVT:
case BTA_DM_SP_RMT_OOB_EVT:
case BTA_DM_SP_KEYPRESS_EVT:
case BTA_DM_ROLE_CHG_EVT:
default:
LOG_WARN( "btc_dm_sec_cback : unhandled event (%d)\n", msg->act );
break;
}
btc_dm_sec_arg_deep_free(msg);
}

View File

@ -14,8 +14,10 @@
#include "btc_task.h"
#include "btc_main.h"
#include "btc_dm.h"
#include "future.h"
#include "esp_err.h"
#include "btc_config.h"
#include "alarm.h"
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
@ -28,27 +30,16 @@ future_t **btc_main_get_future_p(btc_main_future_type_t type)
return &main_future[type];
}
static void btc_sec_callback(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data)
{
switch (event) {
case BTA_DM_ENABLE_EVT:
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_SUCCESS);
break;
case BTA_DM_DISABLE_EVT:
future_ready(*btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE), FUTURE_SUCCESS);
break;
}
}
static void btc_enable_bluetooth(void)
{
if (BTA_EnableBluetooth(btc_sec_callback) != BTA_SUCCESS) {
if (BTA_EnableBluetooth(btc_dm_sec_evt) != BTA_SUCCESS) {
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_FAIL);
}
}
static void btc_disable_bluetooth(void)
{
btc_config_shut_down();
if (BTA_DisableBluetooth() != BTA_SUCCESS) {
future_ready(*btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE), FUTURE_FAIL);
}
@ -63,6 +54,7 @@ static void btc_init_bluetooth(void)
{
osi_alarm_create_mux();
osi_alarm_init();
btc_config_init();
bte_main_boot_entry(btc_init_callback);
}
@ -70,6 +62,7 @@ static void btc_init_bluetooth(void)
static void btc_deinit_bluetooth(void)
{
bte_main_shutdown();
btc_config_clean_up();
osi_alarm_deinit();
osi_alarm_delete_mux();
future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);

View File

@ -0,0 +1,172 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "bt_target.h"
#include <string.h>
#include "esp_bt_main.h"
#include "bt_trace.h"
#include "bt_defs.h"
#include "btc_profile_queue.h"
#include "gki.h"
#include "list.h"
#include "allocator.h"
#if BTC_PRF_QUEUE_INCLUDED
/*******************************************************************************
** Local type definitions
*******************************************************************************/
/*******************************************************************************
** Static variables
*******************************************************************************/
static list_t *connect_queue;
static const size_t MAX_REASONABLE_REQUESTS = 10;
/*******************************************************************************
** Queue helper functions
*******************************************************************************/
static void queue_int_add(connect_node_t *p_param)
{
if (!connect_queue) {
connect_queue = list_new(osi_free_func);
assert(connect_queue != NULL);
}
// Sanity check to make sure we're not leaking connection requests
assert(list_length(connect_queue) < MAX_REASONABLE_REQUESTS);
for (const list_node_t *node = list_begin(connect_queue); node != list_end(connect_queue); node = list_next(node)) {
if (((connect_node_t *)list_node(node))->uuid == p_param->uuid) {
LOG_DEBUG("%s dropping duplicate connect request for uuid: %04x", __func__, p_param->uuid);
return;
}
}
connect_node_t *p_node = osi_malloc(sizeof(connect_node_t));
assert(p_node != NULL);
memcpy(p_node, p_param, sizeof(connect_node_t));
list_append(connect_queue, p_node);
}
static void queue_int_advance()
{
if (connect_queue && !list_is_empty(connect_queue)) {
list_remove(connect_queue, list_front(connect_queue));
}
}
void btc_profile_queue_handler(btc_msg_t *msg)
{
btc_prf_que_args_t *arg = (btc_prf_que_args_t *)(msg->arg);
switch (msg->act) {
case BTC_PRF_QUE_CONNECT:
queue_int_add(&(arg->connect_node));
break;
case BTC_PRF_QUE_ADVANCE:
queue_int_advance();
break;
}
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_ENABLED) {
btc_queue_connect_next();
}
}
/*******************************************************************************
**
** Function btc_queue_connect
**
** Description Add a new connection to the queue and trigger the next
** scheduled connection.
**
** Returns BT_STATUS_SUCCESS if successful
**
*******************************************************************************/
bt_status_t btc_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btc_connect_cb_t connect_cb)
{
btc_msg_t msg;
btc_prf_que_args_t arg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PRF_QUE;
msg.act = BTC_PRF_QUE_CONNECT;
memset(&arg, 0, sizeof(btc_prf_que_args_t));
memcpy(&arg.connect_node.bda, bda, sizeof(bt_bdaddr_t));
arg.connect_node.uuid = uuid;
arg.connect_node.connect_cb = connect_cb;
return btc_transfer_context(&msg, &arg, sizeof(btc_prf_que_args_t), NULL);
}
/*******************************************************************************
**
** Function btc_queue_advance
**
** Description Clear the queue's busy status and advance to the next
** scheduled connection.
**
** Returns void
**
*******************************************************************************/
void btc_queue_advance(void)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PRF_QUE;
msg.act = BTC_PRF_QUE_ADVANCE;
btc_transfer_context(&msg, NULL, 0, NULL);
}
// This function dispatches the next pending connect request. It is called from
// stack_manager when the stack comes up.
bt_status_t btc_queue_connect_next(void)
{
if (!connect_queue || list_is_empty(connect_queue)) {
return BT_STATUS_FAIL;
}
connect_node_t *p_head = list_front(connect_queue);
// If the queue is currently busy, we return success anyway,
// since the connection has been queued...
if (p_head->busy) {
return BT_STATUS_SUCCESS;
}
p_head->busy = true;
return p_head->connect_cb(&p_head->bda, p_head->uuid);
}
/*******************************************************************************
**
** Function btc_queue_release
**
** Description Free up all the queue nodes and set the queue head to NULL
**
** Returns void
**
*******************************************************************************/
void btc_queue_release(void)
{
list_free(connect_queue);
connect_queue = NULL;
}
#endif /* if BTC_PRF_QUEUE_INCLUDED */

View File

@ -0,0 +1,200 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*****************************************************************************
*
* Filename: btc_sm.c
*
* Description: Generic BTC state machine API
*
*****************************************************************************/
#include "bt_target.h"
#include "bt_defs.h"
#include "allocator.h"
#include "btc_common.h"
#include "btc_sm.h"
#include "gki.h"
#if BTC_SM_INCLUDED
/*****************************************************************************
** Constants & Macros
******************************************************************************/
/*****************************************************************************
** Local type definitions
******************************************************************************/
typedef struct {
btc_sm_state_t state;
btc_sm_handler_t *p_handlers;
} btc_sm_cb_t;
/*****************************************************************************
** Static variables
******************************************************************************/
/*****************************************************************************
** Static functions
******************************************************************************/
/*****************************************************************************
** Externs
******************************************************************************/
/*****************************************************************************
** Functions
******************************************************************************/
/*****************************************************************************
**
** Function btc_sm_init
**
** Description Initializes the state machine with the state handlers
** The caller should ensure that the table and the corresponding
** states match. The location that 'p_handlers' points to shall
** be available until the btc_sm_shutdown API is invoked.
**
** Returns Returns a pointer to the initialized state machine handle.
**
******************************************************************************/
btc_sm_handle_t btc_sm_init(const btc_sm_handler_t *p_handlers, btc_sm_state_t initial_state)
{
btc_sm_cb_t *p_cb;
if (p_handlers == NULL) {
LOG_ERROR("%s : p_handlers is NULL", __FUNCTION__);
return NULL;
}
p_cb = (btc_sm_cb_t *)osi_malloc(sizeof(btc_sm_cb_t));
p_cb->state = initial_state;
p_cb->p_handlers = (btc_sm_handler_t *)p_handlers;
/* Send BTC_SM_ENTER_EVT to the initial state */
p_cb->p_handlers[initial_state](BTC_SM_ENTER_EVT, NULL);
return (btc_sm_handle_t)p_cb;
}
/*****************************************************************************
**
** Function btc_sm_shutdown
**
** Description Tears down the state machine
**
** Returns None
**
******************************************************************************/
void btc_sm_shutdown(btc_sm_handle_t handle)
{
btc_sm_cb_t *p_cb = (btc_sm_cb_t *)handle;
if (p_cb == NULL) {
LOG_ERROR("%s : Invalid handle", __FUNCTION__);
return;
}
osi_free(p_cb);
}
/*****************************************************************************
**
** Function btc_sm_get_state
**
** Description Fetches the current state of the state machine
**
** Returns Current state
**
******************************************************************************/
btc_sm_state_t btc_sm_get_state(btc_sm_handle_t handle)
{
btc_sm_cb_t *p_cb = (btc_sm_cb_t *)handle;
if (p_cb == NULL) {
LOG_ERROR("%s : Invalid handle", __FUNCTION__);
return 0;
}
return p_cb->state;
}
/*****************************************************************************
**
** Function btc_sm_dispatch
**
** Description Dispatches the 'event' along with 'data' to the current state handler
**
** Returns BT_STATUS_SUCCESS on success
** BT_STATUS_UNHANDLED if event was not processed
** BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btc_sm_dispatch(btc_sm_handle_t handle, btc_sm_event_t event,
void *data)
{
bt_status_t status = BT_STATUS_SUCCESS;
btc_sm_cb_t *p_cb = (btc_sm_cb_t *)handle;
if (p_cb == NULL) {
LOG_ERROR("%s : Invalid handle", __FUNCTION__);
return BT_STATUS_FAIL;
}
if (p_cb->p_handlers[p_cb->state](event, data) == FALSE) {
return BT_STATUS_UNHANDLED;
}
return status;
}
/*****************************************************************************
**
** Function btc_sm_change_state
**
** Description Make a transition to the new 'state'. The 'BTC_SM_EXIT_EVT'
** shall be invoked before exiting the current state. The
** 'BTC_SM_ENTER_EVT' shall be invoked before entering the new state
**
** Returns BT_STATUS_SUCCESS on success
** BT_STATUS_UNHANDLED if event was not processed
** BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btc_sm_change_state(btc_sm_handle_t handle, btc_sm_state_t state)
{
bt_status_t status = BT_STATUS_SUCCESS;
btc_sm_cb_t *p_cb = (btc_sm_cb_t *)handle;
if (p_cb == NULL) {
LOG_ERROR("%s : Invalid handle", __FUNCTION__);
return BT_STATUS_FAIL;
}
/* Send exit event to the current state */
if (p_cb->p_handlers[p_cb->state](BTC_SM_EXIT_EVT, NULL) == FALSE) {
status = BT_STATUS_UNHANDLED;
}
/* Change to the new state */
p_cb->state = state;
/* Send enter event to the new state */
if (p_cb->p_handlers[p_cb->state](BTC_SM_ENTER_EVT, NULL) == FALSE) {
status = BT_STATUS_UNHANDLED;
}
return status;
}
#endif /* #if BTC_SM_INCLUDED */

View File

@ -0,0 +1,158 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "btc_storage.h"
#include "btc_util.h"
#include "osi.h"
#include "bt_trace.h"
#include "esp_system.h"
#include "bta_api.h"
#include "bdaddr.h"
#include "btc_config.h"
/*******************************************************************************
**
** Function btc_storage_add_bonded_device
**
** Description BTIF storage API - Adds the newly bonded device to NVRAM
** along with the link-key, Key type and Pin key length
**
** Returns BT_STATUS_SUCCESS if the store was successful,
** BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
LINK_KEY link_key,
uint8_t key_type,
uint8_t pin_length)
{
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
LOG_DEBUG("add to storage: Remote device:%s\n", bdstr);
int ret = btc_config_set_int(bdstr, "LinkKeyType", (int)key_type);
ret &= btc_config_set_int(bdstr, "PinLength", (int)pin_length);
ret &= btc_config_set_bin(bdstr, "LinkKey", link_key, sizeof(LINK_KEY));
/* write bonded info immediately */
btc_config_flush();
LOG_DEBUG("Storage add rslt %d\n", ret);
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
/*******************************************************************************
**
** Function btc_in_fetch_bonded_devices
**
** Description Internal helper function to fetch the bonded devices
** from NVRAM
**
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
static bt_status_t btc_in_fetch_bonded_devices(int add)
{
BOOLEAN bt_linkkey_file_found = FALSE;
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) {
const char *name = btc_config_section_name(iter);
if (!string_is_bdaddr(name)) {
continue;
}
LOG_DEBUG("Remote device:%s\n", name);
LINK_KEY link_key;
size_t size = sizeof(link_key);
if (btc_config_get_bin(name, "LinkKey", link_key, &size)) {
int linkkey_type;
if (btc_config_get_int(name, "LinkKeyType", &linkkey_type)) {
//int pin_len;
//btc_config_get_int(name, "PinLength", &pin_len))
bt_bdaddr_t bd_addr;
string_to_bdaddr(name, &bd_addr);
if (add) {
DEV_CLASS dev_class = {0, 0, 0};
int cod;
int pin_length = 0;
if (btc_config_get_int(name, "DevClass", &cod)) {
uint2devclass((UINT32)cod, dev_class);
}
btc_config_get_int(name, "PinLength", &pin_length);
BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0,
(UINT8)linkkey_type, 0, pin_length);
}
bt_linkkey_file_found = TRUE;
} else {
LOG_ERROR("bounded device:%s, LinkKeyType or PinLength is invalid\n", name);
}
}
if (!bt_linkkey_file_found) {
LOG_DEBUG("Remote device:%s, no link key\n", name);
}
}
return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function btc_storage_load_bonded_devices
**
** Description BTC storage API - Loads all the bonded devices from NVRAM
** and adds to the BTA.
** Additionally, this API also invokes the adaper_properties_cb
** and remote_device_properties_cb for each of the bonded devices.
**
** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_load_bonded_devices(void)
{
bt_status_t status;
status = btc_in_fetch_bonded_devices(1);
LOG_DEBUG("Storage load rslt %d\n", status);
return status;
}
/*******************************************************************************
**
** Function btc_storage_remove_bonded_device
**
** Description BTC storage API - Deletes the bonded device from NVRAM
**
** Returns BT_STATUS_SUCCESS if the deletion was successful,
** BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr)
{
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
LOG_DEBUG("Add to storage: Remote device:%s\n", bdstr);
int ret = 1;
if (btc_config_exist(bdstr, "LinkKeyType")) {
ret &= btc_config_remove(bdstr, "LinkKeyType");
}
if (btc_config_exist(bdstr, "PinLength")) {
ret &= btc_config_remove(bdstr, "PinLength");
}
if (btc_config_exist(bdstr, "LinkKey")) {
ret &= btc_config_remove(bdstr, "LinkKey");
}
/* write bonded info immediately */
btc_config_flush();
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}

View File

@ -20,11 +20,19 @@
#include "gki.h"
#include "bt_defs.h"
#include "btc_main.h"
#include "btc_dev.h"
#include "btc_gatts.h"
#include "btc_gattc.h"
#include "btc_gap_ble.h"
#include "btc_blufi_prf.h"
#include "btc_dm.h"
#include "bta_gatt_api.h"
#if CONFIG_CLASSIC_BT_ENABLED
#include "btc_gap_bt.h"
#include "btc_profile_queue.h"
#include "btc_av.h"
#include "btc_avrc.h"
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
static xTaskHandle xBtcTaskHandle = NULL;
@ -32,16 +40,20 @@ static xQueueHandle xBtcQueue = 0;
static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
[BTC_PID_GAP_BT] = {NULL, NULL}, // {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
[BTC_PID_SDP] = {NULL, NULL},
[BTC_PID_BLE_HID] = {NULL, NULL},
[BTC_PID_BT_HID] = {NULL, NULL},
[BTC_PID_SPP] = {NULL, NULL},
[BTC_PID_SPPLIKE] = {NULL, NULL},
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
#if CONFIG_CLASSIC_BT_ENABLED
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, NULL },
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
[BTC_PID_AVRC] = {btc_avrc_call_handler, NULL },
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
};
/*****************************************************************************

View File

@ -0,0 +1,192 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/************************************************************************************
*
* Filename: btc_util.c
*
* Description: Miscellaneous helper functions
*
*
***********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "btc_util.h"
#include "bta_av_api.h"
#include "bt_defs.h"
/************************************************************************************
** Constants & Macros
************************************************************************************/
#define ISDIGIT(a) ((a>='0') && (a<='9'))
#define ISXDIGIT(a) (((a>='0') && (a<='9'))||((a>='A') && (a<='F'))||((a>='a') && (a<='f')))
/************************************************************************************
** Local type definitions
************************************************************************************/
/************************************************************************************
** Static variables
************************************************************************************/
/************************************************************************************
** Static functions
************************************************************************************/
/************************************************************************************
** Externs
************************************************************************************/
/************************************************************************************
** Functions
************************************************************************************/
/*****************************************************************************
** Logging helper functions
*****************************************************************************/
const char *dump_rc_event(UINT8 event)
{
switch (event) {
CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
default:
return "UNKNOWN_EVENT";
}
}
const char *dump_rc_notification_event_id(UINT8 event_id)
{
switch (event_id) {
CASE_RETURN_STR(AVRC_EVT_PLAY_STATUS_CHANGE)
CASE_RETURN_STR(AVRC_EVT_TRACK_CHANGE)
CASE_RETURN_STR(AVRC_EVT_TRACK_REACHED_END)
CASE_RETURN_STR(AVRC_EVT_TRACK_REACHED_START)
CASE_RETURN_STR(AVRC_EVT_PLAY_POS_CHANGED)
CASE_RETURN_STR(AVRC_EVT_BATTERY_STATUS_CHANGE)
CASE_RETURN_STR(AVRC_EVT_SYSTEM_STATUS_CHANGE)
CASE_RETURN_STR(AVRC_EVT_APP_SETTING_CHANGE)
CASE_RETURN_STR(AVRC_EVT_VOLUME_CHANGE)
default:
return "Unhandled Event ID";
}
}
const char *dump_rc_pdu(UINT8 pdu)
{
switch (pdu) {
CASE_RETURN_STR(AVRC_PDU_LIST_PLAYER_APP_ATTR)
CASE_RETURN_STR(AVRC_PDU_LIST_PLAYER_APP_VALUES)
CASE_RETURN_STR(AVRC_PDU_GET_CUR_PLAYER_APP_VALUE)
CASE_RETURN_STR(AVRC_PDU_SET_PLAYER_APP_VALUE)
CASE_RETURN_STR(AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT)
CASE_RETURN_STR(AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT)
CASE_RETURN_STR(AVRC_PDU_INFORM_DISPLAY_CHARSET)
CASE_RETURN_STR(AVRC_PDU_INFORM_BATTERY_STAT_OF_CT)
CASE_RETURN_STR(AVRC_PDU_GET_ELEMENT_ATTR)
CASE_RETURN_STR(AVRC_PDU_GET_PLAY_STATUS)
CASE_RETURN_STR(AVRC_PDU_REGISTER_NOTIFICATION)
CASE_RETURN_STR(AVRC_PDU_REQUEST_CONTINUATION_RSP)
CASE_RETURN_STR(AVRC_PDU_ABORT_CONTINUATION_RSP)
CASE_RETURN_STR(AVRC_PDU_SET_ABSOLUTE_VOLUME)
default:
return "Unknown PDU";
}
}
UINT32 devclass2uint(DEV_CLASS dev_class)
{
UINT32 cod = 0;
if (dev_class != NULL) {
/* if COD is 0, irrespective of the device type set it to Unclassified device */
cod = (dev_class[2]) | (dev_class[1] << 8) | (dev_class[0] << 16);
}
return cod;
}
void uint2devclass(UINT32 cod, DEV_CLASS dev_class)
{
dev_class[2] = (UINT8)cod;
dev_class[1] = (UINT8)(cod >> 8);
dev_class[0] = (UINT8)(cod >> 16);
}
static const UINT8 sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
};
void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t *uuid128)
{
uint16_t uuid16_bo;
memset(uuid128, 0, sizeof(bt_uuid_t));
memcpy(uuid128->uu, sdp_base_uuid, MAX_UUID_SIZE);
uuid16_bo = ntohs(uuid16);
memcpy(uuid128->uu + 2, &uuid16_bo, sizeof(uint16_t));
}
void string_to_uuid(char *str, bt_uuid_t *p_uuid)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
&uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
uuid0 = htonl(uuid0);
uuid1 = htons(uuid1);
uuid2 = htons(uuid2);
uuid3 = htons(uuid3);
uuid4 = htonl(uuid4);
uuid5 = htons(uuid5);
memcpy(&(p_uuid->uu[0]), &uuid0, 4);
memcpy(&(p_uuid->uu[4]), &uuid1, 2);
memcpy(&(p_uuid->uu[6]), &uuid2, 2);
memcpy(&(p_uuid->uu[8]), &uuid3, 2);
memcpy(&(p_uuid->uu[10]), &uuid4, 4);
memcpy(&(p_uuid->uu[14]), &uuid5, 2);
return;
}
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
memcpy(&uuid0, &(p_uuid->uu[0]), 4);
memcpy(&uuid1, &(p_uuid->uu[4]), 2);
memcpy(&uuid2, &(p_uuid->uu[6]), 2);
memcpy(&uuid3, &(p_uuid->uu[8]), 2);
memcpy(&uuid4, &(p_uuid->uu[10]), 4);
memcpy(&uuid5, &(p_uuid->uu[14]), 2);
sprintf((char *)str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
ntohl(uuid0), ntohs(uuid1),
ntohs(uuid2), ntohs(uuid3),
ntohl(uuid4), ntohs(uuid5));
return;
}

View File

@ -0,0 +1,35 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_COMMON_H__
#define __BTC_COMMON_H__
#include "bt_trace.h"
#include "bt_types.h"
#include "osi.h"
#define BTC_ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \
"### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
#define BTC_HAL_CBACK(P_CB, P_CBACK, ...)\
if (P_CB && P_CB->P_CBACK) { \
LOG_INFO("HAL %s->%s", #P_CB, #P_CBACK); \
P_CB->P_CBACK(__VA_ARGS__); \
} \
else { \
BTC_ASSERTC(0, "Callback is NULL", 0); \
}
#endif /* __BTC_COMMON_H__ */

View File

@ -0,0 +1,54 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_CONFIG_H__
#define __BTC_CONFIG_H__
#include <stdbool.h>
#include <stddef.h>
#include "bt_types.h"
typedef struct btc_config_section_iter_t btc_config_section_iter_t;
bool btc_config_init(void);
bool btc_config_shut_down(void);
bool btc_config_clean_up(void);
bool btc_config_has_section(const char *section);
bool btc_config_exist(const char *section, const char *key);
bool btc_config_get_int(const char *section, const char *key, int *value);
bool btc_config_set_int(const char *section, const char *key, int value);
bool btc_config_get_str(const char *section, const char *key, char *value, int *size_bytes);
bool btc_config_set_str(const char *section, const char *key, const char *value);
bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length);
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length);
bool btc_config_remove(const char *section, const char *key);
size_t btc_config_get_bin_length(const char *section, const char *key);
const btc_config_section_iter_t *btc_config_section_begin(void);
const btc_config_section_iter_t *btc_config_section_end(void);
const btc_config_section_iter_t *btc_config_section_next(const btc_config_section_iter_t *section);
const char *btc_config_section_name(const btc_config_section_iter_t *section);
void btc_config_save(void);
void btc_config_flush(void);
int btc_config_clear(void);
// TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general.
bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
#endif

View File

@ -0,0 +1,38 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_DEV_H__
#define __BTC_DEV_H__
#include "esp_bt_defs.h"
#include "esp_bt_device.h"
#include "btc_task.h"
typedef enum {
BTC_DEV_ACT_SET_DEVICE_NAME
} btc_dev_act_t;
/* btc_dev_args_t */
typedef union {
// BTC_BT_GAP_ACT_SET_DEV_NAME
struct set_bt_dev_name_args {
#define ESP_DEV_DEVICE_NAME_MAX (32)
char device_name[ESP_DEV_DEVICE_NAME_MAX + 1];
} set_dev_name;
} btc_dev_args_t;
void btc_dev_call_handler(btc_msg_t *msg);
#endif /* __BTC_DEV_H__ */

View File

@ -0,0 +1,40 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_DM_H__
#define __BTC_DM_H__
#include "btc_task.h"
#include "esp_bt_defs.h"
#include "bta_api.h"
typedef enum {
BTC_DM_SEC_ACT
} btc_dm_sec_act_t;
/* btc_dm_args_t */
typedef union {
//BTC_DM_SEC_ACT
tBTA_DM_SEC sec;
} btc_dm_sec_args_t;
// void btc_dm_call_handler(btc_msg_t *msg);
void btc_dm_sec_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *data);
void btc_dm_sec_cb_handler(btc_msg_t *msg);
void btc_dm_sec_arg_deep_copy(btc_msg_t *msg, void *dst, void *src);
bt_status_t btc_dm_enable_service(tBTA_SERVICE_ID service_id);
bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id);
#endif /* __BTC_DM_H__ */

View File

@ -0,0 +1,55 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*******************************************************************************
*
* Filename: btc_profile_queue.h
*
* Description: Bluetooth remote device connection queuing
*
*******************************************************************************/
#ifndef __BTC_PROFILE_QUEUE_H__
#define __BTC_PROFILE_QUEUE_H__
#include "bt_defs.h"
#include "btc_task.h"
typedef enum {
BTC_PRF_QUE_CONNECT = 0,
BTC_PRF_QUE_ADVANCE
} btc_prf_que_act_t;
typedef bt_status_t (*btc_connect_cb_t) (bt_bdaddr_t *bda, uint16_t uuid);
typedef struct connect_node_t {
bt_bdaddr_t bda;
uint16_t uuid;
bool busy;
btc_connect_cb_t connect_cb;
} connect_node_t;
/* btc_prf_que_args_t */
typedef union {
// BTC_PRF_QUE_CONNECT
connect_node_t connect_node;
} btc_prf_que_args_t;
bt_status_t btc_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btc_connect_cb_t connect_cb);
void btc_queue_advance(void);
bt_status_t btc_queue_connect_next(void);
void btc_queue_release(void);
void btc_profile_queue_handler(btc_msg_t *msg);
#endif /* __BTC_PROFILE_QUEUE_H__ */

View File

@ -0,0 +1,115 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*****************************************************************************
*
* Filename: btc_sm.h
*
* Description: Generic BTC state machine API
*
*****************************************************************************/
#ifndef __BTC_SM_H__
#define __BTC_SM_H__
/*****************************************************************************
** Constants & Macros
******************************************************************************/
/* Generic Enter/Exit state machine events */
#define BTC_SM_ENTER_EVT 0xFFFF
#define BTC_SM_EXIT_EVT 0xFFFE
/*****************************************************************************
** Type definitions and return values
******************************************************************************/
typedef UINT32 btc_sm_state_t;
typedef UINT32 btc_sm_event_t;
typedef void *btc_sm_handle_t;
typedef BOOLEAN (* btc_sm_handler_t)(btc_sm_event_t event, void *data);
/*****************************************************************************
** Functions
**
** NOTE: THESE APIs SHOULD BE INVOKED ONLY IN THE BTC CONTEXT
**
******************************************************************************/
/*****************************************************************************
**
** Function btc_sm_init
**
** Description Initializes the state machine with the state handlers
** The caller should ensure that the table and the corresponding
** states match. The location that 'p_handlers' points to shall
** be available until the btc_sm_shutdown API is invoked.
**
** Returns Returns a pointer to the initialized state machine handle.
**
******************************************************************************/
btc_sm_handle_t btc_sm_init(const btc_sm_handler_t *p_handlers,
btc_sm_state_t initial_state);
/*****************************************************************************
**
** Function btc_sm_shutdown
**
** Description Tears down the state machine
**
** Returns None
**
******************************************************************************/
void btc_sm_shutdown(btc_sm_handle_t handle);
/*****************************************************************************
**
** Function btc_sm_get_state
**
** Description Fetches the current state of the state machine
**
** Returns Current state
**
******************************************************************************/
btc_sm_state_t btc_sm_get_state(btc_sm_handle_t handle);
/*****************************************************************************
**
** Function btc_sm_dispatch
**
** Description Dispatches the 'event' along with 'data' to the current state handler
**
** Returns Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btc_sm_dispatch(btc_sm_handle_t handle, btc_sm_event_t event,
void *data);
/*****************************************************************************
**
** Function btc_sm_change_state
**
** Description Make a transition to the new 'state'. The 'BTC_SM_EXIT_EVT'
** shall be invoked before exiting the current state. The
** 'BTC_SM_ENTER_EVT' shall be invoked before entering the new state
**
**
** Returns Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise
**
******************************************************************************/
bt_status_t btc_sm_change_state(btc_sm_handle_t handle, btc_sm_state_t state);
#endif /* __BTC_SM_H__ */

View File

@ -0,0 +1,62 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_STORAGE_H__
#define __BTC_STORAGE_H__
#include <stdint.h>
#include "bt_defs.h"
#include "bt_types.h"
/*******************************************************************************
**
** Function btc_storage_add_bonded_device
**
** Description BTC storage API - Adds the newly bonded device to NVRAM
** along with the link-key, Key type and Pin key length
**
** Returns BT_STATUS_SUCCESS if the store was successful,
** BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr,
LINK_KEY link_key,
uint8_t key_type,
uint8_t pin_length);
/*******************************************************************************
**
** Function btc_storage_remove_bonded_device
**
** Description BTC storage API - Deletes the bonded device from NVRAM
**
** Returns BT_STATUS_SUCCESS if the deletion was successful,
** BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr);
/*******************************************************************************
**
** Function btc_storage_remove_bonded_device
**
** Description BTC storage API - Deletes the bonded device from NVRAM
**
** Returns BT_STATUS_SUCCESS if the deletion was successful,
** BT_STATUS_FAIL otherwise
**
*******************************************************************************/
bt_status_t btc_storage_load_bonded_devices(void);
#endif /* BTC_STORAGE_H */

View File

@ -16,6 +16,7 @@
#define __BTC_TASK_H__
#include <stdint.h>
#include "bt_target.h"
#include "bt_defs.h"
#include "thread.h"
@ -35,16 +36,20 @@ typedef enum {
typedef enum {
BTC_PID_MAIN_INIT = 0,
BTC_PID_DEV,
BTC_PID_GATTS,
BTC_PID_GATTC,
BTC_PID_GAP_BLE,
BTC_PID_GAP_BT,
BTC_PID_SDP,
BTC_PID_BLE_HID,
BTC_PID_BT_HID,
BTC_PID_SPP,
BTC_PID_SPPLIKE,
BTC_PID_BLUFI,
BTC_PID_DM_SEC,
#if CONFIG_CLASSIC_BT_ENABLED
BTC_PID_GAP_BT,
BTC_PID_PRF_QUE,
BTC_PID_A2DP,
BTC_PID_AVRC,
#endif /* CONFIG_CLASSIC_BT_ENABLED */
BTC_PID_NUM,
} btc_pid_t; //btc profile id

View File

@ -0,0 +1,47 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_UTIL_H__
#define __BTC_UTIL_H__
#include <stdbool.h>
#include "bt_types.h"
#include "bt_defs.h"
/*******************************************************************************
** Constants & Macros
********************************************************************************/
#define CASE_RETURN_STR(const) case const: return #const;
/*******************************************************************************
** Type definitions for callback functions
********************************************************************************/
typedef char bdstr_t[18];
/*******************************************************************************
** Functions
********************************************************************************/
const char *dump_rc_event(UINT8 event);
const char *dump_rc_notification_event_id(UINT8 event_id);
const char *dump_rc_pdu(UINT8 pdu);
UINT32 devclass2uint(DEV_CLASS dev_class);
void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t *uuid128);
void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
void string_to_uuid(char *str, bt_uuid_t *p_uuid);
#endif /* __BTC_UTIL_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,169 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __BTC_AV_CO_H__
#define __BTC_AV_CO_H__
#include "btc_media.h"
/*******************************************************************************
** Constants & Macros
********************************************************************************/
enum {
BTC_SV_AV_AA_SBC_INDEX = 0,
BTC_SV_AV_AA_SBC_SINK_INDEX,
BTC_SV_AV_AA_SEP_INDEX /* Last index */
};
/*******************************************************************************
** Functions
********************************************************************************/
/*******************************************************************************
**
** Function bta_av_co_cp_is_active
**
** Description Get the current configuration of content protection
**
** Returns TRUE if the current streaming has CP, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_cp_is_active(void);
/*******************************************************************************
**
** Function bta_av_co_cp_get_flag
**
** Description Get content protection flag
** BTA_AV_CP_SCMS_COPY_NEVER
** BTA_AV_CP_SCMS_COPY_ONCE
** BTA_AV_CP_SCMS_COPY_FREE
**
** Returns The current flag value
**
*******************************************************************************/
UINT8 bta_av_co_cp_get_flag(void);
/*******************************************************************************
**
** Function bta_av_co_cp_set_flag
**
** Description Set content protection flag
** BTA_AV_CP_SCMS_COPY_NEVER
** BTA_AV_CP_SCMS_COPY_ONCE
** BTA_AV_CP_SCMS_COPY_FREE
**
** Returns TRUE if setting the SCMS flag is supported else FALSE
**
*******************************************************************************/
BOOLEAN bta_av_co_cp_set_flag(UINT8 cp_flag);
/*******************************************************************************
**
** Function bta_av_co_audio_codec_reset
**
** Description Reset the current codec configuration
**
** Returns void
**
*******************************************************************************/
void bta_av_co_audio_codec_reset(void);
/*******************************************************************************
**
** Function bta_av_co_audio_codec_supported
**
** Description Check if all opened connections are compatible with a codec
** configuration
**
** Returns TRUE if all opened devices support this codec, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_codec_supported(tBTC_STATUS *p_status);
/*******************************************************************************
**
** Function bta_av_co_audio_set_codec
**
** Description Set the current codec configuration from the feeding type.
** This function is starting to modify the configuration, it
** should be protected.
**
** Returns TRUE if successful, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_STATUS *p_status);
/*******************************************************************************
**
** Function bta_av_co_audio_get_sbc_config
**
** Description Retrieves the SBC codec configuration. If the codec in use
** is not SBC, return the default SBC codec configuration.
**
** Returns TRUE if codec is SBC, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu);
/*******************************************************************************
**
** Function bta_av_co_audio_discard_config
**
** Description Discard the codec configuration of a connection
**
** Returns Nothing
**
*******************************************************************************/
void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl);
/*******************************************************************************
**
** Function bta_av_co_init
**
** Description Initialization
**
** Returns Nothing
**
*******************************************************************************/
void bta_av_co_init(void);
/*******************************************************************************
**
** Function bta_av_co_peer_cp_supported
**
** Description Checks if the peer supports CP
**
** Returns TRUE if the peer supports CP
**
*******************************************************************************/
BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl);
/*******************************************************************************
**
** Function bta_av_co_get_remote_bitpool_pref
**
** Description Check if remote side did a setconfig within the limits
** of our exported bitpool range. If set we will set the
** remote preference.
**
** Returns TRUE if config set, FALSE otherwize
**
*******************************************************************************/
BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max);
#endif

View File

@ -0,0 +1,443 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*****************************************************************************
*
* Filename: btc_avrc.c
*
* Description: Bluetooth AVRC implementation
*
*****************************************************************************/
#include "bt_target.h"
#include <string.h>
#include "bta_api.h"
#include "bta_av_api.h"
#include "avrc_defs.h"
#include "gki.h"
#include "btc_common.h"
#include "btc_util.h"
#include "btc_av.h"
#include "btc_avrc.h"
#include "btc_manage.h"
#include "esp_avrc_api.h"
#if BTC_AV_INCLUDED
/*****************************************************************************
** Constants & Macros
******************************************************************************/
/* for AVRC 1.4 need to change this */
#define MAX_RC_NOTIFICATIONS AVRC_EVT_APP_SETTING_CHANGE
#define MAX_VOLUME 128
#define MAX_LABEL 16
#define MAX_TRANSACTIONS_PER_SESSION 16
#define MAX_CMD_QUEUE_LEN 8
#define CHECK_ESP_RC_CONNECTED do { \
LOG_DEBUG("## %s ##", __FUNCTION__); \
if (btc_rc_vb.rc_connected == FALSE) { \
LOG_WARN("Function %s() called when RC is not connected", __FUNCTION__); \
return ESP_ERR_INVALID_STATE; \
} \
} while (0)
/*****************************************************************************
** Local type definitions
******************************************************************************/
typedef struct {
UINT8 bNotify;
UINT8 label;
} btc_rc_reg_notifications_t;
typedef struct {
UINT8 label;
UINT8 ctype;
BOOLEAN is_rsp_pending;
} btc_rc_cmd_ctxt_t;
/* TODO : Merge btc_rc_reg_notifications_t and btc_rc_cmd_ctxt_t to a single struct */
typedef struct {
BOOLEAN rc_connected;
UINT8 rc_handle;
tBTA_AV_FEAT rc_features;
BD_ADDR rc_addr;
UINT16 rc_pending_play;
btc_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
btc_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
unsigned int rc_volume;
uint8_t rc_vol_label;
} btc_rc_cb_t;
typedef struct {
BOOLEAN in_use;
UINT8 lbl;
UINT8 handle;
} rc_transaction_t;
typedef struct {
pthread_mutex_t lbllock;
rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
} rc_device_t;
rc_device_t device;
static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open);
static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close);
static void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp);
/*****************************************************************************
** Static variables
******************************************************************************/
static btc_rc_cb_t btc_rc_vb;
/*****************************************************************************
** Externs
******************************************************************************/
/*****************************************************************************
** Static functions
******************************************************************************/
static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
{
esp_avrc_ct_cb_t btc_avrc_cb = (esp_avrc_ct_cb_t)btc_profile_cb_get(BTC_PID_AVRC);
if (btc_avrc_cb) {
btc_avrc_cb(event, param);
}
}
static void handle_rc_features(void)
{
btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
bt_bdaddr_t rc_addr;
bdcpy(rc_addr.address, btc_rc_vb.rc_addr);
// TODO(eisenbach): If devices need to be blacklisted for absolute
// volume, it should be added to device/include/interop_database.h
// For now, everything goes... If blacklisting is necessary, exclude
// the following bit here:
// btc_rc_vb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
if (btc_rc_vb.rc_features & BTA_AV_FEAT_BROWSE) {
rc_features |= BTRC_FEAT_BROWSE;
}
if ( (btc_rc_vb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
(btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG)) {
rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
}
if (btc_rc_vb.rc_features & BTA_AV_FEAT_METADATA) {
rc_features |= BTRC_FEAT_METADATA;
}
LOG_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
}
/***************************************************************************
* Function handle_rc_connect
*
* - Argument: tBTA_AV_RC_OPEN RC open data structure
*
* - Description: RC connection event handler
*
***************************************************************************/
static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
{
LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
#if (AVRC_CTLR_INCLUDED == TRUE)
bt_bdaddr_t rc_addr;
#endif
if (p_rc_open->status == BTA_AV_SUCCESS) {
//check if already some RC is connected
if (btc_rc_vb.rc_connected) {
LOG_ERROR("Got RC OPEN in connected state, Connected RC: %d \
and Current RC: %d", btc_rc_vb.rc_handle, p_rc_open->rc_handle );
if ((btc_rc_vb.rc_handle != p_rc_open->rc_handle)
&& (bdcmp(btc_rc_vb.rc_addr, p_rc_open->peer_addr))) {
LOG_DEBUG("Got RC connected for some other handle");
BTA_AvCloseRc(p_rc_open->rc_handle);
return;
}
}
memcpy(btc_rc_vb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
btc_rc_vb.rc_features = p_rc_open->peer_features;
btc_rc_vb.rc_vol_label = MAX_LABEL;
btc_rc_vb.rc_volume = MAX_VOLUME;
btc_rc_vb.rc_connected = TRUE;
btc_rc_vb.rc_handle = p_rc_open->rc_handle;
/* on locally initiated connection we will get remote features as part of connect */
if (btc_rc_vb.rc_features != 0) {
handle_rc_features();
}
#if (AVRC_CTLR_INCLUDED == TRUE)
bdcpy(rc_addr.address, btc_rc_vb.rc_addr);
/* report connection state if device is AVRCP target */
if (btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG) {
esp_avrc_ct_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
param.conn_stat.connected = true;
param.conn_stat.feat_mask = btc_rc_vb.rc_features;
memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t));
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
#endif
} else {
LOG_ERROR("%s Connect failed with error code: %d",
__FUNCTION__, p_rc_open->status);
btc_rc_vb.rc_connected = FALSE;
}
}
/***************************************************************************
* Function handle_rc_disconnect
*
* - Argument: tBTA_AV_RC_CLOSE RC close data structure
*
* - Description: RC disconnection event handler
*
***************************************************************************/
static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
{
#if (AVRC_CTLR_INCLUDED == TRUE)
bt_bdaddr_t rc_addr;
tBTA_AV_FEAT features;
#endif
LOG_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
if ((p_rc_close->rc_handle != btc_rc_vb.rc_handle)
&& (bdcmp(btc_rc_vb.rc_addr, p_rc_close->peer_addr))) {
LOG_ERROR("Got disconnect of unknown device");
return;
}
btc_rc_vb.rc_handle = 0;
btc_rc_vb.rc_connected = FALSE;
memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR));
memset(btc_rc_vb.rc_notif, 0, sizeof(btc_rc_vb.rc_notif));
#if (AVRC_CTLR_INCLUDED == TRUE)
features = btc_rc_vb.rc_features;
#endif
btc_rc_vb.rc_features = 0;
btc_rc_vb.rc_vol_label = MAX_LABEL;
btc_rc_vb.rc_volume = MAX_VOLUME;
#if (AVRC_CTLR_INCLUDED == TRUE)
bdcpy(rc_addr.address, btc_rc_vb.rc_addr);
#endif
memset(btc_rc_vb.rc_addr, 0, sizeof(BD_ADDR));
#if (AVRC_CTLR_INCLUDED == TRUE)
/* report connection state if device is AVRCP target */
if (features & BTA_AV_FEAT_RCTG) {
esp_avrc_ct_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
param.conn_stat.connected = false;
memcpy(param.conn_stat.remote_bda, &rc_addr, sizeof(esp_bd_addr_t));
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
#endif
}
/***************************************************************************
* Function handle_rc_passthrough_rsp
*
* - Argument: tBTA_AV_REMOTE_RSP passthrough command response
*
* - Description: Remote control passthrough response handler
*
***************************************************************************/
static void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
{
#if (AVRC_CTLR_INCLUDED == TRUE)
const char *status;
if (btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG) {
int key_state;
if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) {
status = "released";
key_state = 1;
} else {
status = "pressed";
key_state = 0;
}
LOG_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
do {
esp_avrc_ct_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
param.psth_rsp.tl = p_remote_rsp->label;
param.psth_rsp.key_code = p_remote_rsp->rc_id;
param.psth_rsp.key_state = key_state;
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PASSTHROUGH_RSP_EVT, &param);
} while (0);
} else {
LOG_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
}
#else
LOG_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
#endif
}
/***************************************************************************
**
** Function btc_rc_handler
**
** Description RC event handler
**
***************************************************************************/
void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
{
LOG_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
switch (event) {
case BTA_AV_RC_OPEN_EVT: {
LOG_DEBUG("Peer_features:%x", p_data->rc_open.peer_features);
handle_rc_connect( &(p_data->rc_open) );
} break;
case BTA_AV_RC_CLOSE_EVT: {
handle_rc_disconnect( &(p_data->rc_close) );
} break;
#if (AVRC_CTLR_INCLUDED == TRUE)
case BTA_AV_REMOTE_RSP_EVT: {
LOG_DEBUG("RSP: rc_id:0x%x key_state:%d", p_data->remote_rsp.rc_id,
p_data->remote_rsp.key_state);
handle_rc_passthrough_rsp( (&p_data->remote_rsp) );
}
break;
#endif
case BTA_AV_RC_FEAT_EVT: {
LOG_DEBUG("Peer_features:%x", p_data->rc_feat.peer_features);
btc_rc_vb.rc_features = p_data->rc_feat.peer_features;
handle_rc_features();
}
break;
// below events are not handled for now
case BTA_AV_META_MSG_EVT:
case BTA_AV_REMOTE_CMD_EVT:
default:
LOG_DEBUG("Unhandled RC event : 0x%x", event);
}
}
/***************************************************************************
**
** Function btc_rc_get_connected_peer
**
** Description Fetches the connected headset's BD_ADDR if any
**
***************************************************************************/
BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr)
{
if (btc_rc_vb.rc_connected == TRUE) {
bdcpy(peer_addr, btc_rc_vb.rc_addr);
return TRUE;
}
return FALSE;
}
/************************************************************************************
** AVRCP API Functions
************************************************************************************/
/*******************************************************************************
**
** Function btc_avrc_ct_init
**
** Description Initializes the AVRC interface
**
** Returns esp_err_t
**
*******************************************************************************/
static void btc_avrc_ct_init(void)
{
LOG_DEBUG("## %s ##", __FUNCTION__);
memset (&btc_rc_vb, 0, sizeof(btc_rc_vb));
btc_rc_vb.rc_vol_label = MAX_LABEL;
btc_rc_vb.rc_volume = MAX_VOLUME;
}
/***************************************************************************
**
** Function cleanup_ctrl
**
** Description Closes the AVRC Controller interface
**
** Returns void
**
***************************************************************************/
static void btc_avrc_ct_deinit(void)
{
LOG_INFO("## %s ##", __FUNCTION__);
memset(&btc_rc_vb, 0, sizeof(btc_rc_cb_t));
LOG_INFO("## %s ## completed", __FUNCTION__);
}
static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
{
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
if (tl >= 16 ||
key_state > ESP_AVRC_PT_CMD_STATE_RELEASED) {
return ESP_ERR_INVALID_ARG;
}
#if (AVRC_CTLR_INCLUDED == TRUE)
CHECK_ESP_RC_CONNECTED;
LOG_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
key_code, key_state);
if (btc_rc_vb.rc_features & BTA_AV_FEAT_RCTG) {
BTA_AvRemoteCmd(btc_rc_vb.rc_handle, tl,
(tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
status = BT_STATUS_SUCCESS;
LOG_INFO("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
} else {
status = BT_STATUS_FAIL;
LOG_DEBUG("%s: feature not supported", __FUNCTION__);
}
#else
LOG_DEBUG("%s: feature not enabled", __FUNCTION__);
#endif
return status;
}
void btc_avrc_call_handler(btc_msg_t *msg)
{
btc_avrc_args_t *arg = (btc_avrc_args_t *)(msg->arg);
switch (msg->act) {
case BTC_AVRC_CTRL_API_INIT_EVT: {
btc_avrc_ct_init();
// todo: callback to application
break;
}
case BTC_AVRC_CTRL_API_DEINIT_EVT: {
btc_avrc_ct_deinit();
// todo: callback to application
break;
}
case BTC_AVRC_CTRL_API_SND_PTCMD_EVT: {
btc_avrc_ct_send_passthrough_cmd(arg->pt_cmd.tl, arg->pt_cmd.key_code, arg->pt_cmd.key_state);
// todo: callback to application
break;
}
default:
LOG_WARN("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
}
}
#endif /* #if BTC_AV_INCLUDED */

View File

@ -814,9 +814,6 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
case BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY:
btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable);
break;
case BTC_GAP_BLE_ACT_SET_DEV_NAME:
BTA_DmSetDeviceName(arg->set_dev_name.device_name);
break;
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW:
btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv,
arg->cfg_adv_data_raw.raw_adv_len,

View File

@ -0,0 +1,87 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "esp_gap_bt_api.h"
#include "btc_gap_bt.h"
#include "bta_api.h"
#include "bt_trace.h"
#include <string.h>
#include "bt_target.h"
#if BTC_GAP_BT_INCLUDED
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
default:
// LOG_ERROR("Unhandled deep copy %d\n", msg->act);
break;
}
}
static void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
{
LOG_DEBUG("%s \n", __func__);
switch (msg->act) {
default:
// LOG_DEBUG("Unhandled deep free %d\n", msg->act);
break;
}
}
static void btc_bt_set_scan_mode(esp_bt_scan_mode_t mode)
{
tBTA_DM_DISC disc_mode;
tBTA_DM_CONN conn_mode;
switch (mode) {
case ESP_BT_SCAN_MODE_NONE:
disc_mode = BTA_DM_NON_DISC;
conn_mode = BTA_DM_NON_CONN;
break;
case ESP_BT_SCAN_MODE_CONNECTABLE:
disc_mode = BTA_DM_NON_DISC;
conn_mode = BTA_DM_CONN;
break;
case ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
disc_mode = BTA_DM_GENERAL_DISC;
conn_mode = BTA_DM_CONN;
break;
default:
LOG_WARN("invalid scan mode (0x%x)", mode);
return;
}
BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE);
return;
}
void btc_gap_bt_call_handler(btc_msg_t *msg)
{
btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
LOG_DEBUG("%s act %d\n", __func__, msg->act);
switch (msg->act) {
case BTC_GAP_BT_ACT_SET_SCAN_MODE: {
btc_bt_set_scan_mode(arg->set_scan_mode.mode);
break;
}
default:
break;
}
btc_gap_bt_arg_deep_free(msg);
}
#endif /* #if BTC_GAP_BT_INCLUDED */

View File

View File

@ -0,0 +1,174 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*******************************************************************************
*
* Filename: btc_av.h
*
* Description: Main API header file for all BTC AV functions accessed
* from internal stack.
*
*******************************************************************************/
#ifndef __BTC_AV_H__
#define __BTC_AV_H__
#include "esp_a2dp_api.h"
#include "btc_task.h"
#include "btc_common.h"
#include "btc_sm.h"
#include "bta_av_api.h"
/*******************************************************************************
** Type definitions for callback functions
********************************************************************************/
typedef enum {
BTC_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT,
BTC_AV_DISCONNECT_REQ_EVT,
BTC_AV_START_STREAM_REQ_EVT,
BTC_AV_STOP_STREAM_REQ_EVT,
BTC_AV_SUSPEND_STREAM_REQ_EVT,
BTC_AV_SINK_CONFIG_REQ_EVT,
} btc_av_sm_event_t;
typedef enum {
BTC_AV_SINK_API_INIT_EVT = 0,
BTC_AV_SINK_API_DEINIT_EVT,
BTC_AV_SINK_API_CONNECT_EVT,
BTC_AV_SINK_API_DISCONNECT_EVT,
BTC_AV_SINK_API_REG_DATA_CB_EVT,
} btc_av_act_t;
/* btc_av_args_t */
typedef union {
// BTC_AV_SINK_CONFIG_REQ_EVT -- internal event
esp_a2d_mcc_t mcc;
// BTC_AV_SINK_API_CONNECT_EVT
bt_bdaddr_t connect;
// BTC_AV_SINK_API_REG_DATA_CB_EVT
esp_a2d_data_cb_t data_cb;
} btc_av_args_t;
/*******************************************************************************
** BTC AV API
********************************************************************************/
void btc_a2dp_call_handler(btc_msg_t *msg);
void btc_a2dp_cb_handler(btc_msg_t *msg);
void btc_a2dp_sink_reg_data_cb(esp_a2d_data_cb_t callback);
/*******************************************************************************
**
** Function btc_av_get_sm_handle
**
** Description Fetches current av SM handle
**
** Returns None
**
*******************************************************************************/
btc_sm_handle_t btc_av_get_sm_handle(void);
/*******************************************************************************
**
** Function btc_av_stream_ready
**
** Description Checks whether AV is ready for starting a stream
**
** Returns None
**
*******************************************************************************/
BOOLEAN btc_av_stream_ready(void);
/*******************************************************************************
**
** Function btc_av_stream_started_ready
**
** Description Checks whether AV ready for media start in streaming state
**
** Returns None
**
*******************************************************************************/
BOOLEAN btc_av_stream_started_ready(void);
/*******************************************************************************
**
** Function btc_dispatch_sm_event
**
** Description Send event to AV statemachine
**
** Returns None
**
*******************************************************************************/
/* used to pass events to AV statemachine from other tasks */
void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len);
/*******************************************************************************
**
** Function btc_av_init
**
** Description Initializes btc AV if not already done
**
** Returns bt_status_t
**
*******************************************************************************/
bt_status_t btc_av_init(void);
/*******************************************************************************
**
** Function btc_av_is_connected
**
** Description Checks if av has a connected sink
**
** Returns BOOLEAN
**
*******************************************************************************/
BOOLEAN btc_av_is_connected(void);
/*******************************************************************************
**
** Function btc_av_is_peer_edr
**
** Description Check if the connected a2dp device supports
** EDR or not. Only when connected this function
** will accurately provide a true capability of
** remote peer. If not connected it will always be false.
**
** Returns TRUE if remote device is capable of EDR
**
*******************************************************************************/
BOOLEAN btc_av_is_peer_edr(void);
/******************************************************************************
**
** Function btc_av_clear_remote_suspend_flag
**
** Description Clears remote suspended flag
**
** Returns Void
********************************************************************************/
void btc_av_clear_remote_suspend_flag(void);
#endif /* __BTC_AV_H__ */

View File

@ -0,0 +1,201 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*****************************************************************************
**
** Name: btc_av_api.h
**
** Description: This is the public interface file for the advanced
** audio/video streaming (AV) subsystem of BTC.
**
*****************************************************************************/
#ifndef __BTC_AV_API_H__
#define __BTC_AV_API_H__
#include "bt_target.h"
#include "bta_av_api.h"
#include "btc_media.h"
#include "a2d_api.h"
#include "a2d_sbc.h"
/*****************************************************************************
** Constants and data types
*****************************************************************************/
/* Codec type */
#define BTC_AV_CODEC_NONE 0xFF
#define BTC_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */
#define BTC_AV_CODEC_PCM 0x5 /* Raw PCM */
typedef UINT8 tBTC_AV_CODEC_ID;
/* AV features masks */
#define BTC_AV_FEAT_RCTG BTA_AV_FEAT_RCTG /* remote control target */
#define BTC_AV_FEAT_RCCT BTA_AV_FEAT_RCCT /* remote control controller */
#define BTC_AV_FEAT_METADATA BTA_AV_FEAT_METADATA /* remote control Metadata Transfer command/response */
typedef UINT16 tBTC_AV_FEAT;
/* AV channel values */
#define BTC_AV_CHNL_MSK BTA_AV_CHNL_MSK
#define BTC_AV_CHNL_AUDIO BTA_AV_CHNL_AUDIO /* audio channel */
#define BTC_AV_CHNL_VIDEO BTA_AV_CHNL_VIDEO /* video channel */
typedef UINT8 tBTC_AV_CHNL;
typedef UINT8 tBTC_AV_HNDL;
/* Operation id list for BTC_AvRemoteCmd */
#define BTC_AV_ID_SELECT 0x00 /* select */
#define BTC_AV_ID_UP 0x01 /* up */
#define BTC_AV_ID_DOWN 0x02 /* down */
#define BTC_AV_ID_LEFT 0x03 /* left */
#define BTC_AV_ID_RIGHT 0x04 /* right */
#define BTC_AV_ID_RIGHT_UP 0x05 /* right-up */
#define BTC_AV_ID_RIGHT_DOWN 0x06 /* right-down */
#define BTC_AV_ID_LEFT_UP 0x07 /* left-up */
#define BTC_AV_ID_LEFT_DOWN 0x08 /* left-down */
#define BTC_AV_ID_ROOT_MENU 0x09 /* root menu */
#define BTC_AV_ID_SETUP_MENU 0x0A /* setup menu */
#define BTC_AV_ID_CONT_MENU 0x0B /* contents menu */
#define BTC_AV_ID_FAV_MENU 0x0C /* favorite menu */
#define BTC_AV_ID_EXIT 0x0D /* exit */
#define BTC_AV_ID_0 0x20 /* 0 */
#define BTC_AV_ID_1 0x21 /* 1 */
#define BTC_AV_ID_2 0x22 /* 2 */
#define BTC_AV_ID_3 0x23 /* 3 */
#define BTC_AV_ID_4 0x24 /* 4 */
#define BTC_AV_ID_5 0x25 /* 5 */
#define BTC_AV_ID_6 0x26 /* 6 */
#define BTC_AV_ID_7 0x27 /* 7 */
#define BTC_AV_ID_8 0x28 /* 8 */
#define BTC_AV_ID_9 0x29 /* 9 */
#define BTC_AV_ID_DOT 0x2A /* dot */
#define BTC_AV_ID_ENTER 0x2B /* enter */
#define BTC_AV_ID_CLEAR 0x2C /* clear */
#define BTC_AV_ID_CHAN_UP 0x30 /* channel up */
#define BTC_AV_ID_CHAN_DOWN 0x31 /* channel down */
#define BTC_AV_ID_PREV_CHAN 0x32 /* previous channel */
#define BTC_AV_ID_SOUND_SEL 0x33 /* sound select */
#define BTC_AV_ID_INPUT_SEL 0x34 /* input select */
#define BTC_AV_ID_DISP_INFO 0x35 /* display information */
#define BTC_AV_ID_HELP 0x36 /* help */
#define BTC_AV_ID_PAGE_UP 0x37 /* page up */
#define BTC_AV_ID_PAGE_DOWN 0x38 /* page down */
#define BTC_AV_ID_POWER 0x40 /* power */
#define BTC_AV_ID_VOL_UP 0x41 /* volume up */
#define BTC_AV_ID_VOL_DOWN 0x42 /* volume down */
#define BTC_AV_ID_MUTE 0x43 /* mute */
#define BTC_AV_ID_PLAY 0x44 /* play */
#define BTC_AV_ID_STOP 0x45 /* stop */
#define BTC_AV_ID_PAUSE 0x46 /* pause */
#define BTC_AV_ID_RECORD 0x47 /* record */
#define BTC_AV_ID_REWIND 0x48 /* rewind */
#define BTC_AV_ID_FAST_FOR 0x49 /* fast forward */
#define BTC_AV_ID_EJECT 0x4A /* eject */
#define BTC_AV_ID_FORWARD 0x4B /* forward */
#define BTC_AV_ID_BACKWARD 0x4C /* backward */
#define BTC_AV_ID_ANGLE 0x50 /* angle */
#define BTC_AV_ID_SUBPICT 0x51 /* subpicture */
#define BTC_AV_ID_F1 0x71 /* F1 */
#define BTC_AV_ID_F2 0x72 /* F2 */
#define BTC_AV_ID_F3 0x73 /* F3 */
#define BTC_AV_ID_F4 0x74 /* F4 */
#define BTC_AV_ID_F5 0x75 /* F5 */
#define BTC_AV_ID_VENDOR 0x7E /* vendor unique */
#define BTC_AV_KEYPRESSED_RELEASE 0x80
typedef UINT8 tBTC_AV_RC;
/* State flag for pass through command */
#define BTC_AV_STATE_PRESS 0 /* key pressed */
#define BTC_AV_STATE_RELEASE 1 /* key released */
typedef UINT8 tBTC_AV_STATE;
typedef UINT8 tBTC_AV_RC_HNDL;
/* Command codes for BTC_AvVendorCmd */
#define BTC_AV_CMD_CTRL 0
#define BTC_AV_CMD_STATUS 1
#define BTC_AV_CMD_SPEC_INQ 2
#define BTC_AV_CMD_NOTIF 3
#define BTC_AV_CMD_GEN_INQ 4
typedef UINT8 tBTC_AV_CMD;
/* AV callback events */
#define BTC_AV_OPEN_EVT 0 /* connection opened */
#define BTC_AV_CLOSE_EVT 1 /* connection closed */
#define BTC_AV_START_EVT 2 /* stream data transfer started */
#define BTC_AV_STOP_EVT 3 /* stream data transfer stopped */
#define BTC_AV_RC_OPEN_EVT 4 /* remote control channel open */
#define BTC_AV_RC_CLOSE_EVT 5 /* remote control channel closed */
#define BTC_AV_REMOTE_CMD_EVT 6 /* remote control command */
#define BTC_AV_REMOTE_RSP_EVT 7 /* remote control response */
#define BTC_AV_META_MSG_EVT 8 /* metadata messages */
typedef UINT8 tBTC_AV_EVT;
#define BTC_AV_FEEDING_ASYNCHRONOUS 0 /* asynchronous feeding, use tx av timer */
#define BTC_AV_FEEDING_SYNCHRONOUS 1 /* synchronous feeding, no av tx timer */
#define BTC_AV_MAX_SYNCHRONOUS_LATENCY 80 /* max latency in ms for BTC_AV_FEEDING_SYNCHRONOUS */
#define BTC_AV_MIN_SYNCHRONOUS_LATENCY 4 /* min latency in ms for BTC_AV_FEEDING_SYNCHRONOUS */
typedef UINT8 tBTC_AV_FEEDING_MODE;
#define BTC_AV_CHANNEL_MODE_MONO A2D_SBC_IE_CH_MD_MONO
#define BTC_AV_CHANNEL_MODE_STEREO A2D_SBC_IE_CH_MD_STEREO
#define BTC_AV_CHANNEL_MODE_JOINT A2D_SBC_IE_CH_MD_JOINT
#define BTC_AV_CHANNEL_MODE_DUAL A2D_SBC_IE_CH_MD_DUAL
typedef UINT8 tBTC_AV_CHANNEL_MODE;
/**
* Structure used to configure the AV codec capabilities/config
*/
typedef struct {
tBTC_AV_CODEC_ID id; /* Codec ID (in terms of BTC) */
UINT8 info[AVDT_CODEC_SIZE]; /* Codec info (can be config or capabilities) */
} tBTC_AV_CODEC_INFO;
/**
* Structure used to configure the AV media feeding
*/
typedef struct {
UINT16 sampling_freq; /* 44100, 48000 etc */
UINT16 num_channel; /* 1 for mono or 2 stereo */
UINT8 bit_per_sample; /* Number of bits per sample (8, 16) */
} tBTC_AV_MEDIA_FEED_CFG_PCM;
typedef union {
tBTC_AV_MEDIA_FEED_CFG_PCM pcm; /* Raw PCM feeding format */
} tBTC_AV_MEDIA_FEED_CFG;
typedef struct {
tBTC_AV_CODEC_ID format; /* Media codec identifier */
tBTC_AV_MEDIA_FEED_CFG cfg; /* Media codec configuration */
} tBTC_AV_MEDIA_FEEDINGS;
#ifdef __cplusplus
}
#endif
#endif /* __BTC_AV_API_H__ */

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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 __BTC_AVRC_H__
#define __BTC_AVRC_H__
#include <stdint.h>
#include <stdbool.h>
#include "bt_defs.h"
#include "bt_types.h"
#include "bta_av_api.h"
#ifndef BTC_AVRC_TGT_INCLUDED
#define BTC_AVRC_TGT_INCLUDED FALSE
#endif
/* Macros */
typedef enum {
BTRC_FEAT_NONE = 0x00, /* AVRCP 1.0 */
BTRC_FEAT_METADATA = 0x01, /* AVRCP 1.3 */
BTRC_FEAT_ABSOLUTE_VOLUME = 0x02, /* Supports TG role and volume sync */
BTRC_FEAT_BROWSE = 0x04, /* AVRCP 1.4 and up, with Browsing support */
} btrc_remote_features_t;
typedef enum {
BTC_AVRC_CTRL_API_INIT_EVT = 0,
BTC_AVRC_CTRL_API_DEINIT_EVT,
BTC_AVRC_CTRL_API_SND_PTCMD_EVT
} btc_avrc_act_t;
typedef struct {
uint8_t tl; /* transaction label */
uint8_t key_code;
uint8_t key_state;
} pt_cmd_t;
/* btc_avrc_args_t */
typedef union {
// BTC_AVRC_CTRL_API_SND_PT_CMD_EVT
struct {
uint8_t tl;
uint8_t key_code;
uint8_t key_state;
} pt_cmd;
} btc_avrc_args_t;
/** BT-RC Controller callback structure. */
typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state);
typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr);
void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr);
/*******************************************************************************
** BTC AVRC API
********************************************************************************/
void btc_avrc_call_handler(btc_msg_t *msg);
#endif /* __BTC_AVRC_H__ */

View File

@ -31,7 +31,6 @@ typedef enum {
BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN,
BTC_GAP_BLE_ACT_SET_RAND_ADDRESS,
BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY,
BTC_GAP_BLE_ACT_SET_DEV_NAME,
BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW,
BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW,
} btc_gap_ble_act_t;
@ -73,11 +72,6 @@ typedef union {
struct cfg_local_privacy_args {
bool privacy_enable;
} cfg_local_privacy;
//BTC_GAP_BLE_ACT_SET_DEV_NAME,
struct set_dev_name_args {
#define ESP_GAP_DEVICE_NAME_MAX (32)
char device_name[ESP_GAP_DEVICE_NAME_MAX + 1];
} set_dev_name;
//BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW,
struct config_adv_data_raw_args {
uint8_t *raw_adv;

View File

@ -15,8 +15,24 @@
#ifndef __BTC_GAP_BT_H__
#define __BTC_GAP_BT_H__
#include "esp_bt_defs.h"
#include "esp_gap_bt_api.h"
#include "btc_task.h"
typedef enum {
BTC_GAP_BT_ACT_SET_SCAN_MODE = 0,
} btc_gap_bt_act_t;
/* btc_bt_gap_args_t */
typedef union {
// BTC_BT_GAP_ACT_SET_SCAN_MODE,
struct set_bt_scan_mode_args {
esp_bt_scan_mode_t mode;
} set_scan_mode;
} btc_gap_bt_args_t;
void btc_gap_bt_call_handler(btc_msg_t *msg);
#define /* __BTC_GAP_BT_H__ */
void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
#endif /* __BTC_GAP_BT_H__ */

View File

@ -0,0 +1,267 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
/*******************************************************************************
*
* Filename: btc_media.h
*
* Description: This is the audio module for the BTC system.
*
*******************************************************************************/
#ifndef __BTC_MEDIA_H__
#define __BTC_MEDIA_H__
#include <stdbool.h>
#include "bta_api.h"
#include "gki.h"
#include "btc_av_api.h"
/*******************************************************************************
** Constants
*******************************************************************************/
#define BTC_SUCCESS (0)
/**
* AV (Audio Video source) Errors
*/
#define BTC_ERROR_SRV_AV_NOT_ENABLED 700 /* AV is not enabled */
#define BTC_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED 701 /* Requested Feeding not supported */
#define BTC_ERROR_SRV_AV_BUSY 702 /* Another operation ongoing */
#define BTC_ERROR_SRV_AV_NOT_OPENED 703 /* No AV link opened */
#define BTC_ERROR_SRV_AV_NOT_STARTED 704 /* AV is not started */
#define BTC_ERROR_SRV_AV_CP_NOT_SUPPORTED 705 /* Content protection is not supported by all headsets */
/* Transcoding definition for TxTranscoding and RxTranscoding */
#define BTC_MEDIA_TRSCD_OFF 0
#define BTC_MEDIA_TRSCD_PCM_2_SBC 1 /* Tx */
/*******************************************************************************
** Data types
*******************************************************************************/
typedef int tBTC_STATUS;
/* tBTC_MEDIA_INIT_AUDIO msg structure */
typedef struct {
BT_HDR hdr;
UINT16 SamplingFreq; /* 16k, 32k, 44.1k or 48k*/
UINT8 ChannelMode; /* mono, dual, stereo or joint stereo*/
UINT8 NumOfSubBands; /* 4 or 8 */
UINT8 NumOfBlocks; /* 4, 8, 12 or 16*/
UINT8 AllocationMethod; /* loudness or SNR*/
UINT16 MtuSize; /* peer mtu size */
} tBTC_MEDIA_INIT_AUDIO;
#if (BTA_AV_INCLUDED == TRUE)
/* tBTC_MEDIA_UPDATE_AUDIO msg structure */
typedef struct {
BT_HDR hdr;
UINT16 MinMtuSize; /* Minimum peer mtu size */
UINT8 MaxBitPool; /* Maximum peer bitpool */
UINT8 MinBitPool; /* Minimum peer bitpool */
} tBTC_MEDIA_UPDATE_AUDIO;
/* tBTC_MEDIA_INIT_AUDIO_FEEDING msg structure */
typedef struct {
BT_HDR hdr;
tBTC_AV_FEEDING_MODE feeding_mode;
tBTC_AV_MEDIA_FEEDINGS feeding;
} tBTC_MEDIA_INIT_AUDIO_FEEDING;
typedef struct {
BT_HDR hdr;
UINT8 codec_info[AVDT_CODEC_SIZE];
} tBTC_MEDIA_SINK_CFG_UPDATE;
#endif
/*******************************************************************************
** Public functions
*******************************************************************************/
/*******************************************************************************
**
** Function btc_av_task
**
** Description
**
** Returns void
**
*******************************************************************************/
extern void btc_media_task(void);
/*******************************************************************************
**
** Function btc_media_task_enc_init_req
**
** Description Request to initialize the media task encoder
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg);
/*******************************************************************************
**
** Function btc_media_task_enc_update_req
**
** Description Request to update the media task encoder
**
** Returns TRUE is success
**
*******************************************************************************/
#if (BTA_AV_INCLUDED == TRUE)
extern BOOLEAN btc_media_task_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg);
#endif
/*******************************************************************************
**
** Function btc_media_task_start_aa_req
**
** Description Request to start audio encoding task
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_start_aa_req(void);
/*******************************************************************************
**
** Function btc_media_task_stop_aa_req
**
** Description Request to stop audio encoding task
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_stop_aa_req(void);
/*******************************************************************************
**
** Function btc_media_task_aa_rx_flush_req
**
** Description Request to flush audio decoding pipe
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_aa_rx_flush_req(void);
/*******************************************************************************
**
** Function btc_media_task_aa_tx_flush_req
**
** Description Request to flush audio encoding pipe
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_aa_tx_flush_req(void);
/*******************************************************************************
**
** Function btc_media_aa_readbuf
**
** Description Read an audio GKI buffer from the BTC media TX queue
**
** Returns pointer on a GKI aa buffer ready to send
**
*******************************************************************************/
extern BT_HDR *btc_media_aa_readbuf(void);
/*******************************************************************************
**
** Function btc_media_sink_enque_buf
**
** Description This function is called by the av_co to fill A2DP Sink Queue
**
**
** Returns size of the queue
*******************************************************************************/
UINT8 btc_media_sink_enque_buf(BT_HDR *p_buf);
/*******************************************************************************
**
** Function btc_media_aa_writebuf
**
** Description Enqueue a Advance Audio media GKI buffer to be processed by btc media task.
**
** Returns TRUE is success
**
*******************************************************************************/
extern void btc_media_aa_writebuf(BT_HDR *pBuf, UINT32 timestamp, UINT16 seq_num);
/*******************************************************************************
**
** Function btc_media_av_writebuf
**
** Description Enqueue a video media GKI buffer to be processed by btc media task.
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_av_writebuf(UINT8 *p_media, UINT32 media_len,
UINT32 timestamp, UINT16 seq_num);
#if (BTA_AV_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btc_media_task_audio_feeding_init_req
**
** Description Request to initialize audio feeding
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg);
#endif
/*******************************************************************************
**
** Function dump_codec_info
**
** Description Decode and display codec_info (for debug)
**
** Returns void
**
*******************************************************************************/
extern void dump_codec_info(unsigned char *p_codec);
/**
* Local adaptation helper functions between btc and media task
*/
bool btc_a2dp_start_media_task(void);
void btc_a2dp_stop_media_task(void);
void btc_a2dp_on_init(void);
void btc_a2dp_setup_codec(void);
void btc_a2dp_on_idle(void);
BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start);
void btc_a2dp_on_stop_req(void);
void btc_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
void btc_a2dp_on_suspend(void);
void btc_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
void btc_a2dp_set_rx_flush(BOOLEAN enable);
void btc_media_check_iop_exceptions(UINT8 *peer_bda);
void btc_reset_decoder(UINT8 *p_av);
int btc_a2dp_get_track_frequency(UINT8 frequency);
int btc_a2dp_get_track_channel_count(UINT8 channeltype);
void btc_a2dp_set_peer_sep(UINT8 sep);
#endif

View File

@ -1,125 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#include "esp_sdp_api.h"
esp_err_t esp_bt_sdp_enable(bt_sdp_cb_t *cback)
{
tBTA_SDP_STATUS status = BTA_SdpEnable((tBTA_SDP_DM_CBACK *)cback);
return (status == BTA_SDP_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_bt_sdp_search(esp_bd_addr_t bd_addr, esp_bt_uuid_t *uuid)
{
tBTA_SDP_STATUS status = BTA_SdpSearch(bd_addr, (tSDP_UUID *)uuid);
return (status == BTA_SDP_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_bt_sdp_create_record_by_user(void *user_data)
{
tBTA_SDP_STATUS status = BTA_SdpCreateRecordByUser(user_data);
return (status == BTA_SDP_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_bt_sdp_remove_record_by_user(void *user_data)
{
tBTA_SDP_STATUS status = BTA_SdpRemoveRecordByUser(user_data);
return (status == BTA_SDP_SUCCESS) ? ESP_OK : ESP_FAIL;
}
/**********************************************************************************************/
/**********************************************************************************************/
/* API into SDP for local service database updates */
/* these APIs are indended to be called in callback function in the context of stack task,
* to handle BT_SDP_CREATE_RECORD_USER_EVT and BT_SDP_REMOVE_RECORD_USER_EVT
*/
uint32_t esp_bt_sdp_create_record(void)
{
return SDP_CreateRecord();
}
bool esp_bt_sdp_delete_record(uint32_t handle)
{
return SDP_DeleteRecord(handle);
}
int32_t esp_bt_sdp_read_record(uint32_t handle, uint8_t *data, int32_t *data_len)
{
return SDP_ReadRecord(handle, data, data_len);
}
bool esp_bt_sdp_add_attribute (uint32_t handle, uint16_t attr_id,
uint8_t attr_type, uint32_t attr_len,
uint8_t *p_val)
{
return SDP_AddAttribute(handle, attr_id, attr_type, attr_len, p_val);
}
bool esp_bt_sdp_add_sequence (uint32_t handle, uint16_t attr_id,
uint16_t num_elem, uint8_t type[],
uint8_t len[], uint8_t *p_val[])
{
return SDP_AddSequence(handle, attr_id, num_elem, type, len, p_val);
}
bool esp_bt_sdp_add_uuid_sequence (uint32_t handle, uint16_t attr_id,
uint16_t num_uuids, uint16_t *p_uuids)
{
return SDP_AddUuidSequence(handle, attr_id, num_uuids, p_uuids);
}
bool esp_bt_sdp_add_protocol_list (uint32_t handle, uint16_t num_elem,
sdp_proto_elem_t *p_elem_list)
{
return SDP_AddProtocolList(handle, num_elem, (tSDP_PROTOCOL_ELEM *)p_elem_list);
}
bool esp_bt_sdp_add_addition_protocol_lists(uint32_t handle, uint16_t num_elem,
sdp_proto_list_elem_t *p_proto_list)
{
return SDP_AddAdditionProtoLists(handle, num_elem, (tSDP_PROTO_LIST_ELEM *)p_proto_list);
}
bool esp_bt_sdp_add_profile_dscp_list (uint32_t handle,
uint16_t profile_uuid,
uint16_t version)
{
return SDP_AddProfileDescriptorList(handle, profile_uuid, version);
}
bool esp_bt_sdp_add_lang_base_attr_id_list(uint32_t handle,
uint16_t lang, uint16_t char_enc,
uint16_t base_id)
{
return SDP_AddLanguageBaseAttrIDList(handle, lang, char_enc, base_id);
}
bool esp_bt_sdp_add_service_class_id_list(uint32_t handle,
uint16_t num_services,
uint16_t *p_service_uuids)
{
return SDP_AddServiceClassIdList(handle, num_services, p_service_uuids);
}
bool esp_bt_sdp_delete_attribute(uint32_t handle, uint16_t attr_id)
{
return SDP_DeleteAttribute(handle, attr_id);
}
/**********************************************************************************************/
/**********************************************************************************************/

View File

@ -1,129 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// 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 __ESP_SDP_API_H__
#define __ESP_SDP_API_H__
#include <stdint.h>
#include "esp_err.h"
#include "esp_bt_common.h"
#include "bta_sdp_api.h"
#include "bt_sdp.h"
#define BT_SDP_STAT_SUCCESS BTA_SDP_SUCCESS
#define BT_SDP_STAT_FAILURE BTA_SDP_FAILURE
#define BT_SDP_STAT_BUSY BTA_SDP_BUSY
#define BT_SDP_ENABLE_EVT BTA_SDP_ENABLE_EVT
#define BT_SDP_SEARCH_EVT BTA_SDP_SEARCH_EVT
#define BT_SDP_SEARCH_COMP_EVT BTA_SDP_SEARCH_COMP_EVT
#define BT_SDP_CREATE_RECORD_USER_EVT BTA_SDP_CREATE_RECORD_USER_EVT
#define BT_SDP_REMOVE_RECORD_USER_EVT BTA_SDP_REMOVE_RECORD_USER_EVT
#define BT_SDP_MAX_EVT BTA_SDP_MAX_EVT
#define BT_SDP_MAX_RECORDS BTA_SDP_MAX_RECORDS
typedef tBTA_SDP_STATUS bt_sdp_status_t;
typedef tBTA_SDP_EVT bt_sdp_evt_t;
typedef bluetooth_sdp_record bt_sdp_record_t;
/* tBTA_SEARCH_COMP, bta_sdp_api.h */
typedef struct {
bt_sdp_status_t status;
esp_bd_addr_t remote_addr;
esp_bt_uuid_t uuid;
int record_count;
bt_sdp_record_t records[BT_SDP_MAX_RECORDS];
} bt_sdp_search_comp_t;
/* tBTA_SDP, bta_sdp_api.h */
typedef union {
bt_sdp_status_t status;
bt_sdp_search_comp_t sdp_search_comp;
} bt_sdp_t;
typedef void (bt_sdp_cb_t)(bt_sdp_evt_t event, bt_sdp_t *p_data, void *user_data);
esp_err_t esp_bt_sdp_enable(bt_sdp_cb_t *cback);
esp_err_t esp_bt_sdp_search(esp_bd_addr_t bd_addr, esp_bt_uuid_t *uuid);
esp_err_t esp_bt_sdp_create_record_by_user(void *user_data);
esp_err_t esp_bt_sdp_remove_record_by_user(void *user_data);
/**********************************************************************************************/
/**********************************************************************************************/
/* API into SDP for local service database updates
* these APIs are indended to be called in callback function in the context of stack task,
* to handle BT_SDP_CREATE_RECORD_USER_EVT and BT_SDP_REMOVE_RECORD_USER_EVT
*/
/* This structure is used to add protocol lists and find protocol elements */
#define ESP_BT_SDP_MAX_PROTOCOL_PARAMS SDP_MAX_PROTOCOL_PARAMS // bt_target.h
typedef struct {
uint16_t protocol_uuid;
uint16_t num_params;
uint16_t params[ESP_BT_SDP_MAX_PROTOCOL_PARAMS];
} sdp_proto_elem_t; // tSDP_PROTOCOL_ELEM, sdp_api.h
#define ESP_BT_SDP_MAX_LIST_ELEMS SDP_MAX_LIST_ELEMS // sdp_api.h
typedef struct {
uint16_t num_elems;
sdp_proto_elem_t list_elem[ESP_BT_SDP_MAX_LIST_ELEMS];
} sdp_proto_list_elem_t; // tSDP_PROTO_LIST_ELEM, sdp_api.h
uint32_t esp_bt_sdp_create_record(void);
bool esp_bt_sdp_delete_record(uint32_t handle);
int32_t esp_bt_sdp_read_record(uint32_t handle, uint8_t *data, int32_t *data_len);
bool esp_bt_sdp_add_attribute (uint32_t handle, uint16_t attr_id,
uint8_t attr_type, uint32_t attr_len,
uint8_t *p_val);
bool esp_bt_sdp_add_sequence (uint32_t handle, uint16_t attr_id,
uint16_t num_elem, uint8_t type[],
uint8_t len[], uint8_t *p_val[]);
bool esp_bt_sdp_add_uuid_sequence (uint32_t handle, uint16_t attr_id,
uint16_t num_uuids, uint16_t *p_uuids);
bool esp_bt_sdp_add_protocol_list (uint32_t handle, uint16_t num_elem,
sdp_proto_elem_t *p_elem_list);
bool esp_bt_sdp_add_addition_protocol_lists(uint32_t handle, uint16_t num_elem,
sdp_proto_list_elem_t *p_proto_list);
bool esp_bt_sdp_add_profile_dscp_list (uint32_t handle,
uint16_t profile_uuid,
uint16_t version);
bool esp_bt_sdp_add_lang_base_attr_id_list(uint32_t handle,
uint16_t lang, uint16_t char_enc,
uint16_t base_id);
bool esp_bt_sdp_add_service_class_id_list(uint32_t handle,
uint16_t num_services,
uint16_t *p_service_uuids);
bool esp_bt_sdp_delete_attribute(uint32_t handle, uint16_t attr_id);
#endif /* __ESP_SDP_API_H__ */

0
components/bt/bluedroid/btcore/include/bdaddr.h Executable file → Normal file
View File

View File

@ -0,0 +1,86 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_ASSERT_H
#define _OI_ASSERT_H
/** @file
This file provides macros and functions for compile-time and run-time assertions.
When the OI_DEBUG preprocessor value is defined, the macro OI_ASSERT is compiled into
the program, providing for a runtime assertion failure check.
C_ASSERT is a macro that can be used to perform compile time checks.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** \addtogroup Debugging Debugging APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OI_DEBUG
/** The macro OI_ASSERT takes a condition argument. If the asserted condition
does not evaluate to true, the OI_ASSERT macro calls the host-dependent function,
OI_AssertFail(), which reports the failure and generates a runtime error.
*/
void OI_AssertFail(char *file, int line, char *reason);
#define OI_ASSERT(condition) \
{ if (!(condition)) OI_AssertFail(__FILE__, __LINE__, #condition); }
#define OI_ASSERT_FAIL(msg) \
{ OI_AssertFail(__FILE__, __LINE__, msg); }
#else
#define OI_ASSERT(condition)
#define OI_ASSERT_FAIL(msg)
#endif
/**
C_ASSERT() can be used to perform many compile-time assertions: type sizes, field offsets, etc.
An assertion failure results in compile time error C2118: negative subscript.
Unfortunately, this elegant macro doesn't work with GCC, so it's all commented out
for now. Perhaps later.....
*/
#ifndef C_ASSERT
// #define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
// #define C_ASSERT(e)
#endif
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_ASSERT_H */

View File

@ -0,0 +1,123 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_BITSTREAM_H
#define _OI_BITSTREAM_H
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Function prototypes and macro definitions for manipulating input and output
bitstreams.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "oi_codec_sbc_private.h"
#include "oi_stddefs.h"
INLINE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs, const OI_BYTE *buffer);
INLINE void OI_BITSTREAM_WriteInit(OI_BITSTREAM *bs, OI_BYTE *buffer);
INLINE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits);
INLINE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs);
INLINE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs);
INLINE void OI_BITSTREAM_WriteUINT(OI_BITSTREAM *bs,
OI_UINT16 value,
OI_UINT bits);
/*
* Use knowledge that the bitstream is aligned to optimize the write of a byte
*/
PRIVATE void OI_BITSTREAM_WriteUINT8Aligned(OI_BITSTREAM *bs,
OI_UINT8 datum);
/*
* Use knowledge that the bitstream is aligned to optimize the write pair of nibbles
*/
PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM *bs,
OI_UINT8 datum1,
OI_UINT8 datum2);
/** Internally the bitstream looks ahead in the stream. When
* OI_SBC_ReadScalefactors() goes to temporarily break the abstraction, it will
* need to know where the "logical" pointer is in the stream.
*/
#define OI_BITSTREAM_GetWritePtr(bs) ((bs)->ptr.w - 3)
#define OI_BITSTREAM_GetReadPtr(bs) ((bs)->ptr.r - 3)
/** This is declared here as a macro because decoder.c breaks the bitsream
* encapsulation for efficiency reasons.
*/
#define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \
do { \
OI_ASSERT((bits) <= 16); \
OI_ASSERT((bitPtr) < 16); \
OI_ASSERT((bitPtr) >= 8); \
\
result = (value) << (bitPtr); \
result >>= 32 - (bits); \
\
bitPtr += (bits); \
while (bitPtr >= 16) { \
value = ((value) << 8) | *ptr++; \
bitPtr -= 8; \
} \
OI_ASSERT((bits == 0) || (result < (1u << (bits)))); \
} while (0)
#define OI_BITSTREAM_WRITEUINT(ptr, value, bitPtr, datum, bits) \
do {\
bitPtr -= bits;\
value |= datum << bitPtr;\
\
while (bitPtr <= 16) {\
bitPtr += 8;\
*ptr++ = (OI_UINT8)(value >> 24);\
value <<= 8;\
}\
} while (0)
#define OI_BITSTREAM_WRITEFLUSH(ptr, value, bitPtr) \
do {\
while (bitPtr < 32) {\
bitPtr += 8;\
*ptr++ = (OI_UINT8)(value >> 24);\
value <<= 8;\
}\
} while (0)
/**
@}
*/
#endif /* _OI_BITSTREAM_H */

View File

@ -0,0 +1,229 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_BT_SPEC_H
#define _OI_BT_SPEC_H
/**
* @file
*
* This file contains common definitions from the Bluetooth specification.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/** The maximum number of active slaves in a piconet. */
#define OI_BT_MAX_ACTIVE_SLAVES 7
/** the number of bytes in a Bluetooth device address (BD_ADDR) */
#define OI_BD_ADDR_BYTE_SIZE 6
/**
* 48-bit Bluetooth device address
*
* Because 48-bit integers may not be supported on all platforms, the
* address is defined as an array of bytes. This array is big-endian,
* meaning that
* - array[0] contains bits 47-40,
* - array[1] contains bits 39-32,
* - array[2] contains bits 31-24,
* - array[3] contains bits 23-16,
* - array[4] contains bits 15-8, and
* - array[5] contains bits 7-0.
*/
typedef struct {
OI_UINT8 addr[OI_BD_ADDR_BYTE_SIZE] ; /**< Bluetooth device address represented as an array of 8-bit values */
} OI_BD_ADDR ;
/**
* @name Data types for working with UUIDs
* UUIDs are 16 bytes (128 bits).
*
* To avoid having to pass around 128-bit values all the time, 32-bit and 16-bit
* UUIDs are defined, along with a mapping from the shorter versions to the full
* version.
*
* @{
*/
/**
* 16-bit representation of a 128-bit UUID
*/
typedef OI_UINT16 OI_UUID16;
/**
* 32-bit representation of a 128-bit UUID
*/
typedef OI_UINT32 OI_UUID32;
/**
* number of bytes in a 128 bit UUID
*/
#define OI_BT_UUID128_SIZE 16
/**
* number of bytes in IPv6 style addresses
*/
#define OI_BT_IPV6ADDR_SIZE 16
/**
* type definition for a 128-bit UUID
*
* To simplify conversion between 128-bit UUIDs and 16-bit and 32-bit UUIDs,
* the most significant 32 bits are stored with the same endian-ness as is
* native on the target (local) device. The remainder of the 128-bit UUID is
* stored as bytes in big-endian order.
*/
typedef struct {
OI_UINT32 ms32bits; /**< most significant 32 bits of 128-bit UUID */
OI_UINT8 base[OI_BT_UUID128_SIZE - sizeof(OI_UINT32)]; /**< remainder of 128-bit UUID, array of 8-bit values */
} OI_UUID128;
/** @} */
/** number of bytes in a link key */
#define OI_BT_LINK_KEY_SIZE 16
/**
* type definition for a baseband link key
*
* Because 128-bit integers may not be supported on all platforms, we define
* link keys as an array of bytes. Unlike the Bluetooth device address,
* the link key is stored in little-endian order, meaning that
* - array[0] contains bits 0 - 7,
* - array[1] contains bits 8 - 15,
* - array[2] contains bits 16 - 23,
* - array[3] contains bits 24 - 31,
* - array[4] contains bits 32 - 39,
* - array[5] contains bits 40 - 47,
* - array[6] contains bits 48 - 55,
* - array[7] contains bits 56 - 63,
* - array[8] contains bits 64 - 71,
* - array[9] contains bits 72 - 79,
* - array[10] contains bits 80 - 87,
* - array[11] contains bits 88 - 95,
* - array[12] contains bits 96 - 103,
* - array[13] contains bits 104- 111,
* - array[14] contains bits 112- 119, and
* - array[15] contains bits 120- 127.
*/
typedef struct {
OI_UINT8 key[OI_BT_LINK_KEY_SIZE] ; /**< link key represented as an array of 8-bit values */
} OI_LINK_KEY ;
/** Out-of-band data size - C and R values are 16-bytes each */
#define OI_BT_OOB_NUM_BYTES 16
typedef struct {
OI_UINT8 value[OI_BT_OOB_NUM_BYTES] ; /**< same struct used for C and R values */
} OI_OOB_DATA ;
/**
* link key types
*/
typedef enum {
OI_LINK_KEY_TYPE_COMBO = 0, /**< combination key */
OI_LINK_KEY_TYPE_LOCAL_UNIT = 1, /**< local unit key */
OI_LINK_KEY_TYPE_REMOTE_UNIT = 2, /**< remote unit key */
OI_LINK_KEY_TYPE_DEBUG_COMBO = 3, /**< debug combination key */
OI_LINK_KEY_TYPE_UNAUTHENTICATED = 4, /**< Unauthenticated */
OI_LINK_KEY_TYPE_AUTHENTICATED = 5, /**< Authenticated */
OI_LINK_KEY_TYPE_CHANGED_COMBO = 6 /**< Changed */
} OI_BT_LINK_KEY_TYPE ;
/** amount of space allocated for a PIN (personal indentification number) in bytes */
#define OI_BT_PIN_CODE_SIZE 16
/** data type for a PIN (PINs are treated as strings, so endianness does not apply.) */
typedef struct {
OI_UINT8 pin[OI_BT_PIN_CODE_SIZE] ; /**< PIN represented as an array of 8-bit values */
} OI_PIN_CODE ;
/** maximum number of SCO connections per device, which is 3 as of version 2.0+EDR
of the Bluetooth specification (see sec 4.3 of vol 2 part B) */
#define OI_BT_MAX_SCO_CONNECTIONS 3
/** data type for clock offset */
typedef OI_UINT16 OI_BT_CLOCK_OFFSET ;
/** data type for a LM handle */
typedef OI_UINT16 OI_HCI_LM_HANDLE;
/** opaque data type for a SCO or ACL connection handle */
typedef struct _OI_HCI_CONNECTION *OI_HCI_CONNECTION_HANDLE;
/** data type for HCI Error Code, as defined in oi_hcispec.h */
typedef OI_UINT8 OI_HCI_ERROR_CODE ;
/**
* The Bluetooth device type is indicated by a 24-bit bitfield, represented as a
* 32-bit number in the stack. The bit layout and values for device class are specified
* in the file oi_bt_assigned_nos.h and in the Bluetooth "Assigned Numbers" specification
* at http://www.bluetooth.org/assigned-numbers/.
*/
typedef OI_UINT32 OI_BT_DEVICE_CLASS ;
#define OI_BT_DEV_CLASS_FORMAT_MASK 0x000003 /**< Bits 0-1 contain format type. */
#define OI_BT_DEV_CLASS_MINOR_DEVICE_MASK 0x0000FC /**< Bits 2-7 contain minor device class value. */
#define OI_BT_DEV_CLASS_MAJOR_DEVICE_MASK 0x001F00 /**< Bits 8-12 contain major device class value. */
#define OI_BT_DEV_CLASS_MAJOR_SERVICE_MASK 0xFFE000 /**< Bits 13-23 contain major service class value. */
/** There is currently only one device class format defined, type 00. */
#define OI_BT_DEV_CLASS_FORMAT_TYPE 00
/** Bit 13 in device class indicates limited discoverability mode (GAP v2.0+EDR, section 4.1.2.2) */
#define OI_BT_DEV_CLASS_LIMITED_DISCO_BIT BIT13
/** macro to test validity of the Device Class Format */
#define OI_BT_VALID_DEVICE_CLASS_FORMAT(class) (OI_BT_DEV_CLASS_FORMAT_TYPE == ((class) & OI_BT_DEV_CLASS_FORMAT_MASK))
/** the time between baseband clock ticks, currently 625 microseconds (one slot) */
#define OI_BT_TICK 625
/** some macros to convert to/from baseband clock ticks - use no floating point! */
#define OI_SECONDS_TO_BT_TICKS(secs) ((secs)*1600)
#define OI_BT_TICKS_TO_SECONDS(ticks) ((ticks)/1600)
#define OI_MSECS_TO_BT_TICKS(msecs) (((msecs)*8)/5)
#define OI_BT_TICKS_TO_MSECS(ticks) (((ticks)*5)/8)
/** EIR byte order */
#define OI_EIR_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#ifdef __cplusplus
}
#endif
/**@}*/
/*****************************************************************************/
#endif /* _OI_BT_SPEC_H */

View File

@ -0,0 +1,484 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#ifndef _OI_CODEC_SBC_CORE_H
#define _OI_CODEC_SBC_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
@file
Declarations of codec functions, data types, and macros.
@ingroup codec_lib
*/
/**
@addtogroup codec_lib
@{
*/
/* Non-BM3 users of of the codec must include oi_codec_sbc_bm3defs.h prior to
* including this file, or else these includes will fail because the BM3 SDK is
* not in the include path */
#ifndef _OI_CODEC_SBC_BM3DEFS_H
#include "oi_stddefs.h"
#include "oi_status.h"
#endif
#include <stdint.h>
#define SBC_MAX_CHANNELS 2
#define SBC_MAX_BANDS 8
#define SBC_MAX_BLOCKS 16
#define SBC_MIN_BITPOOL 2 /**< Minimum size of the bit allocation pool used to encode the stream */
#define SBC_MAX_BITPOOL 250 /**< Maximum size of the bit allocation pool used to encode the stream */
#define SBC_MAX_ONE_CHANNEL_BPS 320000
#define SBC_MAX_TWO_CHANNEL_BPS 512000
#define SBC_WBS_BITRATE 62000
#define SBC_WBS_BITPOOL 27
#define SBC_WBS_NROF_BLOCKS 16
#define SBC_WBS_FRAME_LEN 62
#define SBC_WBS_SAMPLES_PER_FRAME 128
#define SBC_HEADER_LEN 4
#define SBC_MAX_FRAME_LEN (SBC_HEADER_LEN + \
((SBC_MAX_BANDS * SBC_MAX_CHANNELS / 2) + \
(SBC_MAX_BANDS + SBC_MAX_BLOCKS * SBC_MAX_BITPOOL + 7)/8))
#define SBC_MAX_SAMPLES_PER_FRAME (SBC_MAX_BANDS * SBC_MAX_BLOCKS)
#define SBC_MAX_SCALEFACTOR_BYTES ((4*(SBC_MAX_CHANNELS * SBC_MAX_BANDS) + 7)/8)
#define OI_SBC_SYNCWORD 0x9c
#define OI_SBC_ENHANCED_SYNCWORD 0x9d
/**@name Sampling frequencies */
/**@{*/
#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_32000 1 /**< The sampling frequency is 32 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_44100 2 /**< The sampling frequency is 44.1 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_FREQ_48000 3 /**< The sampling frequency is 48 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Channel modes */
/**@{*/
#define SBC_MONO 0 /**< The mode of the encoded channel is mono. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_DUAL_CHANNEL 1 /**< The mode of the encoded channel is dual-channel. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_STEREO 2 /**< The mode of the encoded channel is stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_JOINT_STEREO 3 /**< The mode of the encoded channel is joint stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Subbands */
/**@{*/
#define SBC_SUBBANDS_4 0 /**< The encoded stream has 4 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure()*/
#define SBC_SUBBANDS_8 1 /**< The encoded stream has 8 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Block lengths */
/**@{*/
#define SBC_BLOCKS_4 0 /**< A block size of 4 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_8 1 /**< A block size of 8 blocks was used to encode the stream is. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_12 2 /**< A block size of 12 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_BLOCKS_16 3 /**< A block size of 16 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**@name Bit allocation methods */
/**@{*/
#define SBC_LOUDNESS 0 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
#define SBC_SNR 1 /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
/**@}*/
/**
@}
@addtogroup codec_internal
@{
*/
typedef OI_INT16 SBC_BUFFER_T;
/** Used internally. */
typedef struct {
OI_UINT16 frequency; /**< The sampling frequency. Input parameter. */
OI_UINT8 freqIndex;
OI_UINT8 nrof_blocks; /**< The block size used to encode the stream. Input parameter. */
OI_UINT8 blocks;
OI_UINT8 nrof_subbands; /**< The number of subbands of the encoded stream. Input parameter. */
OI_UINT8 subbands;
OI_UINT8 mode; /**< The mode of the encoded channel. Input parameter. */
OI_UINT8 nrof_channels; /**< The number of channels of the encoded stream. */
OI_UINT8 alloc; /**< The bit allocation method. Input parameter. */
OI_UINT8 bitpool; /**< Size of the bit allocation pool used to encode the stream. Input parameter. */
OI_UINT8 crc; /**< Parity check byte used for error detection. */
OI_UINT8 join; /**< Whether joint stereo has been used. */
OI_UINT8 enhanced;
OI_UINT8 min_bitpool; /**< This value is only used when encoding. SBC_MAX_BITPOOL if variable
bitpools are disallowed, otherwise the minimum bitpool size that will
be used by the bit allocator. */
OI_UINT8 cachedInfo; /**< Information about the previous frame */
} OI_CODEC_SBC_FRAME_INFO;
/** Used internally. */
typedef struct {
const OI_CHAR *codecInfo;
OI_CODEC_SBC_FRAME_INFO frameInfo;
OI_INT8 scale_factor[SBC_MAX_CHANNELS * SBC_MAX_BANDS];
OI_UINT32 frameCount;
OI_INT32 *subdata;
SBC_BUFFER_T *filterBuffer[SBC_MAX_CHANNELS];
OI_INT32 filterBufferLen;
OI_UINT filterBufferOffset;
union {
OI_UINT8 uint8[SBC_MAX_CHANNELS * SBC_MAX_BANDS];
OI_UINT32 uint32[SBC_MAX_CHANNELS * SBC_MAX_BANDS / 4];
} bits;
OI_UINT8 maxBitneed; /**< Running maximum bitneed */
OI_BYTE formatByte;
OI_UINT8 pcmStride;
OI_UINT8 maxChannels;
} OI_CODEC_SBC_COMMON_CONTEXT;
/*
* A smaller value reduces RAM usage at the expense of increased CPU usage. Values in the range
* 27..50 are recommended, beyond 50 there is a diminishing return on reduced CPU usage.
*/
#define SBC_CODEC_MIN_FILTER_BUFFERS 16
#define SBC_CODEC_FAST_FILTER_BUFFERS 27
/* Expands to the number of OI_UINT32s needed to ensure enough memory to encode
* or decode streams of numChannels channels, using numBuffers buffers.
* Example:
* OI_UINT32 decoderData[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_DECODER_FAST_SYNTHESIS_BUFFERS)];
* */
#define CODEC_DATA_WORDS(numChannels, numBuffers) \
((\
(sizeof(OI_INT32) * SBC_MAX_BLOCKS * numChannels * SBC_MAX_BANDS) \
+ (sizeof(SBC_BUFFER_T) * SBC_MAX_CHANNELS * SBC_MAX_BANDS * numBuffers) \
+ (sizeof (OI_UINT32) - 1) \
) / sizeof(OI_UINT32))
/** Opaque parameter to decoding functions; maintains decoder context. */
typedef struct {
OI_CODEC_SBC_COMMON_CONTEXT common;
OI_UINT8 limitFrameFormat; /* Boolean, set by OI_CODEC_SBC_DecoderLimit() */
OI_UINT8 restrictSubbands;
OI_UINT8 enhancedEnabled;
OI_UINT8 bufferedBlocks;
} OI_CODEC_SBC_DECODER_CONTEXT;
typedef struct {
OI_UINT32 data[CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS)];
} OI_CODEC_SBC_CODEC_DATA_MONO;
typedef struct {
OI_UINT32 data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
} OI_CODEC_SBC_CODEC_DATA_STEREO;
/**
@}
@addtogroup codec_lib
@{
*/
/**
* This function resets the decoder. The context must be reset when
* changing streams, or if the following stream parameters change:
* number of subbands, stereo mode, or frequency.
*
* @param context Pointer to the decoder context structure to be reset.
*
* @param enhanced If true, enhanced SBC operation is enabled. If enabled,
* the codec will recognize the alternative syncword for
* decoding an enhanced SBC stream. Enhancements should not
* be enabled unless the stream is known to be generated
* by an enhanced encoder, or there is a small possibility
* for decoding glitches if synchronization were to be lost.
*/
OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride,
OI_BOOL enhanced);
/**
* This function restricts the kind of SBC frames that the Decoder will
* process. Its use is optional. If used, it must be called after
* calling OI_CODEC_SBC_DecoderReset(). After it is called, any calls
* to OI_CODEC_SBC_DecodeFrame() with SBC frames that do not conform
* to the Subband and Enhanced SBC setting will be rejected with an
* OI_STATUS_INVALID_PARAMETERS return.
*
* @param context Pointer to the decoder context structure to be limited.
*
* @param enhanced If true, all frames passed to the decoder must be
* Enhanced SBC frames. If false, all frames must be
* standard SBC frames.
*
* @param subbands May be set to SBC_SUBBANDS_4 or SBC_SUBBANDS_8. All
* frames passed to the decoder must be encoded with
* the requested number of subbands.
*
*/
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 subbands);
/**
* This function sets the decoder parameters for a raw decode where the decoder parameters are not
* available in the sbc data stream. OI_CODEC_SBC_DecoderReset must be called
* prior to calling this function.
*
* @param context Decoder context structure. This must be the context must be
* used each time a frame is decoded.
*
* @param enhanced Set to TRUE to enable Qualcomm proprietary
* quality enhancements.
*
* @param frequency One of SBC_FREQ_16000, SBC_FREQ_32000, SBC_FREQ_44100,
* SBC_FREQ_48000
*
* @param mode One of SBC_MONO, SBC_DUAL_CHANNEL, SBC_STEREO,
* SBC_JOINT_STEREO
*
* @param subbands One of SBC_SUBBANDS_4, SBC_SUBBANDS_8
*
* @param blocks One of SBC_BLOCKS_4, SBC_BLOCKS_8, SBC_BLOCKS_12,
* SBC_BLOCKS_16
*
* @param alloc One of SBC_LOUDNESS, SBC_SNR
*
* @param maxBitpool The maximum bitpool size for this context
*/
OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 frequency,
OI_UINT8 mode,
OI_UINT8 subbands,
OI_UINT8 blocks,
OI_UINT8 alloc,
OI_UINT8 maxBitpool);
/**
* Decode one SBC frame. The frame has no header bytes. The context must have been previously
* initialized by calling OI_CODEC_SBC_DecoderConfigureRaw().
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param bitpool The actual bitpool size for this frame. Must be <= the maxbitpool specified
* in the call to OI_CODEC_SBC_DecoderConfigureRaw(),
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
* @param pcmData Address of an array of OI_INT16 pairs, which will be
* populated with the decoded audio data. This address
* is not updated.
*
* @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it
* should contain the number of bytes available for pcm
* data. On output, it will contain the number of bytes
* written. Note that this differs from the semantics of
* frameBytes.
*/
OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
/**
* Decode one SBC frame.
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
* @param pcmData Address of an array of OI_INT16 pairs, which will be
* populated with the decoded audio data. This address
* is not updated.
*
* @param pcmBytes Pointer to a UINT32 in/out parameter. On input, it
* should contain the number of bytes available for pcm
* data. On output, it will contain the number of bytes
* written. Note that this differs from the semantics of
* frameBytes.
*/
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
/**
* Calculate the number of SBC frames but don't decode. CRC's are not checked,
* but the Sync word is found prior to count calculation.
*
* @param frameData Pointer to the SBC data.
*
* @param frameBytes Number of bytes avaiable in the frameData buffer
*
*/
OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData,
OI_UINT32 frameBytes);
/**
* Analyze an SBC frame but don't do the decode.
*
* @param context Pointer to a decoder context structure. The same context
* must be used each time when decoding from the same stream.
*
* @param frameData Address of a pointer to the SBC data to decode. This
* value will be updated to point to the next frame after
* successful decoding.
*
* @param frameBytes Pointer to a UINT32 containing the number of available
* bytes of frame data. This value will be updated to reflect
* the number of bytes remaining after a decoding operation.
*
*/
OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes);
/* Common functions */
/**
Calculate the frame length.
@param frame The frame whose length to calculate
@return the length of an individual encoded frame in
bytes
*/
OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
/**
* Calculate the maximum bitpool size that fits within a given frame length.
*
* @param frame The frame to calculate the bitpool size for
* @param frameLen The frame length to fit the bitpool to
*
* @return the maximum bitpool that will fit in the specified frame length
*/
OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
OI_UINT16 frameLen);
/**
Calculate the bit rate.
@param frame The frame whose bit rate to calculate
@return the approximate bit rate in bits per second,
assuming that stream parameters are constant
*/
OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
/**
Calculate decoded audio data length for one frame.
@param frame The frame whose audio data length to calculate
@return length of decoded audio data for a
single frame, in bytes
*/
OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common);
/**
* Get the codec version text.
*
* @return pointer to text string containing codec version text
*
*/
OI_CHAR *OI_CODEC_Version(void);
/**
@}
@addtogroup codec_internal
@{
*/
extern const OI_CHAR *const OI_CODEC_SBC_FreqText[];
extern const OI_CHAR *const OI_CODEC_SBC_ModeText[];
extern const OI_CHAR *const OI_CODEC_SBC_SubbandsText[];
extern const OI_CHAR *const OI_CODEC_SBC_BlocksText[];
extern const OI_CHAR *const OI_CODEC_SBC_AllocText[];
/**
@}
@addtogroup codec_lib
@{
*/
#ifdef OI_DEBUG
void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo);
#else
#define OI_CODEC_SBC_DumpConfig(f)
#endif
/**
@}
*/
#ifdef __cplusplus
}
#endif
#endif /* _OI_CODEC_SBC_CORE_H */

View File

@ -0,0 +1,229 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_CODEC_SBC_PRIVATE_H
#define _OI_CODEC_SBC_PRIVATE_H
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Function prototypes and macro definitions used internally by the codec.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#ifdef USE_RESTRICT_KEYWORD
#define RESTRICT restrict
#else
#define RESTRICT
#endif
#ifdef CODEC_DEBUG
#include <stdio.h>
#define ERROR(x) do { printf x; printf("\n"); } while (0)
#else
#define ERROR(x)
#endif
#ifdef TRACE_EXECUTION
#define TRACE(x) do { printf x; printf("\n"); } while (0)
#else
#define TRACE(x)
#endif
#ifndef PRIVATE
#define PRIVATE
#endif
#ifndef INLINE
#define INLINE
#endif
#include "oi_assert.h"
#include "oi_codec_sbc.h"
#ifndef OI_SBC_SYNCWORD
#define OI_SBC_SYNCWORD 0x9c
#endif
#ifndef DIVIDE
#define DIVIDE(a, b) ((a) / (b))
#endif
typedef union {
OI_UINT8 uint8[SBC_MAX_BANDS];
OI_UINT32 uint32[SBC_MAX_BANDS / 4];
} BITNEED_UNION1;
typedef union {
OI_UINT8 uint8[2 * SBC_MAX_BANDS];
OI_UINT32 uint32[2 * SBC_MAX_BANDS / 4];
} BITNEED_UNION2;
static const OI_UINT16 freq_values[] = { 16000, 32000, 44100, 48000 };
static const OI_UINT8 block_values[] = { 4, 8, 12, 16 };
static const OI_UINT8 channel_values[] = { 1, 2, 2, 2 };
static const OI_UINT8 band_values[] = { 4, 8 };
#define TEST_MODE_SENTINEL "OINA"
#define TEST_MODE_SENTINEL_LENGTH 4
/** Used internally. */
typedef struct {
union {
const OI_UINT8 *r;
OI_UINT8 *w;
} ptr;
OI_UINT32 value;
OI_UINT bitPtr;
} OI_BITSTREAM;
#define VALID_INT16(x) (((x) >= OI_INT16_MIN) && ((x) <= OI_INT16_MAX))
#define VALID_INT32(x) (((x) >= OI_INT32_MIN) && ((x) <= OI_INT32_MAX))
#define DCTII_8_SHIFT_IN 0
#define DCTII_8_SHIFT_OUT 16-DCTII_8_SHIFT_IN
#define DCTII_8_SHIFT_0 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_1 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_2 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_3 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_4 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_5 (DCTII_8_SHIFT_OUT)
#define DCTII_8_SHIFT_6 (DCTII_8_SHIFT_OUT-1)
#define DCTII_8_SHIFT_7 (DCTII_8_SHIFT_OUT-2)
#define DCT_SHIFT 15
#define DCTIII_4_SHIFT_IN 2
#define DCTIII_4_SHIFT_OUT 15
#define DCTIII_8_SHIFT_IN 3
#define DCTIII_8_SHIFT_OUT 14
OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT8 *bitneeds,
OI_UINT ch,
OI_UINT *preferredBitpool);
void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
BITNEED_UNION1 *bitneeds,
OI_UINT ch,
OI_UINT bitcount);
OI_INT adjustToFitBitpool(const OI_UINT bitpool,
OI_UINT32 *bitneeds,
const OI_UINT subbands,
OI_UINT bitcount,
OI_UINT *excess);
INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
OI_INT bits,
OI_INT excess);
INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
OI_INT excess);
PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common);
typedef void (*BIT_ALLOC)(OI_CODEC_SBC_COMMON_CONTEXT *common);
PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes);
INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_BYTE maxChannels,
OI_BYTE pcmStride,
OI_BOOL enhanced);
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_);
PRIVATE OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *frame);
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data);
/* Transform functions */
PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount);
PRIVATE void cosineModulateSynth4(SBC_BUFFER_T *RESTRICT out, OI_INT32 const *RESTRICT in);
PRIVATE void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift);
INLINE void dct3_4(OI_INT32 *RESTRICT out, OI_INT32 const *RESTRICT in);
PRIVATE void analyze4_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 40],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[4]);
INLINE void dct3_8(OI_INT32 *RESTRICT out, OI_INT32 const *RESTRICT in);
PRIVATE void analyze8_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 80],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[8]);
#ifdef SBC_ENHANCED
PRIVATE void analyze8_enhanced_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 112],
OI_INT16 *pcm,
OI_UINT strideShift,
OI_INT32 subband[8]);
#endif
/* Decoder functions */
INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data);
PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *b, OI_BITSTREAM *bs);
PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *ob);
PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *global_bs);
PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks);
INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits);
PRIVATE OI_BOOL OI_SBC_ExamineCommandPacket(OI_CODEC_SBC_DECODER_CONTEXT *context, const OI_BYTE *data, OI_UINT32 len);
PRIVATE void OI_SBC_GenerateTestSignal(OI_INT16 pcmData[][2], OI_UINT32 sampleCount);
PRIVATE void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame);
PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT32 *codecDataAligned,
OI_UINT32 codecDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride);
/**
@}
*/
#endif /* _OI_CODEC_SBC_PRIVATE_H */

View File

@ -0,0 +1,43 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_COMMON_H
#define _OI_COMMON_H
/**
* @file
*
* This file is used to group commonly used BLUEmagic 3.0 software
* header files.
*
* This file should be included in application source code along with the header
* files for the specific modules of the protocol stack being used.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_bt_spec.h"
#include "oi_stddefs.h"
#include "oi_status.h"
#include "oi_time.h"
#include "oi_osinterface.h"
/*****************************************************************************/
#endif /* _OI_COMMON_H */

View File

@ -0,0 +1,505 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_CPU_DEP_H
#define _OI_CPU_DEP_H
/**
* @file
* This file contains definitions for characteristics of the target CPU and
* compiler, including primitive data types and endianness.
*
* This file defines the byte order and primitive data types for various
* CPU families. The preprocessor symbol 'CPU' must be defined to be an
* appropriate value or this header will generate a compile-time error.
*
* @note The documentation for this header file uses the x86 family of processors
* as an illustrative example for CPU/compiler-dependent data type definitions.
* Go to the source code of this header file to see the details of primitive type
* definitions for each platform.
*
* Additional information is available in the @ref data_types_docpage section.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
/** @name Definitions indicating family of target OI_CPU_TYPE
* @{
*/
#define OI_CPU_X86 1 /**< x86 processor family */
#define OI_CPU_ARM 2 /**< ARM processor family.
@deprecated Use #OI_CPU_ARM7_LEND or
#OI_CPU_ARM7_BEND. */
#define OI_CPU_ARC 3 /**< ARC processor family.
@deprecated Use #OI_CPU_ARC_LEND or
#OI_CPU_ARC_BEND. */
#define OI_CPU_SH3 4 /**< Hitachi SH-3 processor family */
#define OI_CPU_H8 5 /**< Hitachi H8 processor family */
#define OI_CPU_MIPS 6 /**< MIPS processor family */
#define OI_CPU_SPARC 7 /**< SPARC processor family */
#define OI_CPU_M68000 8 /**< Motorola M68000 processor family */
#define OI_CPU_PPC 9 /**< PowerPC (PPC) processor family */
#define OI_CPU_SH4_7750 10 /**< Hitachi SH7750 series in SH-4 processor family */
#define OI_CPU_SH2 11 /**< Hitachi SH-2 processor family */
#define OI_CPU_ARM7_LEND 12 /**< ARM7, little-endian */
#define OI_CPU_ARM7_BEND 13 /**< ARM7, big-endian */
#define OI_CPU_GDM1202 14 /**< GCT GDM1202 */
#define OI_CPU_ARC_LEND 15 /**< ARC processor family, little-endian */
#define OI_CPU_ARC_BEND 16 /**< ARC processor family, big-endian */
#define OI_CPU_M30833F 17 /**< Mitsubishi M308 processor family */
#define OI_CPU_CR16C 18 /**< National Semiconductor 16 bit processor family */
#define OI_CPU_M64111 19 /**< Renesas M64111 processor (M32R family) */
#define OI_CPU_ARMV5_LEND 20 //*< ARM5, little-endian */
#define OI_CPU_TYPE 12
#ifndef OI_CPU_TYPE
#error "OI_CPU_TYPE type not defined"
#endif
/**@}*/
/** @name Definitions indicating byte-wise endianness of target CPU
* @{
*/
#define OI_BIG_ENDIAN_BYTE_ORDER 0 /**< Multiple-byte values are stored in memory beginning with the most significant byte at the lowest address. */
#define OI_LITTLE_ENDIAN_BYTE_ORDER 1 /**< Multiple-byte values are stored in memory beginning with the least significant byte at the lowest address. */
/**@}*/
/** @name CPU/compiler-independent primitive data type definitions
* @{
*/
typedef int OI_BOOL; /**< Boolean values use native integer data type for target CPU. */
typedef int OI_INT; /**< Integer values use native integer data type for target CPU. */
typedef unsigned int OI_UINT; /**< Unsigned integer values use native unsigned integer data type for target CPU. */
typedef unsigned char OI_BYTE; /**< Raw bytes type uses native character data type for target CPU. */
/**@}*/
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_X86
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< x86 platform byte ordering is little-endian */
/** @name CPU/compiler-dependent primitive data type definitions for x86 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for x86 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for x86 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for x86 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for x86 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for x86 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for x86 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM
/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARM7_LEND or OI_CPU_ARM7_BEND for
little-endian or big-endian configurations of the ARM7, respectively. */
#error OI_CPU_ARM is deprecated
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC
/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARC_LEND or OI_CPU_ARC_BEND for
little-endian or big-endian configurations of the ARC, respectively. */
#error OI_CPU_ARC is deprecated
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH3
/* The Hitachi SH C compiler defines _LIT or _BIG, depending on the endianness
specified to the compiler on the command line. */
#if defined(_LIT)
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER /**< If _LIT is defined, SH-3 platform byte ordering is little-endian. */
#elif defined(_BIG)
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< If _BIG is defined, SH-3 platform byte ordering is big-endian. */
#else
#error SH compiler endianness undefined
#endif
/** @name CPU/compiler-dependent primitive data type definitions for SH-3 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-3 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-3 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-3 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-3 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-3 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-3 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH2
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH-2 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for SH-2 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH-2 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH-2 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH-2 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH-2 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-2 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-2 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_H8
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
#error basic types not defined
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_MIPS
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for MIPS processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SPARC
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
#error basic types not defined
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M68000
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< M68000 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for M68000 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M68000 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M68000 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M68000 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M68000 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M68000 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M68000 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_PPC
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for PPC 8XX processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for PPC8XX processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for PPC8XX processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for PPC8XX processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for PPC8XX processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for PPC8XX processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for PPC8XX processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_SH4_7750
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH7750 platform byte ordering is big-endian. */
/** @name CPU/compiler-dependent primitive data type definitions for SH7750 processor series of the SH-4 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for SH7750 SH-4 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for SH7750 SH-4 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for SH7750 SH-4 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for SH7750 SH-4 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH7750 SH-4 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH7750 SH-4 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM7_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef void *OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARM7_BEND
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name big-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef void *OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_GDM1202
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
typedef signed char OI_INT8; /**< 8-bit signed integer. */
typedef signed short OI_INT16; /**< 16-bit signed integer. */
typedef signed long OI_INT32; /**< 32-bit signed integer. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARC_BEND
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARC processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M30833F
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for Mitsubishi M308 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M308 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M308 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M308 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M308 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M308 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M308 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_CR16C
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for National Semicnductor processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for CR16C processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for CR16C processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for CR16C processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for CR16C processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for CR16C processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for CR16C processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_M64111
#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
/** @name CPU/compiler-dependent primitive data type definitions for Renesas M32R processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for M64111 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for M64111 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for M64111 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for M64111 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M64111 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M64111 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#if OI_CPU_TYPE==OI_CPU_ARMV5_LEND
#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
/** @name little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
* @{
*/
typedef signed char OI_INT8; /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
typedef signed short OI_INT16; /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
typedef signed long OI_INT32; /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
typedef unsigned char OI_UINT8; /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
typedef unsigned short OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
typedef unsigned long OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
/**@}*/
#endif
/*********************************************************************************/
#ifndef OI_CPU_BYTE_ORDER
#error "Byte order (endian-ness) not defined"
#endif
/**@}*/
#ifdef __cplusplus
}
#endif
/*********************************************************************************/
#endif /* _OI_CPU_DEP_H */

View File

@ -0,0 +1,171 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_MODULES_H
#define _OI_MODULES_H
/**
* @file
*
* Enumeration type defining the inidivual stack components.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* This enumeration lists constants for referencing the components of
* the BLUEmagic 3.0 protocol stack, profiles, and other functionalities.
*
* In order to distinguish types of modules, items are grouped with markers to
* delineate start and end of the groups
*
* The module type is used for various purposes:
* identification in debug print statements
* access to initialization flags
* access to the configuration table
*/
typedef enum {
/* profiles and protocols --> Updates to oi_debug.c and oi_config_table.c */
/* XX --> Keep Enum values up-to-date! */
OI_MODULE_AT, /**< 00 AT command processing */
OI_MODULE_A2DP, /**< 01 Advanced Audio Distribution Profile */
OI_MODULE_AVCTP, /**< 02 Audio-Visual Control Transport Profile */
OI_MODULE_AVDTP, /**< 03 Audio-Visual Distribution Protocol */
OI_MODULE_AVRCP, /**< 04 Audio-Visual Remote Control Profile */
OI_MODULE_BIP_CLI, /**< 05 Basic Imaging Profile protocol client */
OI_MODULE_BIP_SRV, /**< 06 Basic Imaging Profile protocol server */
OI_MODULE_BNEP, /**< 07 Bluetooth Network Encapsulation Protocol */
OI_MODULE_BPP_SENDER, /**< 08 Basic Printing Profile */
OI_MODULE_BPP_PRINTER, /**< 09 Basic Printing Profile */
OI_MODULE_CTP, /**< 10 Cordless Telephony Profile */
OI_MODULE_DUN, /**< 11 Dial-Up Networking Profile */
OI_MODULE_FAX, /**< 12 Fax Profile */
OI_MODULE_FTP_CLI, /**< 13 File Transfer Profile protocol client */
OI_MODULE_FTP_SRV, /**< 14 File Transfer Profile protocol server */
OI_MODULE_HANDSFREE, /**< 15 Hands-Free Profile */
OI_MODULE_HANDSFREE_AG, /**< 16 Hands-Free Profile */
OI_MODULE_HCRP_CLI, /**< 17 Hardcopy Cable Replacement Profile */
OI_MODULE_HCRP_SRV, /**< 18 Hardcopy Cable Replacement Profile */
OI_MODULE_HEADSET, /**< 19 Headset Profile */
OI_MODULE_HEADSET_AG, /**< 20 Headset Profile */
OI_MODULE_HID, /**< 21 Human Interface Device profile */
OI_MODULE_INTERCOM, /**< 22 Intercom Profile */
OI_MODULE_OBEX_CLI, /**< 23 OBEX protocol client, Generic Object Exchange Profile */
OI_MODULE_OBEX_SRV, /**< 24 OBEX protocol server, Generic Object Exchange Profile */
OI_MODULE_OPP_CLI, /**< 25 Object Push Profile protocol client */
OI_MODULE_OPP_SRV, /**< 26 Object Push Profile protocol server */
OI_MODULE_PAN, /**< 27 PAN profile */
OI_MODULE_PBAP_CLI, /**< 28 Phonebook Access Profile client */
OI_MODULE_PBAP_SRV, /**< 29 Phonebook Access Profile server */
OI_MODULE_SAP_CLI, /**< 30 SIM Access Profile */
OI_MODULE_SAP_SRV, /**< 31 SIM Access Profile */
OI_MODULE_SPP, /**< 32 Serial Port Profile */
OI_MODULE_SYNC_CLI, /**< 33 Synchronization Profile */
OI_MODULE_SYNC_SRV, /**< 34 Synchronization Profile */
OI_MODULE_SYNC_CMD_CLI, /**< 35 Synchronization Profile */
OI_MODULE_SYNC_CMD_SRV, /**< 36 Synchronization Profile */
OI_MODULE_SYNCML, /**< 37 SyncML Profile */
OI_MODULE_TCS, /**< 38 TCS Binary */
OI_MODULE_VDP, /**< 39 Video Distribution Profile */
/* corestack components --> Updates to oi_debug.c and oi_config_table.c */
OI_MODULE_COMMON_CONFIG, /**< 40 Common configuration, module has no meaning other than for config struct */
OI_MODULE_CMDCHAIN, /**< 41 Command chaining utility */
OI_MODULE_DISPATCH, /**< 42 Dispatcher */
OI_MODULE_DATAELEM, /**< 43 Data Elements, marshaller */
OI_MODULE_DEVMGR, /**< 44 Device Manager */
OI_MODULE_DEVMGR_MODES, /**< 45 Device Manager connectability/discoverability modes */
OI_MODULE_HCI, /**< 46 Host Controller Interface command layer */
OI_MODULE_L2CAP, /**< 47 L2CAP */
OI_MODULE_MEMMGR, /**< 48 modules that do memory management */
OI_MODULE_POLICYMGR, /**< 49 Policy Manager */
OI_MODULE_RFCOMM, /**< 50 RFCOMM */
OI_MODULE_RFCOMM_SD, /**< 51 RFCOMM Service discovery */
OI_MODULE_SDP_CLI, /**< 52 Service Discovery Protocol client */
OI_MODULE_SDP_SRV, /**< 53 Service Discovery Protocol server */
OI_MODULE_SDPDB, /**< 54 Service Discovery Protocol database */
OI_MODULE_SECMGR, /**< 55 Security Manager */
OI_MODULE_SNIFFLOG, /**< 56 sniff log */
OI_MODULE_SUPPORT, /**< 57 support functions, including CThru Dispatcher, time functions, and stack initialization */
OI_MODULE_TRANSPORT, /**< 58 transport layer between HCI command layer and driver */
OI_MODULE_TEST, /**< 59 used to debug output from internal test programs */
OI_MODULE_XML, /**< 60 XML/CSS parser */
OI_MODULE_DI, /**< 61 Device Identification Profile */
// bhapi components --> Updates to oi_debug.c
OI_MODULE_BHAPI, /**< 62 BLUEmagic Host API generic */
OI_MODULE_BHCLI, /**< 63 BLUEmagic Host API client side */
OI_MODULE_BHSRV, /**< 64 BLUEmagic Host API server side */
OI_MODULE_MSGQ, /**< 65 module that handles message queuing */
OI_MODULE_BHAPI_TRANSPORT, /**< 66 module that handles message queuing */
OI_MODULE_BLST_SRV, /**< 67 module that provides server side BHAPI Lightweight Serial Transport */
OI_MODULE_BLST_CLI, /**< 68 module that provides client side BHAPI Lightweight Serial Transport */
// OEM files --> Updates to oi_debug.c
OI_MODULE_OEM, /**< 69 Application Memory allocation */
// Application glue --> Updates to oi_debug.c
OI_MODULE_APP, /**< 70 Application Memory allocation */
/* various pieces of code depend on these last 2 elements occuring in a specific order:
OI_MODULE_ALL must be the 2nd to last element
OI_MODULE_UNKNOWN must be the last element
*/
OI_MODULE_ALL, /**< 71 special value identifying all modules - used for control of debug print statements */
OI_MODULE_UNKNOWN /**< 72 special value - used for debug print statements */
} OI_MODULE;
/**
* This constant is the number of actual modules in the list. ALL and UNKNOWN are
* special values that are not actually modules.
* Used for debug print and memmgr profiling
*/
#define OI_NUM_MODULES OI_MODULE_ALL
/**
* This constant is the number of profile and core components. It is used to size
* the initialization and configuration tables.
*/
#define OI_NUM_STACK_MODULES OI_MODULE_BHAPI
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_MODULES_H */

View File

@ -0,0 +1,197 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_OSINTERFACE_H
#define _OI_OSINTERFACE_H
/**
@file
* This file provides the platform-independent interface for functions for which
* implementation is platform-specific.
*
* The functions in this header file define the operating system or hardware
* services needed by the BLUEmagic 3.0 protocol stack. The
* actual implementation of these services is platform-dependent.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
#include "oi_time.h"
#include "oi_status.h"
#include "oi_modules.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Terminates execution.
*
* @param reason Reason for termination
*/
void OI_FatalError(OI_STATUS reason);
/**
* This function logs an error.
*
* When built for release mode, BLUEmagic 3 errors are logged to
* this function. (in debug mode, errors are logged via
* OI_Print()).
*
* @param module Module in which the error was detected (see
* oi_modules.h)
* @param lineno Line number of the C file OI_SLOG_ERROR called
* @param status Status code associated with the error event
*/
void OI_LogError(OI_MODULE module, OI_INT lineno, OI_STATUS status);
/**
* This function initializes the debug code handling.
*
* When built for debug mode, this function performs platform
* dependent initialization to handle message codes passed in
* via OI_SetMsgCode().
*/
void OI_InitDebugCodeHandler(void);
/**
* This function reads the time from the real time clock.
*
* All timing in BM3 is relative, typically a granularity
* of 5 or 10 msecs is adequate.
*
* @param[out] now Pointer to the buffer to which the current
* time will be returned
*/
void OI_Time_Now(OI_TIME *now);
/**
* This function causes the current thread to sleep for the
* specified amount of time. This function must be called
* without the stack access token.
*
* @note BM3 corestack and profiles never suspend and never call
* OI_Sleep. The use of OI_Sleep is limited to applications and
* platform-specific code.
*
* If your port and applications never use OI_Sleep, this function can be left unimplemented.
*
* @param milliseconds Number of milliseconds to sleep
*/
void OI_Sleep(OI_UINT32 milliseconds);
/**
* Defines for message type codes.
*/
#define OI_MSG_CODE_APPLICATION 0 /**< Application output */
#define OI_MSG_CODE_ERROR 1 /**< Error message output */
#define OI_MSG_CODE_WARNING 2 /**< Warning message output */
#define OI_MSG_CODE_TRACE 3 /**< User API function trace output */
#define OI_MSG_CODE_PRINT1 4 /**< Catagory 1 debug print output */
#define OI_MSG_CODE_PRINT2 5 /**< Catagory 2 debug print output */
#define OI_MSG_CODE_HEADER 6 /**< Error/Debug output header */
/**
* This function is used to indicate the type of text being output with
* OI_Print(). For the Linux and Win32 platforms, it will set
* the color of the text. Other possible uses could be to insert
* HTML style tags, add some other message type indication, or
* be completely ignored altogether.
*
* @param code OI_MSG_CODE_* indicating setting the message type.
*/
void OI_SetMsgCode(OI_UINT8 code);
/**
* All output from OI_Printf() and all debug output is sent to OI_Print.
* Typically, if the platform has a console, OI_Print() is sent to stdout.
* Embedded platforms typically send OI_Print() output to a serial port.
*
* @param str String to print
*/
void OI_Print(OI_CHAR const *str);
/**
* In cases where OI_Print() is sending output to a logfile in addition to console,
* it is desirable to also put console input into the logfile.
* This function can be called by the console input process.
*
* @note This is an optional API which is strictly
* between the platform-specific stack_console and osinterface
* modules. This API need only be implemented on those
* platforms where is serves a useful purpose, e.g., win32.
*
* @param str Console input string
*/
void OI_Print_ConsoleInput(OI_CHAR const *str);
/**
* This function computes the CRC16 of the program image.
*/
OI_UINT16 OI_ProgramImageCRC16(void);
/**
* Writes an integer to stdout in hex. This macro is intended
* for selective use when debugging in small memory
* configurations or other times when it is not possible to use
* OI_DBGPRINT.
*
* @param n the integer to print
*/
#define OI_Print_Int(n) \
{ \
static const OI_CHAR _digits[] = "0123456789ABCDEF"; \
OI_CHAR _buf[9]; \
OI_CHAR *_str = &_buf[8]; \
OI_UINT32 _i = n; \
*_str = 0; \
do { *(--_str) = _digits[(_i & 0xF)]; _i >>= 4; } while (_i); \
OI_Print(_str); \
}
/**
* Application Dynamic Memory allocation.
*
* These APIs are provided for application use on those
* platforms which have no dynamic memory support. Memory is
* allocated from the pool-based heap managed by the stack's
* internal memory manager.
*/
void *OI_APP_Malloc(OI_INT32 size);
void OI_APP_Free(void *ptr);
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_OSINTERFACE_H */

View File

@ -0,0 +1,579 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_STATUS_H
#define _OI_STATUS_H
/**
* @file
* This file contains status codes for BLUEmagic 3.0 software.
*/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/** test it **/
/**
* OI_STATUS must fit in 16 bits, so status codes can range from 0 to 66535, inclusive.
*/
typedef enum {
OI_STATUS_SUCCESS = 0, /**< function call succeeded alias for #OI_OK */
OI_OK = 0, /**< function call succeeded alias for #OI_STATUS_SUCCESS */
OI_STATUS_INVALID_PARAMETERS = 101, /**< invalid function input parameters */
OI_STATUS_NOT_IMPLEMENTED = 102, /**< attempt to use an unimplemented function */
OI_STATUS_NOT_INITIALIZED = 103, /**< data not initialized */
OI_STATUS_NO_RESOURCES = 104, /**< generic resource allocation failure status */
OI_STATUS_INTERNAL_ERROR = 105, /**< internal inconsistency */
OI_STATUS_OUT_OF_MEMORY = 106, /**< generally, OI_Malloc failed */
OI_ILLEGAL_REENTRANT_CALL = 107, /**< violation of non-reentrant module policy */
OI_STATUS_INITIALIZATION_FAILED = 108, /**< module initialization failed */
OI_STATUS_INITIALIZATION_PENDING = 109, /**< inititialization not yet complete */
OI_STATUS_NO_SCO_SUPPORT = 110, /**< SCO operation rejected; system not configured for SCO */
OI_STATUS_OUT_OF_STATIC_MEMORY = 111, /**< static malloc failed */
OI_TIMEOUT = 112, /**< generic timeout */
OI_OS_ERROR = 113, /**< some operating system error */
OI_FAIL = 114, /**< generic failure */
OI_STRING_FORMAT_ERROR = 115, /**< error in VarString formatting string */
OI_STATUS_PENDING = 116, /**< The operation is pending. */
OI_STATUS_INVALID_COMMAND = 117, /**< The command was invalid. */
OI_BUSY_FAIL = 118, /**< command rejected due to busy */
OI_STATUS_ALREADY_REGISTERED = 119, /**< The registration has already been performed. */
OI_STATUS_NOT_FOUND = 120, /**< The referenced resource was not found. */
OI_STATUS_NOT_REGISTERED = 121, /**< not registered */
OI_STATUS_NOT_CONNECTED = 122, /**< not connected */
OI_CALLBACK_FUNCTION_REQUIRED = 123, /**< A callback function parameter was required. */
OI_STATUS_MBUF_OVERFLOW = 124, /**< There is no room to add another buffer to an mbuf. */
OI_STATUS_MBUF_UNDERFLOW = 125, /**< There was an attempt to pull too many bytes from an mbuf. */
OI_STATUS_CONNECTION_EXISTS = 126, /**< connection exists */
OI_STATUS_NOT_CONFIGURED = 127, /**< module not configured */
OI_LOWER_STACK_ERROR = 128, /**< An error was reported by lower stack API. This is used for embedded platforms. */
OI_STATUS_RESET_IN_PROGRESS = 129, /**< Request failed/rejected because we're busy resetting. */
OI_STATUS_ACCESS_DENIED = 130, /**< Generic access denied error. */
OI_STATUS_DATA_ERROR = 131, /**< Generic data error. */
OI_STATUS_INVALID_ROLE = 132, /**< The requested role was invalid. */
OI_STATUS_ALREADY_CONNECTED = 133, /**< The requested connection is already established. */
OI_STATUS_PARSE_ERROR = 134, /**< Parse error */
OI_STATUS_END_OF_FILE = 135, /**< End of file */
OI_STATUS_READ_ERROR = 136, /**< Generic read error */
OI_STATUS_WRITE_ERROR = 137, /**< Generic write error */
OI_STATUS_NEGOTIATION_FAILURE = 138, /**< Error in negotiation */
OI_STATUS_READ_IN_PROGRESS = 139, /**< A read is already in progress */
OI_STATUS_ALREADY_INITIALIZED = 140, /**< Initialization has already been done */
OI_STATUS_STILL_CONNECTED = 141, /**< The service cannot be shutdown because there are still active connections. */
OI_STATUS_MTU_EXCEEDED = 142, /**< The packet is too big */
OI_STATUS_LINK_TERMINATED = 143, /**< The link was terminated */
OI_STATUS_PIN_CODE_TOO_LONG = 144, /**< Application gave us a pin code that is too long */
OI_STATUS_STILL_REGISTERED = 145, /**< The service cannot be shutdown because there are still active registrations. */
OI_STATUS_SPEC_VIOLATION = 146, /**< Some application behavior contrary to BT specifications */
OI_STATUS_PSM_ALREADY_REGISTERED = 402, /**< L2CAP: The specified PSM has already been registered. */
OI_STATUS_INVALID_CID = 403, /**< L2CAP: CID is invalid or no longer valid (connection terminated) */
OI_STATUS_CID_NOT_FOUND = 404, /**< L2CAP: CID does not represent a current connection */
OI_STATUS_CHANNEL_NOT_FOUND = 406, /**< L2CAP: CID does not represent a current connection */
OI_STATUS_PSM_NOT_FOUND = 407, /**< L2CAP: PSM not found */
OI_STATUS_INVALID_STATE = 408, /**< L2CAP: invalid state */
OI_STATUS_WRITE_IN_PROGRESS = 410, /**< L2CAP: write in progress */
OI_STATUS_INVALID_PACKET = 411, /**< L2CAP: invalid packet */
OI_STATUS_SEND_COMPLETE = 412, /**< L2CAP: send is complete */
OI_STATUS_INVALID_HANDLE = 414, /**< L2CAP: handle is invalid */
OI_STATUS_GROUP_FULL = 418, /**< L2CAP: No more members can be added to the specified group. */
OI_STATUS_DEVICE_ALREADY_IN_GROUP = 423, /**< L2CAP: The device already exists in the group. */
OI_STATUS_DUPLICATE_GROUP = 425, /**< L2CAP: attempt to add more than one group */
OI_STATUS_EMPTY_GROUP = 426, /**< L2CAP: group is empty */
OI_STATUS_PACKET_NOT_FOUND = 427, /**< L2CAP: packet not found */
OI_STATUS_BUFFER_TOO_SMALL = 428, /**< L2CAP: The buffer size is too small. */
OI_STATUS_IDENTIFIER_NOT_FOUND = 429, /**< L2CAP: identifier not found */
OI_L2CAP_DISCONNECT_LOWER_LAYER = 430, /**< L2CAP: The lower level forced a disconnect. */
OI_L2CAP_DISCONNECT_REMOTE_REQUEST = 431, /**< L2CAP: The remote device requested a disconnect. */
OI_L2CAP_GROUP_ADD_CONNECT_FAIL = 433, /**< L2CAP: Group add connect faiL */
OI_L2CAP_GROUP_REMOVE_FAILURE = 434, /**< L2CAP: Group remove failure */
OI_L2CAP_DATA_WRITE_ERROR_LINK_TERM = 435, /**< L2CAP: Data write error LINK_TERM */
OI_L2CAP_DISCONNECT_LOCAL_REQUEST = 436, /**< L2CAP: Disconnect local request */
OI_L2CAP_CONNECT_TIMEOUT = 437, /**< L2CAP: Connect timeout */
OI_L2CAP_DISCONNECT_TIMEOUT = 439, /**< L2CAP: Disconnect timeout */
OI_L2CAP_PING_TIMEOUT = 440, /**< L2CAP: Ping timeout */
OI_L2CAP_GET_INFO_TIMEOUT = 441, /**< L2CAP: Get info timeout */
OI_L2CAP_INVALID_ADDRESS = 444, /**< L2CAP: Invalid address */
OI_L2CAP_CMD_REJECT_RCVD = 445, /**< L2CAP: remote sent us 'command reject' response */
OI_L2CAP_CONNECT_BASE = 450, /**< L2CAP: Connect base */
OI_L2CAP_CONNECT_PENDING = 451, /**< L2CAP: Connect pending */
OI_L2CAP_CONNECT_REFUSED_INVALID_PSM = 452, /**< L2CAP: Connect refused invalid PSM */
OI_L2CAP_CONNECT_REFUSED_SECURITY = 453, /**< L2CAP: Connect refused security */
OI_L2CAP_CONNECT_REFUSED_NO_RESOURCES = 454, /**< L2CAP: Connect refused no resources */
OI_L2CAP_CONFIG_BASE = 460, /**< L2CAP: Config base */
OI_L2CAP_CONFIG_FAIL_INVALID_PARAMETERS = 461, /**< L2CAP: Config fail invalid parameters */
OI_L2CAP_CONFIG_FAIL_NO_REASON = 462, /**< L2CAP: Config fail no reason */
OI_L2CAP_CONFIG_FAIL_UNKNOWN_OPTIONS = 463, /**< L2CAP: Config fail unknown options */
OI_L2CAP_GET_INFO_BASE = 470, /**< L2CAP: Get info base */
OI_L2CAP_GET_INFO_NOT_SUPPORTED = 471, /**< L2CAP: Get info not supported */
OI_L2CAP_MTU_EXCEEDED = 472, /**< L2CAP: The MTU of the channel was exceeded */
OI_L2CAP_INVALID_PSM = 482, /**< L2CAP: Invalid PSM */
OI_L2CAP_INVALID_MTU = 483, /**< L2CAP: Invalid MTU */
OI_L2CAP_INVALID_FLUSHTO = 484, /**< L2CAP: Invalid flush timeout */
OI_HCI_NO_SUCH_CONNECTION = 601, /**< HCI: caller specified a non-existent connection handle */
OI_HCI_CB_LIST_FULL = 603, /**< HCI: callback list is full, cannot attempt to send command */
OI_HCI_EVENT_UNDERRUN = 605, /**< HCI: parsing event packet, premature end-of-parameters */
OI_HCI_UNKNOWN_EVENT_CODE = 607, /**< HCI: event received - event code is unknown */
OI_HCI_BAD_EVENT_PARM_LEN = 608, /**< HCI: event - parameter length is incorrect */
OI_HCI_CMD_QUEUE_FULL = 611, /**< HCI: command queue is full */
OI_HCI_SHORT_EVENT = 612, /**< HCI: event received, missing event code and/or parm len */
OI_HCI_TRANSMIT_NOT_READY = 613, /**< HCI: ACL/SCO transmit request failed - busy or no buffers available */
OI_HCI_ORPHAN_SENT_EVENT = 614, /**< HCI: got spurious 'sent' event from transport layer */
OI_HCI_CMD_TABLE_ERROR = 615, /**< HCI: inconsistency in the internal command table */
OI_HCI_UNKNOWN_CMD_ID = 616, /**< HCI: HciApi Command - unknown command id */
OI_HCI_UNEXPECTED_EVENT = 619, /**< HCI: event received which only occurs in response to our cmd */
OI_HCI_EVENT_TABLE_ERROR = 620, /**< HCI: inconsistency in the internal event table */
OI_HCI_EXPECTED_EVENT_TIMOUT = 621, /**< HCI: timed out waiting for an expected event */
OI_HCI_NO_CMD_DESC_FOR_OPCODE = 622, /**< HCI: event opcode is not known */
OI_HCI_INVALID_OPCODE_ERROR = 623, /**< HCI: command opcode is invalid */
OI_HCI_FLOW_CONTROL_DISABLED = 624, /**< HCI: can not use host flow control APIs if disabled in configuration */
OI_HCI_TX_COMPLETE = 625, /**< HCI: packet delivery to Host Controler complete */
OI_HCI_TX_ERROR = 626, /**< HCI: failed to deliver packet to Host Controler */
OI_HCI_DEVICE_NOT_INITIALIZED = 627, /**< HCI: commands from upper layers disallowed until device is up and running */
OI_HCI_UNSUPPORTED_COMMAND = 628, /**< HCI: command requested is not supported by local device */
OI_HCI_PASSTHROUGH_ERROR = 629, /**< HCI: Error processing passthrough command */
OI_HCI_PASSTHROUGH_ALREADY_SET = 630, /**< HCI: Passthrough mode already enabled */
OI_HCI_RESET_FAILURE = 631, /**< HCI: failed to reset the device/baseband */
OI_HCI_TRANSPORT_RESET = 632, /**< HCI: some operation failed because of a reset in the transport */
OI_HCIERR_HCIIFC_INIT_FAILURE = 633, /**< HCI: failed to initialize transport layer interface */
OI_HCIERR_FIRST_ERROR_VALUE = 701, /**< marker for first HCI protocol error */
OI_HCIERR_UNKNOWN_HCI_COMMAND = 701, /**< HCI: protocol error 0x01 */
OI_HCIERR_NO_CONNECTION = 702, /**< HCI: protocol error 0x02 */
OI_HCIERR_HARDWARE_FAILURE = 703, /**< HCI: protocol error 0x03 */
OI_HCIERR_PAGE_TIMEOUT = 704, /**< HCI: protocol error 0x04 */
OI_HCIERR_AUTHENTICATION_FAILURE = 705, /**< HCI: protocol error 0x05 */
OI_HCIERR_KEY_MISSING = 706, /**< HCI: protocol error 0x06 */
OI_HCIERR_MEMORY_FULL = 707, /**< HCI: protocol error 0x07 */
OI_HCIERR_CONNECTION_TIMEOUT = 708, /**< HCI: protocol error 0x08 */
OI_HCIERR_MAX_NUM_OF_CONNECTIONS = 709, /**< HCI: protocol error 0x09 */
OI_HCIERR_MAX_NUM_OF_SCO_CONNECTIONS = 710, /**< HCI: protocol error 0x0A */
OI_HCIERR_ACL_CONNECTION_ALREADY_EXISTS = 711, /**< HCI: protocol error 0x0B */
OI_HCIERR_COMMAND_DISALLOWED = 712, /**< HCI: protocol error 0x0C */
OI_HCIERR_HOST_REJECTED_RESOURCES = 713, /**< HCI: protocol error 0x0D */
OI_HCIERR_HOST_REJECTED_SECURITY = 714, /**< HCI: protocol error 0x0E */
OI_HCIERR_HOST_REJECTED_PERSONAL_DEVICE = 715, /**< HCI: protocol error 0x0F */
OI_HCIERR_HOST_TIMEOUT = 716, /**< HCI: protocol error 0x10 */
OI_HCIERR_UNSUPPORTED = 717, /**< HCI: protocol error 0x11 */
OI_HCIERR_INVALID_PARAMETERS = 718, /**< HCI: protocol error 0x12 */
OI_HCIERR_OTHER_END_USER_DISCONNECT = 719, /**< HCI: protocol error 0x13 */
OI_HCIERR_OTHER_END_LOW_RESOURCES = 720, /**< HCI: protocol error 0x14 */
OI_HCIERR_OTHER_END_POWERING_OFF = 721, /**< HCI: protocol error 0x15 */
OI_HCIERR_CONNECTION_TERMINATED_LOCALLY = 722, /**< HCI: protocol error 0x16 */
OI_HCIERR_REPEATED_ATTEMPTS = 723, /**< HCI: protocol error 0x17 */
OI_HCIERR_PAIRING_NOT_ALLOWED = 724, /**< HCI: protocol error 0x18 */
OI_HCIERR_UNKNOWN_LMP_PDU = 725, /**< HCI: protocol error 0x19 */
OI_HCIERR_UNSUPPORTED_REMOTE_FEATURE = 726, /**< HCI: protocol error 0x1A */
OI_HCIERR_SCO_OFFSET_REJECTED = 727, /**< HCI: protocol error 0x1B */
OI_HCIERR_SCO_INTERVAL_REJECTED = 728, /**< HCI: protocol error 0x1C */
OI_HCIERR_SCO_AIR_MODE_REJECTED = 729, /**< HCI: protocol error 0x1D */
OI_HCIERR_INVALID_LMP_PARMS = 730, /**< HCI: protocol error 0x1E */
OI_HCIERR_UNSPECIFIED_ERROR = 731, /**< HCI: protocol error 0x1F */
OI_HCIERR_UNSUPPORTED_LMP_PARAMETERS = 732, /**< HCI: protocol error 0x20 */
OI_HCIERR_ROLE_CHANGE_NOT_ALLOWED = 733, /**< HCI: protocol error 0x21 */
OI_HCIERR_LMP_RESPONSE_TIMEOUT = 734, /**< HCI: protocol error 0x22 */
OI_HCIERR_LMP_ERROR_TRANS_COLLISION = 735, /**< HCI: protocol error 0x23 */
OI_HCIERR_LMP_PDU_NOT_ALLOWED = 736, /**< HCI: protocol error 0x24 */
OI_HCIERR_ENCRYPTION_MODE_NOT_ACCEPTABLE = 737, /**< HCI: protocol error 0x25 */
OI_HCIERR_UNIT_KEY_USED = 738, /**< HCI: protocol error 0x26 */
OI_HCIERR_QOS_NOT_SUPPORTED = 739, /**< HCI: protocol error 0x27 */
OI_HCIERR_INSTANT_PASSED = 740, /**< HCI: protocol error 0x28 */
OI_HCIERR_UNIT_KEY_PAIRING_UNSUPPORTED = 741, /**< HCI: protocol error 0x29 */
OI_HCIERR_DIFFERENT_TRANS_COLLISION = 742, /**< HCI: protocol error 0x2A */
OI_HCIERR_RESERVED_2B = 743, /**< HCI: protocol error 0x2B */
OI_HCIERR_QOS_UNACCEPTABLE_PARAMETER = 744, /**< HCI: protocol error 0x2C */
OI_HCIERR_QOS_REJECTED = 745, /**< HCI: protocol error 0x2D */
OI_HCIERR_CHANNEL_CLASSIFICATION_NS = 746, /**< HCI: protocol error 0x2E */
OI_HCIERR_INSUFFICIENT_SECURITY = 747, /**< HCI: protocol error 0x2F */
OI_HCIERR_PARM_OUT_OF_MANDATORY_RANGE = 748, /**< HCI: protocol error 0x30 */
OI_HCIERR_RESERVED_31 = 749, /**< HCI: protocol error 0x31 */
OI_HCIERR_ROLE_SWITCH_PENDING = 750, /**< HCI: protocol error 0x32 */
OI_HCIERR_RESERVED_33 = 751, /**< HCI: protocol error 0x33 */
OI_HCIERR_RESERVED_SLOT_VIOLATION = 752, /**< HCI: protocol error 0x34 */
OI_HCIERR_ROLE_SWITCH_FAILED = 753, /**< HCI: protocol error 0x35 */
OI_HCIERR_EIR_TOO_LARGE = 754, /**< HCI: protocol error 0x36 */
OI_HCIERR_SSP_NOT_SUPPORTED_BY_HOST = 755, /**< HCI: protocol error 0x37 */
OI_HCIERR_HOST_BUSY_PAIRING = 756, /**< HCI: protocol error 0x38 */
OI_HCIERR_UNKNOWN_ERROR = 757, /**< HCI: unknown error code */
OI_HCIERR_LAST_ERROR_VALUE = 757, /**< marker for last HCI protocol error */
OI_SDP_SPEC_ERROR = 800, /**< SDP: Base error status for mapping OI_STATUS codes to SDP errors */
OI_SDP_INVALID_SERVICE_RECORD_HANDLE = (OI_SDP_SPEC_ERROR + 2), /**< SDP: protocol error Invalid Service Record Handle */
OI_SDP_INVALID_REQUEST_SYNTAX = (OI_SDP_SPEC_ERROR + 3), /**< SDP: protocol error Invalid Request Syntax */
OI_SDP_INVALID_PDU_SIZE = (OI_SDP_SPEC_ERROR + 4), /**< SDP: protocol error Invalid PDU Size */
OI_SDP_INVALID_CONTINUATION_STATE = (OI_SDP_SPEC_ERROR + 5), /**< SDP: protocol error Invalid Continuation State */
OI_SDP_INSUFFICIENT_RESOURCES = (OI_SDP_SPEC_ERROR + 6), /**< SDP: protocol error Insufficient Resources */
OI_SDP_ERROR = 807, /**< SDP: server returned an error code */
OI_SDP_CORRUPT_DATA_ELEMENT = 808, /**< SDP: Invalid or corrupt data element representation */
OI_SDP_SERVER_NOT_CONNECTED = 810, /**< SDP: Attempt to disconnect from an unconnected server */
OI_SDP_ACCESS_DENIED = 811, /**< SDP: Server denied access to server */
OI_SDP_ATTRIBUTES_OUT_OF_ORDER = 812, /**< SDP: Attributes in attribute list not in ascending order */
OI_SDP_DEVICE_DOES_NOT_SUPPORT_SDP = 813, /**< SDP: Tried to connect to a device that does not support SDP */
OI_SDP_NO_MORE_DATA = 815, /**< SDP: Server does not have more continuation data */
OI_SDP_REQUEST_PARAMS_TOO_LONG = 816, /**< SDP: Parameters for a request exceed the L2CAP buffer size */
OI_SDP_REQUEST_PENDING = 817, /**< SDP: Cannot make a request when another request is being processed */
OI_SDP_SERVER_CONNECT_FAILED = 819, /**< SDP: Failed attempt to connect to an SDP server */
OI_SDP_SERVER_TOO_MANY_CONNECTIONS = 821, /**< SDP: Exceeded maximum number of simultaneous server connections */
OI_SDP_NO_MATCHING_SERVICE_RECORD = 823, /**< SDP: No service record matched the UUID list */
OI_SDP_PARTIAL_RESPONSE = 824, /**< SDP: Internal use only */
OI_SDP_ILLEGAL_ARGUMENT = 825, /**< SDP: Illegal argument passed to an SDP function */
OI_SDP_ATTRIBUTE_NOT_FOUND = 826, /**< SDP: A requested attribute was not found in a service record */
OI_SDP_DATABASE_OUT_OF_RESOURCES = 827, /**< SDP: server database is out of memory */
OI_SDP_SHORT_PDU = 829, /**< SDP: Not enough bytes in the packet */
OI_SDP_TRANSACTION_ID_MISMATCH = 830, /**< SDP: Transaction Id was not as expected */
OI_SDP_UNEXPECTED_RESPONSE_PDU_ID = 831, /**< SDP: Did not expect this response PDU */
OI_SDP_REQUEST_TIMEOUT = 832, /**< SDP: Did not get a response within the timeout period */
OI_SDP_INVALID_RESPONSE_SYNTAX = 833, /**< SDP: Response is not correctly formatted */
OI_SDP_CONNECTION_TIMEOUT = 834, /**< SDP: Connection attempt timed out at a lower layer */
OI_SDP_RESPONSE_DATA_ERROR = 835, /**< SDP: Response to a service request appears to be corrupt */
OI_SDP_TOO_MANY_ATTRIBUTE_BYTES = 836, /**< SDP: Response contained more bytes than requested. */
OI_SDP_TOO_MANY_SERVICE_RECORDS = 837, /**< SDP: Response contained more service records than requested. */
OI_SDP_INVALID_CONNECTION_ID = 838, /**< SDP: Invalid connection ID in an SDP request */
OI_SDP_CANNOT_SET_ATTRIBUTE = 839, /**< SDP: Attempt to set a dynamic attribute value failed */
OI_SDP_BADLY_FORMED_ATTRIBUTE_VALUE = 840, /**< SDP: An attribute value has the wrong type or structure */
OI_SDP_NO_ATTRIBUTE_LIST_TO_REMOVE = 841, /**< SDP: Attempt to remove a non-existent attribute list from a service record */
OI_SDP_ATTRIBUTE_LIST_ALREADY_ADDED = 842, /**< SDP: An attribute list has already been added to the service record */
OI_SDP_DATA_ELEMENT_TRUNCATED = 843, /**< SDP: Data element truncated (too few bytes) */
OI_RFCOMM_WRITE_IN_PROGRESS = 901, /**< RFCOMM: Write in progress */
OI_RFCOMM_INVALID_BAUDRATE = 903, /**< RFCOMM: Invalid baudrate */
OI_RFCOMM_INVALID_DATABIT = 904, /**< RFCOMM: Invalid databit */
OI_RFCOMM_INVALID_STOPBIT = 905, /**< RFCOMM: Invalid stopbit */
OI_RFCOMM_INVALID_PARITY = 906, /**< RFCOMM: Invalid parity */
OI_RFCOMM_INVALID_PARITYTYPE = 907, /**< RFCOMM: Invalid paritytype */
OI_RFCOMM_INVALID_FLOWCONTROL = 908, /**< RFCOMM: Invalid flowcontrol */
OI_RFCOMM_SESSION_EXISTS = 909, /**< RFCOMM: Session exists */
OI_RFCOMM_INVALID_CHANNEL = 910, /**< RFCOMM: Invalid channel */
OI_RFCOMM_DLCI_EXISTS = 911, /**< RFCOMM: DLCI exists */
OI_RFCOMM_LINK_NOT_FOUND = 912, /**< RFCOMM: Link not found */
OI_RFCOMM_REMOTE_REJECT = 913, /**< RFCOMM: Remote reject */
OI_RFCOMM_TEST_IN_PROGRESS = 915, /**< RFCOMM: Test in progress */
OI_RFCOMM_SESSION_NOT_FOUND = 916, /**< RFCOMM: Session not found */
OI_RFCOMM_INVALID_PACKET = 917, /**< RFCOMM: Invalid packet */
OI_RFCOMM_FRAMESIZE_EXCEEDED = 918, /**< RFCOMM: Framesize exceeded */
OI_RFCOMM_INVALID_DLCI = 920, /**< RFCOMM: Invalid dlci */
OI_RFCOMM_SERVER_NOT_REGISTERED = 921, /**< RFCOMM: Server not registered */
OI_RFCOMM_CREDIT_ERROR = 922, /**< RFCOMM: Credit error */
OI_RFCOMM_NO_CHANNEL_NUMBER = 923, /**< RFCOMM: No channel number */
OI_RFCOMM_QUERY_IN_PROGRESS = 924, /**< RFCOMM: Query in progress */
OI_RFCOMM_SESSION_SHUTDOWN = 925, /**< RFCOMM: Session shutdown */
OI_RFCOMM_LOCAL_DEVICE_DISCONNECTED = 926, /**< RFCOMM: Local device disconnected */
OI_RFCOMM_REMOTE_DEVICE_DISCONNECTED = 927, /**< RFCOMM: Remote device disconnected */
OI_RFCOMM_OUT_OF_SERVER_CHANNELS = 928, /**< RFCOMM: Out of server channels */
OI_DISPATCH_INVALID_CB_HANDLE = 1001, /**< Dispatcher was handed an invalid callback handle */
OI_DISPATCH_TABLE_OVERFLOW = 1002, /**< Dispatcher table is full */
OI_TEST_UNKNOWN_TEST = 1101, /**< TEST: Unknown test */
OI_TEST_FAIL = 1102, /**< TEST: Fail */
OI_HCITRANS_CANNOT_CONNECT_TO_DEVICE = 1201, /**< TRANSPORT: Cannot connect to device */
OI_HCITRANS_BUFFER_TOO_SMALL = 1203, /**< TRANSPORT: Buffer too small */
OI_HCITRANS_NULL_DEVICE_HANDLE = 1204, /**< TRANSPORT: Null device handle */
OI_HCITRANS_IO_ERROR = 1205, /**< TRANSPORT: IO error */
OI_HCITRANS_DEVICE_NOT_READY = 1206, /**< TRANSPORT: Device not ready */
OI_HCITRANS_FUNCTION_NOT_SUPPORTED = 1207, /**< TRANSPORT: Function not supporteD */
OI_HCITRANS_ACCESS_DENIED = 1209, /**< TRANSPORT: win32 */
OI_HCITRANS_ACL_DATA_ERROR = 1210, /**< TRANSPORT: ACL data error */
OI_HCITRANS_SCO_DATA_ERROR = 1211, /**< TRANSPORT: SCO data error */
OI_HCITRANS_EVENT_DATA_ERROR = 1212, /**< TRANSPORT: HCI event data error */
OI_HCITRANS_INTERNAL_ERROR = 1214, /**< TRANSPORT: Internal error in the transport */
OI_HCITRANS_LINK_NOT_ACTIVE = 1215, /**< TRANSPORT: Link to the device is not currently active */
OI_HCITRANS_INITIALIZING = 1216, /**< TRANSPORT: Transport is initializing */
OI_DEVMGR_NO_CONNECTION = 1301, /**< DEVMGR: No connection */
OI_DEVMGR_HARDWARE_ERROR = 1305, /**< DEVMGR: error reported by HCI */
OI_DEVMGR_PENDING_CONNECT_LIST_FULL = 1307, /**< DEVMGR: Pending connect list full */
OI_DEVMGR_CONNECTION_LIST_FULL = 1309, /**< DEVMGR: Connection list full */
OI_DEVMGR_NO_SUCH_CONNECTION = 1310, /**< DEVMGR: No such connection */
OI_DEVMGR_INQUIRY_IN_PROGRESS = 1311, /**< DEVMGR: Inquiry in progress */
OI_DEVMGR_PERIODIC_INQUIRY_ACTIVE = 1312, /**< DEVMGR: Periodic inquiry active */
OI_DEVMGR_NO_INQUIRIES_ACTIVE = 1313, /**< DEVMGR: can not cancel/exit if not active */
OI_DEVMGR_DUPLICATE_CONNECTION = 1314, /**< DEVMGR: internal error */
OI_DEVMGR_DUPLICATE_EVENT_CALLBACK = 1316, /**< DEVMGR: attempt to register same callback twice */
OI_DEVMGR_EVENT_CALLBACK_LIST_FULL = 1317, /**< DEVMGR: can not register event callback, list is full */
OI_DEVMGR_EVENT_CALLBACK_NOT_FOUND = 1318, /**< DEVMGR: attempt to unregister callback failed */
OI_DEVMGR_BUSY = 1319, /**< DEVMGR: some operations can only execute one at a time */
OI_DEVMGR_ENUM_UNEXPECTED_INQ_COMPLETE = 1320, /**< DEVMGR: inquiry complete event in inappropriate enumeration state */
OI_DEVMGR_ENUM_UNEXPECTED_INQ_RESULT = 1321, /**< DEVMGR: inquiry result event in inappropriate enumeration state */
OI_DEVMGR_ENUM_DATABASE_FULL = 1322, /**< DEVMGR: device enumeration, database is full, couldn't add a new device */
OI_DEVMGR_ENUM_INQUIRIES_OVERLAP = 1323, /**< DEVMGR: device enumeration, periodic inquiries occurring too close together */
OI_DEVMGR_UNKNOWN_LINK_TYPE = 1324, /**< DEVMGR: HCI connect request with unkown link type */
OI_DEVMGR_PARAM_IO_ACTIVE = 1325, /**< DEVMGR: request for parameter read/write while param read/write active */
OI_DEVMGR_UNKNOWN_IAC_LAP = 1326, /**< DEVMGR: unrecognized IAC LAP */
OI_DEVMGR_SCO_ALREADY_REGISTERED = 1327, /**< DEVMGR: only one application can use SCO */
OI_DEVMGR_SCO_NOT_REGISTERED = 1328, /**< DEVMGR: SCO applications must register before using the API */
OI_DEVMGR_SCO_WITHOUT_ACL = 1329, /**< DEVMGR: Got SCO connection but there is no underlying ACL connection */
OI_DEVMGR_NO_SUPPORT = 1330, /**< DEVMGR: Request is not supported by the device */
OI_DEVMGR_WRITE_POLICY_FAILED = 1331, /**< DEVMGR: connection attempt failed - unable to write link policy */
OI_DEVMGR_NOT_IN_MASTER_MODE = 1332, /**< DEVMGR: OI_DEVMGR EndMasterMode without prior OI_DEVMGR_BeginMasterMode */
OI_DEVMGR_POLICY_VIOLATION = 1333, /**< DEVMGR: low-power request is rejected - link policy does not allow it */
OI_DEVMGR_BUSY_TIMEOUT = 1334, /**< DEVMGR: queued operation timed out while in the queue; \n
timeout configurable via @ref OI_CONFIG_DEVMGR::connectQueueTimeoutSecs "connectQueueTimeoutSecs" */
OI_DEVMGR_REENCRYPT_FAILED = 1335, /**< DEVMGR: failed to re-encrypt link after role switch */
OI_DEVMGR_ROLE_POLICY_CONFLICT = 1336, /**< DEVMGR: requested role conflicts with current policy */
OI_DEVMGR_BAD_INTERVAL = 1337, /**< DEVMGR: current linkTO outside range of requested min/max interval */
OI_DEVMGR_INVALID_SCO_HANDLE = 1338, /**< DEVMGR: HCI SCO event, invalid handle */
OI_DEVMGR_CONNECTION_OVERLAP = 1339, /**< DEVMGR: Connection failed due to race condition with remote side */
OI_DEVMGR_ORPHAN_SUBRATE_COMPLETE = 1340, /**< DEVMGR: sniff subrate complete, but no callback */
OI_DEVMGR_EIR_RESPONSE_2_LARGE = 1341, /**< DEVMGR: eir builder, response length would exceed spec max */
OI_SECMGR_NO_POLICY = 1401, /**< SECMGR: no security policy has been established */
OI_SECMGR_INTERNAL_ERROR = 1402, /**< SECMGR: internal inconsistency */
OI_SECMGR_ORPHANED_CALLBACK = 1403, /**< SECMGR: we've been called back, but CB context is gone */
OI_SECMGR_BUSY = 1404, /**< SECMGR: configure and access request cannot be concurrent */
OI_SECMGR_DEVICE_NOT_TRUSTED = 1405, /**< SECMGR: l2cap access denied - device is not trusted */
OI_SECMGR_DEVICE_ENCRYPT_FAIL = 1407, /**< SECMGR: l2cap access denied - failed to start encryption */
OI_SECMGR_DISCONNECTED_FAIL = 1408, /**< SECMGR: l2cap access denied - disconnected */
OI_SECMGR_ACCESS_PENDING = 1409, /**< SECMGR: l2cap access request is still pending */
OI_SECMGR_PIN_CODE_TOO_SHORT = 1410, /**< SECMGR: Higher-layer process gave us a pin code that is too short */
OI_SECMGR_UNKNOWN_ENCRYPT_VALUE = 1411, /**< SECMGR: got EncryptionChange event, unknown encryption enable value */
OI_SECMGR_INVALID_POLICY = 1412, /**< SECMGR: the specified security policy is not valid for security mode */
OI_SECMGR_AUTHORIZATION_FAILED = 1413, /**< SECMGR: device authorization failed */
OI_SECMGR_ENCRYPTION_FAILED = 1414, /**< SECMGR: device encryption failed */
OI_SECMGR_UNIT_KEY_UNSUPPORTED = 1415, /**< SECMGR: authentication failed due to non-support of unit keys */
OI_SECMGR_NOT_REGISTERED = 1416, /**< SECMGR: required registrations have not yet occurred */
OI_SECMGR_ILLEGAL_WRITE_SSP_MODE = 1417, /**< SECMGR: 2.1 HCI spec does not allow SSP mode to be disabled */
OI_SECMGR_INVALID_SEC_LEVEL = 1418, /**< SECMGR: security level for a service is not a valid value */
OI_SECMGR_INSUFFICIENT_LINK_KEY = 1419, /**< SECMGR: link key type is not sufficient to meet service requirements */
OI_SECMGR_INVALID_KEY_TYPE = 1420, /**< SECMGR: link key type is not a valid value */
OI_SECMGR_SSP_NOT_ENCRYPTED = 1421, /**< SECMGR: ssp required encryption on incoming link */
OI_SECMGR_ORPHAN_EVENT = 1422, /**< SECMGR: some HCI security event unrelated to current processes */
OI_SECMGR_NOT_BONDABLE = 1423, /**< SECMGR: not in bondable mode */
OI_TCS_INVALID_ELEMENT_TYPE = 1602, /**< TCS: element type is invalid */
OI_TCS_INVALID_PACKET = 1603, /**< TCS: packet is invalide */
OI_TCS_CALL_IN_PROGRESS = 1604, /**< TCS: call is in progress */
OI_TCS_NO_CALL_IN_PROGRESS = 1605, /**< TCS: no call in progress */
OI_OBEX_CONTINUE = 1701, /**< OBEX: Continue processing OBEX request */
OI_OBEX_COMMAND_ERROR = 1702, /**< OBEX: An unrecognized OBEX command opcode */
OI_OBEX_CONNECTION_TIMEOUT = 1703, /**< OBEX: Timeout waiting for a response to a request */
OI_OBEX_CONNECT_FAILED = 1704, /**< OBEX: An OBEX connection request did not succeed */
OI_OBEX_DISCONNECT_FAILED = 1705, /**< OBEX: A disconnect failed probably because the connection did not exist */
OI_OBEX_ERROR = 1706, /**< OBEX: Unspecified OBEX error */
OI_OBEX_INCOMPLETE_PACKET = 1707, /**< OBEX: Packet too short or corrupt */
OI_OBEX_LENGTH_REQUIRED = 1708, /**< OBEX: Length header required in OBEX command */
OI_OBEX_NOT_CONNECTED = 1709, /**< OBEX: No connection to OBEX server */
OI_OBEX_NO_MORE_CONNECTIONS = 1710, /**< OBEX: Reached max connections limit */
OI_OBEX_OPERATION_IN_PROGRESS = 1711, /**< OBEX: Another operation is still in progress on a connection */
OI_OBEX_PUT_RESPONSE_ERROR = 1712, /**< OBEX: An error in the response to a PUT command */
OI_OBEX_GET_RESPONSE_ERROR = 1713, /**< OBEX: An error in the response to a GET command */
OI_OBEX_REQUIRED_HEADER_NOT_FOUND = 1714, /**< OBEX: packet was missing a required header */
OI_OBEX_SERVICE_UNAVAILABLE = 1715, /**< OBEX: Unown OBEX target or required service */
OI_OBEX_TOO_MANY_HEADER_BYTES = 1716, /**< OBEX: Headers will not fit in single OBEX packet */
OI_OBEX_UNKNOWN_COMMAND = 1717, /**< OBEX: Unrecognized OBEX command */
OI_OBEX_UNSUPPORTED_VERSION = 1718, /**< OBEX: Version mismatch */
OI_OBEX_CLIENT_ABORTED_COMMAND = 1719, /**< OBEX: server received abort command */
OI_OBEX_BAD_PACKET = 1720, /**< OBEX: Any malformed OBEX packet */
OI_OBEX_BAD_REQUEST = 1721, /**< OBEX: Maps to OBEX response of the same name */
OI_OBEX_OBJECT_OVERFLOW = 1723, /**< OBEX: Too many bytes received. */
OI_OBEX_NOT_FOUND = 1724, /**< OBEX: Maps to obex response of same name */
OI_OBEX_ACCESS_DENIED = 1735, /**< OBEX: Object could not be read or written. */
OI_OBEX_VALUE_NOT_ACCEPTABLE = 1736, /**< OBEX: Value in a command was not in the acceptable range. */
OI_OBEX_PACKET_OVERFLOW = 1737, /**< OBEX: Buffer will not fit in a single OBEX packet. */
OI_OBEX_NO_SUCH_FOLDER = 1738, /**< OBEX: Error returned by a setpath operation. */
OI_OBEX_NAME_REQUIRED = 1739, /**< OBEX: Name must be non-null and non-empty. */
OI_OBEX_PASSWORD_TOO_LONG = 1740, /**< OBEX: Password exceeds implementation imposed length limit. */
OI_OBEX_PRECONDITION_FAILED = 1741, /**< OBEX: response Precondition Failed */
OI_OBEX_UNAUTHORIZED = 1742, /**< OBEX: authentication was not successful. */
OI_OBEX_NOT_IMPLEMENTED = 1743, /**< OBEX: Unimplemented feature. */
OI_OBEX_INVALID_AUTH_DIGEST = 1744, /**< OBEX: An authentication digest was bad. */
OI_OBEX_INVALID_OPERATION = 1745, /**< OBEX: Operation not allowed at this time. */
OI_OBEX_DATABASE_FULL = 1746, /**< OBEX: Sync database full. */
OI_OBEX_DATABASE_LOCKED = 1747, /**< OBEX: Sync database locked. */
OI_OBEX_INTERNAL_SERVER_ERROR = 1748, /**< OBEX: response Internal Server Error */
OI_OBEX_UNSUPPORTED_MEDIA_TYPE = 1749, /**< OBEX: response Unsupported Media Type */
OI_OBEX_PARTIAL_CONTENT = 1750, /**< OBEX: response Partial Content */
OI_OBEX_METHOD_NOT_ALLOWED = 1751, /**< OBEX: response Method Not Allowed */
OI_OBEXSRV_INCOMPLETE_GET = 1752, /**< OBEX: Indicates to a GET handler that the request phase is still in progress */
OI_OBEX_FOLDER_BROWSING_NOT_ALLOWED = 1753, /**< OBEX: Indicates that an FTP server does not allow folder browsing */
OI_OBEX_SERVER_FORCED_DISCONNECT = 1754, /**< OBEX: connection was forcibly terminated by the server */
OI_OBEX_OFS_ERROR = 1755, /**< OBEX: OPP object file system error occurred */
OI_OBEX_FILEOP_ERROR = 1756, /**< OBEX: FTP/PBAP file operation system error occurred */
OI_OBEX_USERID_TOO_LONG = 1757, /**< OBEX: User Id exceeds spec limited length limit. */
OI_HANDSFREE_EVENT_REPORTING_DISABLED = 1801, /**< HANDSFREE: Event reporting disabled */
OI_HANDSFREE_NOT_CONNECTED = 1802, /**< HANDSFREE: Not connected */
OI_HANDSFREE_SERVICE_NOT_STARTED = 1803, /**< HANDSFREE: Cannot connect to handsfree AG if handsfree service not started */
OI_HANDSFREE_AG_SERVICE_NOT_STARTED = 1804, /**< HANDSFREE: Cannot connect to handsfree device if handsfree AG service not started */
OI_HANDSFREE_COMMAND_IN_PROGRESS = 1805, /**< HANDSFREE: Cannot accept a command at this time */
OI_HANDSFREE_AUDIO_ALREADY_CONNECTED = 1806, /**< HANDSFREE: Audio is already connected */
OI_HANDSFREE_AUDIO_NOT_CONNECTED = 1807, /**< HANDSFREE: Audio is not connected */
OI_HANDSFREE_FEATURE_NOT_SUPPORTED = 1808, /**< HANDSFREE: Local or remote feature not supported for requested command */
OI_HEADSET_SERVICE_NOT_STARTED = 1901, /**< HEADSET: Cannot connect to headset AG if headset service not started */
OI_HEADSET_AG_SERVICE_NOT_STARTED = 1902, /**< HEADSET: Cannot connect to headset device if headset AG service not started */
OI_HEADSET_COMMAND_IN_PROGRESS = 1903, /**< HEADSET: Cannot accept a command at this time */
OI_BNEP_INVALID_MTU = 2001, /**< BNEP: The remote device cannot support the minimum BNEP MTU */
OI_BNEP_SETUP_TIMEOUT = 2002, /**< BNEP: The setup request timed out. */
OI_BNEP_SERVICE_NOT_REGISTERED = 2003, /**< BNEP: The requested service was not found. */
OI_BNEP_INVALID_HANDLE = 2004, /**< BNEP: The specified connection handle is not valid. */
OI_BNEP_RESPONSE_TIMEOUT = 2005, /**< BNEP: The timer for receiving a response has expired. */
OI_BNEP_INVALID_CONNECTION = 2006, /**< BNEP: Invalid connection */
OI_BNEP_INVALID_FILTER = 2007, /**< BNEP: The supplied filter was invalid. */
OI_BNEP_CONNECTION_EXISTS = 2008, /**< BNEP: An attempt was made to create a duplicate connection. */
OI_BNEP_NOT_INITIALIZED = 2009, /**< BNEP: Init has not been called */
OI_BNEP_CONNECT_BASE = 2010, /**< BNEP: connection response codes */
OI_BNEP_CONNECT_FAILED_INVALID_DEST_UUID = 2011, /**< BNEP: connect response code Invalid Dest UUID */
OI_BNEP_CONNECT_FAILED_INVALID_SOURCE_UUID = 2012, /**< BNEP: connect response code Invalid Source UUID */
OI_BNEP_CONNECT_FAILED_INVALID_UUID_SIZE = 2013, /**< BNEP: connect response code Invalid UUID Size */
OI_BNEP_CONNECT_FAILED_NOT_ALLOWED = 2014, /**< BNEP: connect response code Not Allowed */
OI_BNEP_FILTER_NET_BASE = 2020, /**< BNEP: filter response codes */
OI_BNEP_FILTER_NET_UNSUPPORTED_REQUEST = 2021, /**< BNEP: filter response code Unsupported Request */
OI_BNEP_FILTER_NET_FAILED_INVALID_PROTOCOL_TYPE = 2022, /**< BNEP: filter response code Invalid Protocol Type */
OI_BNEP_FILTER_NET_FAILED_MAX_LIMIT_REACHED = 2023, /**< BNEP: filter response code Max Limit Reached */
OI_BNEP_FILTER_NET_FAILED_SECURITY = 2024, /**< BNEP: filter response code Security */
OI_BNEP_FILTER_MULTI_BASE = 2030, /**< BNEP: multicast response codes */
OI_BNEP_FILTER_MULTI_UNSUPPORTED_REQUEST = 2031, /**< BNEP: multicast response code Unsupported Request */
OI_BNEP_FILTER_MULTI_FAILED_INVALID_ADDRESS = 2032, /**< BNEP: multicast response code Invalid Address */
OI_BNEP_FILTER_MULTI_FAILED_MAX_LIMIT_REACHED = 2033, /**< BNEP: multicast response code Max Limit Reached */
OI_BNEP_FILTER_MULTI_FAILED_SECURITY = 2034, /**< BNEP: multicast response code Security */
OI_BNEP_LOCAL_DEVICE_MUST_BE_MASTER = 2040, /**< BNEP: Device must be master of the piconet for this function */
OI_BNEP_PACKET_FILTERED_OUT = 2041, /**< BNEP: Packet did not pass current filters */
OI_NETIFC_UP_FAILED = 2101, /**< NETIFC: Could not bring up network interface */
OI_NETIFC_COULD_NOT_CREATE_THREAD = 2102, /**< NETIFC: Network interface could not create a read thread */
OI_NETIFC_INITIALIZATION_FAILED = 2103, /**< NETIFC: Error in network interface initialization */
OI_NETIFC_INTERFACE_ALREADY_UP = 2104, /**< NETIFC: Network interface is already up */
OI_NETIFC_INTERFACE_NOT_UP = 2105, /**< NETIFC: Network interface is not up */
OI_NETIFC_PACKET_TOO_BIG = 2106, /**< NETIFC: The packet is too big */
OI_PAN_ROLE_ALREADY_REGISTERED = 2201, /**< PAN: This PAN role was already registered */
OI_PAN_ROLE_NOT_ALLOWED = 2202, /**< PAN: The PAN role is not currently allowed */
OI_PAN_INCOMPATIBLE_ROLES = 2203, /**< PAN: Only certain local and remote role combinations are permitted */
OI_PAN_INVALID_ROLE = 2204, /**< PAN: Role specified is not one the defined PAN roles */
OI_PAN_CONNECTION_IN_PROGRESS = 2205, /**< PAN: A PAN connection is currently being established */
OI_PAN_USER_ALREADY_CONNECTED = 2206, /**< PAN: PAN user role only allows a single connection */
OI_PAN_DEVICE_CONNECTED = 2207, /**< PAN: A PAN connection already exists to specified device */
OI_CODEC_SBC_NO_SYNCWORD = 2301, /**< CODEC: Couldn't find an SBC SYNCWORD */
OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA = 2302, /**< CODEC: Not enough data provided to decode an SBC header */
OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA = 2303, /**< CODEC: Decoded the header, but not enough data to contain the rest of the frame */
OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA = 2304, /**< CODEC: Not enough audio data for this frame */
OI_CODEC_SBC_CHECKSUM_MISMATCH = 2305, /**< CODEC: The frame header didn't match the checksum */
OI_CODEC_SBC_PARTIAL_DECODE = 2306, /**< CODEC: Decoding was successful, but frame data still remains. Next call will provide audio without consuming input data. */
OI_FIFOQ_QUEUE_NOT_ALIGNED = 2401, /**< FIFOQ: queue must be 32-bit aligned */
OI_FIFOQ_INVALID_Q = 2402, /**< FIFOQ: queue parameter is not a valid queue */
OI_FIFOQ_BUF_TOO_LARGE = 2403, /**< FIFOQ: attempt to queue a buffer which is too large */
OI_FIFOQ_FULL = 2404, /**< FIFOQ: enqueue() failed, queue is full */
OI_FIFOQ_NOT_ALLOCATED = 2405, /**< FIFOQ: Enqueue QBuf() failed, buffer not allocated */
OI_FIFOQ_INVALID_DATA_PTR = 2406, /**< FIFOQ: Enqueue QBuf() failed, data pointer does not match */
OI_HID_HOST_SERVICE_NOT_STARTED = 2601, /**< HID: Cannot connect to a HID device unless HID host is started */
OI_HID_DEVICE_SERVICE_NOT_STARTED = 2602, /**< HID: Cannot connect to a HID host unless HID device is started */
OI_AT_ERROR = 2701, /**< AT: ERROR response */
OI_AT_NO_CARRIER = 2702, /**< AT: NO CARRIER response */
OI_AT_BUSY = 2703, /**< AT: BUSY response */
OI_AT_NO_ANSWER = 2704, /**< AT: NO ANSWER response */
OI_AT_DELAYED = 2705, /**< AT: DELAYED response */
OI_AT_BLACKLISTED = 2706, /**< AT: BLACKLISTED response */
OI_AT_CME_ERROR = 2707, /**< AT: +CME ERROR response */
OI_AT_CMS_ERROR = 2708, /**< AT: +CMS ERROR response */
OI_BLST_CHARACTER_TIMEOUT = 2801, /**< BLST: Timeout expired while waiting for a character from the client. */
OI_BLST_ACKNOWLDGE_TIMEOUT = 2802, /**< BLST: Timeout expired while waiting for event acknowledgment from the client */
OI_BLST_TX_NOT_READY = 2803, /**< BLST: BLST is not ready to send a BHAPI message to the client. */
OI_BLST_TX_BUSY = 2804, /**< BLST: BLST transmit buffer is in use. */
OI_AVDTP_CONNECTION_SEQ_ERROR = 2901, /**< AVDTP: sequencing of signalling/media channel connections broken. */
OI_AVDTP_OUT_OF_RESOURCES = 2902, /**< AVDTP: Tried to allocate too many endpoints or signalling channels. */
OI_PBAP_REPOSITORY_NOT_SET = 3001, /**< PBAP: Phonebook repository must be set for operation to complete. */
OI_PBAP_PHONEBOOK_NOT_SET = 3002, /**< PBAP: Phonebook be set for operation to complete. */
OI_AADP_BAD_ENDPOINT = 3101, /**< AADP: Invalid local endpoint specified */
OI_AADP_BAD_STATE = 3102, /**< AADP: AADP State is not correct for this operation. */
OI_UNICODE_INVALID_SOURCE = 3200, /**< Unicode Conversion: Source string has invalid character encoding. */
OI_UNICODE_SOURCE_EXHAUSTED = 3201, /**< Unicode Conversion: Incomplete Unicode character at end of source buffer. */
OI_UNICODE_DESTINATION_EXHAUSTED = 3202, /**< Unicode Conversion: Destination buffer not large enough to hold resulting Unicode string. */
OI_AVRCP_TOO_MANY_CONNECTIONS = 3300, /**< AVRCP: Exceeded maximum number of simultaneous AVCTP connections. */
OI_AVRCP_NOT_IMPLEMENTED = 3301, /**< AVRCP: The target does not implement the command specified by the opcode and operand. */
OI_AVRCP_REJECTED = 3302, /**< AVRCP: The target cannot respond because of invalid operands in command packet. */
OI_AVRCP_INVALID_RESPONSE = 3303, /**< AVRCP: The controller received the response with invalid parameters */
OI_AVRCP_RESPONSE_PACKET_OVERFLOW = 3304, /**< AVRCP: The response message does not fir in one AVRCP packet (512 bytes), has to be fragmented. */
OI_AVRCP_RESPONSE_INVALID_PDU = 3305, /**< AVRCP: Command rejected: target received a PDU that it did not understand. */
OI_AVRCP_RESPONSE_INVALID_PARAMETER = 3306, /**< AVRCP: Command rejected: target received a PDU with a parameter ID that it did not understand. */
OI_AVRCP_RESPONSE_PARAMETER_NOT_FOUND = 3307, /**< AVRCP: Command rejected: specified parameter not found, sent if the parameter ID is understood, but content is wrong or corrupted.*/
OI_AVRCP_RESPONSE_INTERNAL_ERROR = 3308, /**< AVRCP: Command rejected: target detected other error conditions. */
OI_MAX_BM3_STATUS_VAL, /* Maximum BM3 status code */
/* Status code values reserved for BM3 SDK platform-specific implementations */
OI_STATUS_RESERVED_FOR_BCOT = 9000,
/* Status code values reserved for BHAPI products */
OI_STATUS_RESERVED_FOR_BHAPI = 9200,
/* Status code values reserved for Soundabout products */
OI_STATUS_RESERVED_FOR_SOUNDABOUT = 9400,
/*
* Status code values greater than or equal to this value are reserved for use by applications.
* However, because of differences between compilers, and differences between 16-bit and 32-bit
* platforms custom status codes should be in the 16-bit range, so status codes can range from 0
* to 65534, inclusive (65535 is reserved)
*/
OI_STATUS_RESERVED_FOR_APPS = 10000,
OI_STATUS_NONE = 0xffff /**< Special status code to indicate that there is no status. (Only to be used for special cases involving OI_SLOG_ERROR() and OI_SLOG_WARNING().) */
} OI_STATUS;
/* Remeber to update the #define below when new reserved blocks are added to
* the list above. */
#define OI_NUM_RESERVED_STATUS_BLOCKS 4 /**< Number of status code blocks reserved, including user apps */
/**
* Test for success
*/
#define OI_SUCCESS(x) ((x) == OI_OK)
/*****************************************************************************/
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_STATUS_H */

View File

@ -0,0 +1,232 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 OI_STDDEFS_H
#define OI_STDDEFS_H
/**
* @file
* This file contains BM3 standard type definitions.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_cpu_dep.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FALSE
#define FALSE 0 /**< This define statement sets FALSE as a preprocessor alias for 0. */
#endif
#ifndef TRUE
#define TRUE (!FALSE) /**< This define statement sets TRUE as a preprocessor alias for !FALSE. */
#endif
#ifdef HEW_TOOLCHAIN
#ifdef NULL
#undef NULL /**< Override HEW toolchain NULL definition */
#endif
#define NULL 0 /**< HEW toolchain does not allow us to compare (void*) type to function pointer */
#else
#ifndef NULL
#define NULL ((void*)0) /**< This define statement sets NULL as a preprocessor alias for (void*)0 */
#endif
#endif
/**
* @name Maximum and minimum values for basic types
* @{
*/
#define OI_INT8_MIN ((OI_INT8)0x80) /**< decimal value: -128 */
#define OI_INT8_MAX ((OI_INT8)0x7F) /**< decimal value: 127 */
#define OI_INT16_MIN ((OI_INT16)0x8000) /**< decimal value: -32768 */
#define OI_INT16_MAX ((OI_INT16)0x7FFF) /**< decimal value: 32767 */
#define OI_INT32_MIN ((OI_INT32)0x80000000) /**< decimal value: -2,147,483,648 */
#define OI_INT32_MAX ((OI_INT32)0x7FFFFFFF) /**< decimal value: 2,147,483,647 */
#define OI_UINT8_MIN ((OI_UINT8)0) /**< decimal value: 0 */
#define OI_UINT8_MAX ((OI_UINT8)0xFF) /**< decimal value: 255 */
#define OI_UINT16_MIN ((OI_UINT16)0) /**< decimal value: 0 */
#define OI_UINT16_MAX ((OI_UINT16)0xFFFF) /**< decimal value: 65535 */
#define OI_UINT32_MIN ((OI_UINT32)0) /**< decimal value: 0 */
#define OI_UINT32_MAX ((OI_UINT32)0xFFFFFFFF) /**< decimal value: 4,294,967,295 */
/**
* @}
*/
/**
* @name Integer types required by the Service Discovery Protocol
* @{
*/
/** unsigned 64-bit integer as a structure of two unsigned 32-bit integers */
typedef struct {
OI_UINT32 I1; /**< most significant 32 bits */
OI_UINT32 I2; /**< least significant 32 bits */
} OI_UINT64;
#define OI_UINT64_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_UINT64_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** signed 64-bit integer as a structure of one unsigned 32-bit integer and one signed 32-bit integer */
typedef struct {
OI_INT32 I1; /**< most significant 32 bits as a signed integer */
OI_UINT32 I2; /**< least significant 32 bits as an unsigned integer */
} OI_INT64;
#define OI_INT64_MIN { (OI_INT32)0x80000000, (OI_UINT32)0x00000000 }
#define OI_INT64_MAX { (OI_INT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** unsigned 128-bit integer as a structure of four unsigned 32-bit integers */
typedef struct {
OI_UINT32 I1; /**< most significant 32 bits */
OI_UINT32 I2; /**< second-most significant 32 bits */
OI_UINT32 I3; /**< third-most significant 32 bits */
OI_UINT32 I4; /**< least significant 32 bits */
} OI_UINT128;
#define OI_UINT128_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_UINT128_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/** signed 128-bit integer as a structure of three unsigned 32-bit integers and one signed 32-bit integer */
typedef struct {
OI_INT32 I1; /**< most significant 32 bits as a signed integer */
OI_UINT32 I2; /**< second-most significant 32 bits as an unsigned integer */
OI_UINT32 I3; /**< third-most significant 32 bits as an unsigned integer */
OI_UINT32 I4; /**< least significant 32 bits as an unsigned integer */
} OI_INT128;
#define OI_INT128_MIN { (OI_UINT32)0x80000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
#define OI_INT128_MAX { (OI_UINT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
/**
* @}
*/
/**
* type for ASCII character data items
*/
typedef char OI_CHAR;
/**
* type for double-byte character data items
*/
typedef OI_UINT16 OI_CHAR16;
/**
* types for UTF encoded strings.
*/
typedef OI_UINT8 OI_UTF8;
typedef OI_UINT16 OI_UTF16;
typedef OI_UINT32 OI_UTF32;
/**
* @name Single-bit operation macros
* @{
* In these macros, x is the data item for which a bit is to be tested or set and y specifies which bit
* is to be tested or set.
*/
/** This macro's value is TRUE if the bit specified by y is set in data item x. */
#define OI_BIT_TEST(x,y) ((x) & (y))
/** This macro's value is TRUE if the bit specified by y is not set in data item x. */
#define OI_BIT_CLEAR_TEST(x,y) (((x) & (y)) == 0)
/** This macro sets the bit specified by y in data item x. */
#define OI_BIT_SET(x,y) ((x) |= (y))
/** This macro clears the bit specified by y in data item x. */
#define OI_BIT_CLEAR(x,y) ((x) &= ~(y))
/** @} */
/**
* The OI_ARRAYSIZE macro is set to the number of elements in an array
* (instead of the number of bytes, which is returned by sizeof()).
*/
#ifndef OI_ARRAYSIZE
#define OI_ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#endif
/**
* @name Preprocessor aliases for individual bit positions
* Bits are defined here only if they are not already defined.
* @{
*/
#ifndef BIT0
#define BIT0 0x00000001 /**< preprocessor alias for 32-bit value with bit 0 set, used to specify this single bit */
#define BIT1 0x00000002 /**< preprocessor alias for 32-bit value with bit 1 set, used to specify this single bit */
#define BIT2 0x00000004 /**< preprocessor alias for 32-bit value with bit 2 set, used to specify this single bit */
#define BIT3 0x00000008 /**< preprocessor alias for 32-bit value with bit 3 set, used to specify this single bit */
#define BIT4 0x00000010 /**< preprocessor alias for 32-bit value with bit 4 set, used to specify this single bit */
#define BIT5 0x00000020 /**< preprocessor alias for 32-bit value with bit 5 set, used to specify this single bit */
#define BIT6 0x00000040 /**< preprocessor alias for 32-bit value with bit 6 set, used to specify this single bit */
#define BIT7 0x00000080 /**< preprocessor alias for 32-bit value with bit 7 set, used to specify this single bit */
#define BIT8 0x00000100 /**< preprocessor alias for 32-bit value with bit 8 set, used to specify this single bit */
#define BIT9 0x00000200 /**< preprocessor alias for 32-bit value with bit 9 set, used to specify this single bit */
#define BIT10 0x00000400 /**< preprocessor alias for 32-bit value with bit 10 set, used to specify this single bit */
#define BIT11 0x00000800 /**< preprocessor alias for 32-bit value with bit 11 set, used to specify this single bit */
#define BIT12 0x00001000 /**< preprocessor alias for 32-bit value with bit 12 set, used to specify this single bit */
#define BIT13 0x00002000 /**< preprocessor alias for 32-bit value with bit 13 set, used to specify this single bit */
#define BIT14 0x00004000 /**< preprocessor alias for 32-bit value with bit 14 set, used to specify this single bit */
#define BIT15 0x00008000 /**< preprocessor alias for 32-bit value with bit 15 set, used to specify this single bit */
#define BIT16 0x00010000 /**< preprocessor alias for 32-bit value with bit 16 set, used to specify this single bit */
#define BIT17 0x00020000 /**< preprocessor alias for 32-bit value with bit 17 set, used to specify this single bit */
#define BIT18 0x00040000 /**< preprocessor alias for 32-bit value with bit 18 set, used to specify this single bit */
#define BIT19 0x00080000 /**< preprocessor alias for 32-bit value with bit 19 set, used to specify this single bit */
#define BIT20 0x00100000 /**< preprocessor alias for 32-bit value with bit 20 set, used to specify this single bit */
#define BIT21 0x00200000 /**< preprocessor alias for 32-bit value with bit 21 set, used to specify this single bit */
#define BIT22 0x00400000 /**< preprocessor alias for 32-bit value with bit 22 set, used to specify this single bit */
#define BIT23 0x00800000 /**< preprocessor alias for 32-bit value with bit 23 set, used to specify this single bit */
#define BIT24 0x01000000 /**< preprocessor alias for 32-bit value with bit 24 set, used to specify this single bit */
#define BIT25 0x02000000 /**< preprocessor alias for 32-bit value with bit 25 set, used to specify this single bit */
#define BIT26 0x04000000 /**< preprocessor alias for 32-bit value with bit 26 set, used to specify this single bit */
#define BIT27 0x08000000 /**< preprocessor alias for 32-bit value with bit 27 set, used to specify this single bit */
#define BIT28 0x10000000 /**< preprocessor alias for 32-bit value with bit 28 set, used to specify this single bit */
#define BIT29 0x20000000 /**< preprocessor alias for 32-bit value with bit 29 set, used to specify this single bit */
#define BIT30 0x40000000 /**< preprocessor alias for 32-bit value with bit 30 set, used to specify this single bit */
#define BIT31 0x80000000 /**< preprocessor alias for 32-bit value with bit 31 set, used to specify this single bit */
#endif /* BIT0 et al */
/** @} */
#ifdef __cplusplus
}
#endif
/**@}*/
/*****************************************************************************/
#endif /* OI_STDDEFS_H */

View File

@ -0,0 +1,208 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 OI_STRING_H
#define OI_STRING_H
/**
* @file
* This file contains BM3 supplied portable string.h functions
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_cpu_dep.h"
#include "oi_stddefs.h"
#if defined(USE_NATIVE_MEMCPY) || defined(USE_NATIVE_MALLOC)
#include <string.h>
#endif
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* If we are using Native malloc(), we must also use
* native Ansi string.h functions for memory manipulation.
*/
#ifdef USE_NATIVE_MALLOC
#ifndef USE_NATIVE_MEMCPY
#define USE_NATIVE_MEMCPY
#endif
#endif
#ifdef USE_NATIVE_MEMCPY
#define OI_MemCopy(to, from, size) memcpy((to), (from), (size))
#define OI_MemSet(block, val, size) memset((block), (val), (size))
#define OI_MemZero(block, size) memset((block), 0, (size))
#define OI_MemCmp(s1, s2, n) memcmp((s1), (s2), (n))
#define OI_Strcpy(dest, src) strcpy((dest),(src))
#define OI_Strcat(dest, src) strcat((dest),(src))
#define OI_StrLen(str) strlen((str))
#define OI_Strcmp(s1, s2) strcmp((s1), (s2))
#define OI_Strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#else
/*
* OI_MemCopy
*
* Copy an arbitrary number of bytes from one memory address to another.
* The underlying implementation is the ANSI memmove() or equivalant, so
* overlapping memory copies will work correctly.
*/
void OI_MemCopy(void *To, void const *From, OI_UINT32 Size);
/*
* OI_MemSet
*
* Sets all bytes in a block of memory to the same value
*/
void OI_MemSet(void *Block, OI_UINT8 Val, OI_UINT32 Size);
/*
* OI_MemZero
*
* Sets all bytes in a block of memory to zero
*/
void OI_MemZero(void *Block, OI_UINT32 Size);
/*
* OI_MemCmp
*
* Compare two blocks of memory
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_MemCmp(void const *s1, void const *s2, OI_UINT32 n);
/*
* OI_Strcpy
*
* Copies the Null terminated string from pStr to pDest, and
* returns pDest.
*/
OI_CHAR *OI_Strcpy(OI_CHAR *pDest,
OI_CHAR const *pStr);
/*
* OI_Strcat
*
* Concatonates the pStr string to the end of pDest, and
* returns pDest.
*/
OI_CHAR *OI_Strcat(OI_CHAR *pDest,
OI_CHAR const *pStr) ;
/*
* OI_StrLen
*
* Calculates the number of OI_CHARs in pStr (not including
* the Null terminator) and returns the value.
*/
OI_UINT OI_StrLen(OI_CHAR const *pStr) ;
/*
* OI_Strcmp
*
* Compares two Null terminated strings
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_Strcmp(OI_CHAR const *s1,
OI_CHAR const *s2);
/*
* OI_Strncmp
*
* Compares the first "len" OI_CHARs of strings s1 and s2.
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_Strncmp(OI_CHAR const *s1,
OI_CHAR const *s2,
OI_UINT32 len);
#endif /* USE_NATIVE_MEMCPY */
/*
* OI_StrcmpInsensitive
*
* Compares two Null terminated strings, treating
* the Upper and Lower case of 'A' through 'Z' as
* equivilent.
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_StrcmpInsensitive(OI_CHAR const *s1,
OI_CHAR const *s2);
/*
* OI_StrncmpInsensitive
*
* Compares the first "len" OI_CHARs of strings s1 and s2,
* treating the Upper and Lower case of 'A' through 'Z' as
* equivilent.
*
*
* Returns:
* 0, if s1 == s2
* < 0, if s1 < s2
* > 0, if s2 > s2
*/
OI_INT OI_StrncmpInsensitive(OI_CHAR const *s1,
OI_CHAR const *s2,
OI_UINT len);
#ifdef __cplusplus
}
#endif
/** @} */
/*****************************************************************************/
#endif /* OI_STRING_H */

View File

@ -0,0 +1,200 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_TIME_H
#define _OI_TIME_H
/** @file
*
* This file provides time type definitions and interfaces to time-related functions.
*
* The stack maintains a 64-bit real-time millisecond clock. The choice of
* milliseconds is for convenience, not accuracy.
*
* Timeouts are specified as tenths of seconds in a 32-bit value. Timeout values
* specified by the Bluetooth specification are usually muliple seconds, so
* accuracy to a tenth of a second is more than adequate.
*
* This file also contains macros to convert between seconds and the Link
* Manager's 1.28-second units.
*
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "oi_stddefs.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Within the core stack timeouts are specified in intervals of tenths of seconds
*/
typedef OI_UINT16 OI_INTERVAL;
#define OI_INTERVALS_PER_SECOND 10
#define MSECS_PER_OI_INTERVAL (1000 / OI_INTERVALS_PER_SECOND)
/** maximum interval (54 min 36.7 sec) */
#define OI_MAX_INTERVAL 0x7fff
/**
* Macro to convert seconds to OI_INTERVAL time units
*/
#define OI_SECONDS(n) ((OI_INTERVAL) ((n) * OI_INTERVALS_PER_SECOND))
/**
* Macro to convert milliseconds to OI_INTERVAL time units (Rounded Up)
*/
#define OI_MSECONDS(n) ((OI_INTERVAL) ((n + MSECS_PER_OI_INTERVAL - 1) / MSECS_PER_OI_INTERVAL))
/**
* Macro to convert minutes to OI_INTERVAL time units
*/
#define OI_MINUTES(n) ((OI_INTERVAL) ((n) * OI_SECONDS(60)))
/** Convert an OI_INTERVAL to milliseconds. */
#define OI_INTERVAL_TO_MILLISECONDS(i) ((i) * MSECS_PER_OI_INTERVAL)
/**
* The stack depends on relative not absolute time. Any mapping between the
* stack's real-time clock and absolute time and date is implementation-dependent.
*/
typedef struct {
OI_INT32 seconds;
OI_INT16 mseconds;
} OI_TIME;
/**
* Convert an OI_TIME to milliseconds.
*
* @param t the time to convert
*
* @return the time in milliseconds
*/
OI_UINT32 OI_Time_ToMS(OI_TIME *t);
/**
* This function compares two time values.
*
* @param T1 first time to compare.
*
* @param T2 second time to compare.
*
* @return
@verbatim
-1 if t1 < t2
0 if t1 = t2
+1 if t1 > t2
@endverbatim
*/
OI_INT16 OI_Time_Compare(OI_TIME *T1,
OI_TIME *T2);
/**
* This function returns the interval between two times to a granularity of 0.1 seconds.
*
* @param Sooner a time value more recent that Later
*
* @param Later a time value later than Sooner
*
* @note The result is an OI_INTERVAL value so this function only works for time intervals
* that are less than about 71 minutes.
*
* @return the time interval between the two times = (Later - Sooner)
*/
OI_INTERVAL OI_Time_Interval(OI_TIME *Sooner,
OI_TIME *Later);
/**
* This function returns the interval between two times to a granularity of milliseconds.
*
* @param Sooner a time value more recent that Later
*
* @param Later a time value later than Sooner
*
* @note The result is an OI_UINT32 value so this function only works for time intervals
* that are less than about 50 days.
*
* @return the time interval between the two times = (Later - Sooner)
*/
OI_UINT32 OI_Time_IntervalMsecs(OI_TIME *Sooner,
OI_TIME *Later);
/**
* This function answers the question, Have we reached or gone past the target time?
*
* @param pTargetTime target time
*
* @return TRUE means time now is at or past target time
* FALSE means target time is still some time in the future
*/
OI_BOOL OI_Time_NowReachedTime(OI_TIME *pTargetTime);
/**
* Convert seconds to the Link Manager 1.28-second units
* Approximate by using 1.25 conversion factor.
*/
#define OI_SECONDS_TO_LM_TIME_UNITS(lmUnits) ((lmUnits)<4?(lmUnits):(lmUnits)-((lmUnits)>>2))
/**
* Convert Link Manager 1.28-second units to seconds.
* Approximate by using 1.25 conversion factor.
*/
#define OI_LM_TIME_UNITS_TO_SECONDS(lmUnits) ((lmUnits) + ((lmUnits)>>2))
#ifdef __cplusplus
}
#endif
/**@}*/
/* Include for OI_Time_Now() prototype
* Must be included at end to obtain OI_TIME typedef
*/
#include "oi_osinterface.h"
/*****************************************************************************/
#endif /* _OI_TIME_H */

View File

@ -0,0 +1,377 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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 _OI_UTILS_H
#define _OI_UTILS_H
/**
* @file
*
* This file provides the interface for utility functions.
* Among the utilities are strlen (string length), strcmp (string compare), and
* other string manipulation functions. These are provided for those plaforms
* where this functionality is not available in stdlib.
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include <stdarg.h>
#include "oi_common.h"
#include "oi_string.h"
#include "oi_bt_spec.h"
/** \addtogroup Misc Miscellaneous APIs */
/**@{*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Opaque type for a callback function handle. See OI_ScheduleCallbackFunction()
*/
typedef OI_UINT32 OI_CALLBACK_HANDLE;
/**
* Function prototype for a timed procedure callback.
*
* @param arg Value that was passed into the OI_ScheduleCallback() function
*
*/
typedef void (*OI_SCHEDULED_CALLBACK)(void *arg);
/**
* Registers a function to be called when a timeout expires. This API uses BLUEmagic's internal
* function dispatch mechanism, so applications that make extensive use of this facility may need to
* increase the value of DispatchTableSize in the configuration block for the dispatcher (see
* oi_bt_stack_config.h).
*
* @param callbackFunction The function that will be called when the timeout expires
*
* @param arg Value that will be returned as the parameter to the callback function.
*
* @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
* zero in which case the callback function will be called as soon as
* possible.
*
* @param handle NULL or a pointer receive the callback handle.
*
* @return OI_OK if the function was reqistered, or an error status.
*/
OI_STATUS OI_ScheduleCallbackFunction(OI_SCHEDULED_CALLBACK callbackFunction,
void *arg,
OI_INTERVAL timeout,
OI_CALLBACK_HANDLE *handle);
/**
* Cancels a function registered with OI_ScheduleCallbackFunction() before its timer expires.
*
* @param handle handle returned by OI_ScheduleCallbackFunction().
*
* @return OI_OK if the function was cancelled, or an error status.
*/
OI_STATUS OI_CancelCallbackFunction(OI_CALLBACK_HANDLE handle);
/**
* Registers a function to be called when a timeout expires. This version does not return a handle
* so can only be canceled by calling OI_CancelCallback().
*
* @param callbackFunction The function that will be called when the timeout expires
*
* @param arg Value that will be returned as the parameter to the callback function.
*
* @param timeout A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
* zero in which case the callback function will be called as soon as
* possible.
*
* @return OI_OK if the function was reqistered, or an error status.
*/
#define OI_ScheduleCallback(f, a, t) OI_ScheduleCallbackFunction(f, a, t, NULL);
/**
* Cancels a function registered with OI_ScheduleCallback() before its timer expires. This
* function will cancel the first entry matches the indicated callback function pointer.
*
* @param callbackFunction The function that was originally registered
*
* @return OI_OK if the function was cancelled, or an error status.
*/
OI_STATUS OI_CancelCallback(OI_SCHEDULED_CALLBACK callbackFunction);
/**
* Parse a Bluetooth device address from the specified string.
*
* @param str the string to parse
* @param addr the parsed address, if successful
*
* @return TRUE if an address was successfully parsed, FALSE otherwise
*/
OI_BOOL OI_ParseBdAddr(const OI_CHAR *str,
OI_BD_ADDR *addr) ;
/**
* Printf function for platforms which have no stdio or printf available.
* OI_Printf supports the basic formatting types, with the exception of
* floating point types. Additionally, OI_Printf supports several formats
* specific to BLUEmagic 3.0 software:
*
* \%! prints the string for an #OI_STATUS value.
* @code OI_Printf("There was an error %!", status); @endcode
*
* \%@ prints a hex dump of a buffer.
* Requires a pointer to the buffer and a signed integer length
* (0 for default length). If the buffer is large, only an excerpt will
* be printed.
* @code OI_Printf("Contents of buffer %@", buffer, sizeof(buffer)); @endcode
*
* \%: prints a Bluetooth address in the form "HH:HH:HH:HH:HH:HH".
* Requires a pointer to an #OI_BD_ADDR.
* @code OI_Printf("Bluetooth address %:", &bdaddr); @endcode
*
* \%^ decodes and prints a data element as formatted XML.
* Requires a pointer to an #OI_DATAELEM.
* @code OI_Printf("Service attribute list is:\n%^", &attributes); @endcode
*
* \%/ prints the base file name of a path, that is, the final substring
* following a '/' or '\\' character. Requires a pointer to a null
* terminated string.
* @code OI_Printf("File %/", "c:\\dir1\\dir2\\file.txt"); @endcode
*
* \%~ prints a string, escaping characters as needed to display it in
* ASCII. Requires a pointer to an #OI_PSTR and an #OI_UNICODE_ENCODING
* parameter.
* @code OI_Printf("Identifier %~", &id, OI_UNICODE_UTF16_BE); @endcode
*
* \%[ inserts an ANSI color escape sequence. Requires a single character
* identifying the color to select. Colors are red (r/R), green (g/G),
* blue (b/B), yellow (y/Y), cyan (c/C), magenta (m/M), white (W),
* light-gray (l/L), dark-gray (d/D), and black (0). The lower case is
* dim, the upper case is bright (except in the case of light-gray and
* dark-gray, where bright and dim are identical). Any other value will
* select the default color.
* @code OI_Printf("%[red text %[black %[normal\n", 'r', '0', 0); @endcode
*
* \%a same as \%s, except '\\r' and '\\n' are output as "<cr>" and "<lf>".
* \%?a is valid, but \%la is not.
*
* \%b prints an integer in base 2.
* @code OI_Printf("Bits are %b", I); @endcode
*
* \%lb prints a long integer in base 2.
*
* \%?b prints the least significant N bits of an integer (or long integer)
* in base 2. Requires the integer and a length N.
* @code OI_Printf("Bottom 4 bits are: %?b", I, 4); @endcode
*
* \%B prints an integer as boolean text, "TRUE" or "FALSE".
* @code OI_Printf("The value 0 is %B, the value 1 is %B", 0, 1); @endcode
*
* \%?s prints a substring up to a specified maximum length.
* Requires a pointer to a string and a length parameter.
* @code OI_Printf("String prefix is %?s", str, 3); @endcode
*
* \%ls same as \%S.
*
* \%S prints a UTF16 string as UTF8 (plain ASCII, plus 8-bit char sequences
* where needed). Requires a pointer to #OI_CHAR16. \%?S is valid. The
* length parameter is in OI_CHAR16 characters.
*
* \%T prints time, formatted as "secs.msecs".
* Requires pointer to #OI_TIME struct, NULL pointer prints current time.
* @code OI_Printf("The time now is %T", NULL); @endcode
*
* @param format The format string
*
*/
void OI_Printf(const OI_CHAR *format, ...);
/**
* Var-args version OI_Printf
*
* @param format Same as for OI_Printf.
*
* @param argp Var-args list.
*/
void OI_VPrintf(const OI_CHAR *format, va_list argp);
/**
* Writes a formatted string to a buffer. This function supports the same format specifiers as
* OI_Printf().
*
* @param buffer Destination buffer for the formatted string.
*
* @param bufLen The length of the destination buffer.
*
* @param format The format string
*
* @return Number of characters written or -1 in the case of an error.
*/
OI_INT32 OI_SNPrintf(OI_CHAR *buffer,
OI_UINT16 bufLen,
const OI_CHAR *format, ...);
/**
* Var-args version OI_SNPrintf
*
* @param buffer Destination buffer for the formatted string.
*
* @param bufLen The length of the destination buffer.
*
* @param format The format string
*
* @param argp Var-args list.
*
* @return Number of characters written or -1 in the case of an error.
*/
OI_INT32 OI_VSNPrintf(OI_CHAR *buffer,
OI_UINT16 bufLen,
const OI_CHAR *format, va_list argp);
/**
* Convert a string to an integer.
*
* @param str the string to parse
*
* @return the integer value of the string or 0 if the string could not be parsed
*/
OI_INT OI_atoi(const OI_CHAR *str);
/**
* Parse a signed integer in a string.
*
* Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
* must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
* pointer passed in if the string does not describe an integer.
*
* @param str String to parse.
*
* @param val Pointer to receive the parsed integer value.
*
* @return A pointer to the first character following the integer or the pointer passed in.
*/
const OI_CHAR *OI_ScanInt(const OI_CHAR *str,
OI_INT32 *val);
/**
* Parse an unsigned integer in a string.
*
* Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
* must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
* pointer passed in if the string does not describe an integer.
*
* @param str String to parse.
*
* @param val Pointer to receive the parsed unsigned integer value.
*
* @return A pointer to the first character following the unsigned integer or the pointer passed in.
*/
const OI_CHAR *OI_ScanUInt(const OI_CHAR *str,
OI_UINT32 *val);
/**
* Parse a whitespace delimited substring out of a string.
*
* @param str Input string to parse.
* @param outStr Buffer to return the substring
* @param len Length of outStr
*
*
* @return A pointer to the first character following the substring or the pointer passed in.
*/
const OI_CHAR *OI_ScanStr(const OI_CHAR *str,
OI_CHAR *outStr,
OI_UINT16 len);
/**
* Parse a string for one of a set of alternative value. Skips leading whitespace (space and tabs
* only) and parses text matching one of the alternative strings. Returns pointer to first character
* following the matched text.
*
* @param str String to parse.
*
* @param alts Alternative matching strings separated by '|'
*
* @param index Pointer to receive the index of the matching alternative, return value is -1 if
* there is no match.
*
* @return A pointer to the first character following the matched value or the pointer passed in
* if there was no matching text.
*/
const OI_CHAR *OI_ScanAlt(const OI_CHAR *str,
const OI_CHAR *alts,
OI_INT *index);
/**
* Parse a string for a BD Addr. Skips leading whitespace (space and tabs only) and parses a
* Bluetooth device address with nibbles optionally separated by colons. Return pointet to first
* character following the BD Addr.
*
* @param str String to parse.
*
* @param addr Pointer to receive the Bluetooth device address
*
* @return A pointer to the first character following the BD Addr or the pointer passed in.
*/
const OI_CHAR *OI_ScanBdAddr(const OI_CHAR *str,
OI_BD_ADDR *addr);
/** Get a character from a digit integer value (0 - 9). */
#define OI_DigitToChar(d) ((d) + '0')
/**
* Determine Maximum and Minimum between two arguments.
*
* @param a 1st value
* @param b 2nd value
*
* @return the max or min value between a & b
*/
#define OI_MAX(a, b) (((a) < (b)) ? (b) : (a) )
#define OI_MIN(a, b) (((a) > (b)) ? (b) : (a) )
/**
* Compare two BD_ADDRs
* SAME_BD_ADDR - Boolean: TRUE if they are the same address
*/
#define SAME_BD_ADDR(x, y) (0 == OI_MemCmp((x),(y),OI_BD_ADDR_BYTE_SIZE) )
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* _OI_UTILS_H */

View File

@ -0,0 +1,82 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
#include "bt_target.h"
#include <stdlib.h>
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT32 *codecDataAligned,
OI_UINT32 codecDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride)
{
int i;
size_t filterBufferCount;
size_t subdataSize;
OI_BYTE *codecData = (OI_BYTE *)codecDataAligned;
if (maxChannels < 1 || maxChannels > 2) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (pcmStride < 1 || pcmStride > maxChannels) {
return OI_STATUS_INVALID_PARAMETERS;
}
common->maxChannels = maxChannels;
common->pcmStride = pcmStride;
/* Compute sizes needed for the memory regions, and bail if we don't have
* enough memory for them. */
subdataSize = maxChannels * sizeof(common->subdata[0]) * SBC_MAX_BANDS * SBC_MAX_BLOCKS;
if (subdataSize > codecDataBytes) {
return OI_STATUS_OUT_OF_MEMORY;
}
filterBufferCount = (codecDataBytes - subdataSize) / (sizeof(common->filterBuffer[0][0]) * SBC_MAX_BANDS * maxChannels);
if (filterBufferCount < SBC_CODEC_MIN_FILTER_BUFFERS) {
return OI_STATUS_OUT_OF_MEMORY;
}
common->filterBufferLen = filterBufferCount * SBC_MAX_BANDS;
/* Allocate memory for the subband data */
common->subdata = (OI_INT32 *)codecData;
codecData += subdataSize;
OI_ASSERT(codecDataBytes >= subdataSize);
codecDataBytes -= subdataSize;
/* Allocate memory for the synthesis buffers */
for (i = 0; i < maxChannels; ++i) {
size_t allocSize = common->filterBufferLen * sizeof(common->filterBuffer[0][0]);
common->filterBuffer[i] = (SBC_BUFFER_T *)codecData;
OI_ASSERT(codecDataBytes >= allocSize);
codecData += allocSize;
codecDataBytes -= allocSize;
}
return OI_OK;
}
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,168 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
#include "bt_target.h"
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_UINT bitcountL;
OI_UINT bitcountR;
OI_UINT bitpoolPreferenceL = 0;
OI_UINT bitpoolPreferenceR = 0;
BITNEED_UNION1 bitneedsL;
BITNEED_UNION1 bitneedsR;
bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
}
static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
BITNEED_UNION2 bitneeds;
OI_UINT excess;
OI_INT bitadjust;
OI_UINT bitcount;
OI_UINT sbL;
OI_UINT sbR;
OI_UINT bitpoolPreference = 0;
bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, &bitpoolPreference);
{
OI_UINT ex;
bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 2 * nrof_subbands, bitcount, &ex);
/* We want the compiler to put excess into a register */
excess = ex;
}
sbL = 0;
sbR = nrof_subbands;
while (sbL < nrof_subbands) {
excess = allocAdjustedBits(&common->bits.uint8[sbL], bitneeds.uint8[sbL] + bitadjust, excess);
++sbL;
excess = allocAdjustedBits(&common->bits.uint8[sbR], bitneeds.uint8[sbR] + bitadjust, excess);
++sbR;
}
sbL = 0;
sbR = nrof_subbands;
while (excess) {
excess = allocExcessBits(&common->bits.uint8[sbL], excess);
++sbL;
if (!excess) {
break;
}
excess = allocExcessBits(&common->bits.uint8[sbR], excess);
++sbR;
}
}
static const BIT_ALLOC balloc[] = {
monoBitAllocation, /* SBC_MONO */
dualBitAllocation, /* SBC_DUAL_CHANNEL */
stereoBitAllocation, /* SBC_STEREO */
stereoBitAllocation /* SBC_JOINT_STEREO */
};
PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
/*
* Using an array of function pointers prevents the compiler from creating a suboptimal
* monolithic inlined bit allocation function.
*/
balloc[common->frameInfo.mode](common);
}
OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
{
return internal_CalculateBitrate(frame);
}
/*
* Return the current maximum bitneed and clear it.
*/
OI_UINT8 OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
OI_UINT8 max = common->maxBitneed;
common->maxBitneed = 0;
return max;
}
/*
* Calculates the bitpool size for a given frame length
*/
OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
OI_UINT16 frameLen)
{
OI_UINT16 nrof_subbands = frame->nrof_subbands;
OI_UINT16 nrof_blocks = frame->nrof_blocks;
OI_UINT16 hdr;
OI_UINT16 bits;
if (frame->mode == SBC_JOINT_STEREO) {
hdr = 9 * nrof_subbands;
} else {
if (frame->mode == SBC_MONO) {
hdr = 4 * nrof_subbands;
} else {
hdr = 8 * nrof_subbands;
}
if (frame->mode == SBC_DUAL_CHANNEL) {
nrof_blocks *= 2;
}
}
bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr;
return DIVIDE(bits, nrof_blocks);
}
OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
return sizeof(OI_INT16) * common->pcmStride * common->frameInfo.nrof_subbands * common->frameInfo.nrof_blocks;
}
OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
{
return internal_CalculateFramelen(frame);
}
/**@}*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,405 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
The functions in this file relate to the allocation of available bits to
subbands within the SBC/eSBC frame, along with support functions for computing
frame length and bitrate.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include "oi_utils.h"
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame)
{
switch (frame->mode) {
case SBC_MONO:
case SBC_DUAL_CHANNEL:
return 16 * frame->nrof_subbands;
case SBC_STEREO:
case SBC_JOINT_STEREO:
return 32 * frame->nrof_subbands;
}
ERROR(("Invalid frame mode %d", frame->mode));
OI_ASSERT(FALSE);
return 0; /* Should never be reached */
}
PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
{
OI_UINT16 nbits = frame->nrof_blocks * frame->bitpool;
OI_UINT16 nrof_subbands = frame->nrof_subbands;
OI_UINT16 result = nbits;
if (frame->mode == SBC_JOINT_STEREO) {
result += nrof_subbands + (8 * nrof_subbands);
} else {
if (frame->mode == SBC_DUAL_CHANNEL) {
result += nbits;
}
if (frame->mode == SBC_MONO) {
result += 4 * nrof_subbands;
} else {
result += 8 * nrof_subbands;
}
}
return SBC_HEADER_LEN + (result + 7) / 8;
}
PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
{
OI_UINT blocksbands;
blocksbands = frame->nrof_subbands * frame->nrof_blocks;
return DIVIDE(8 * internal_CalculateFramelen(frame) * frame->frequency, blocksbands);
}
INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_)
{
OI_UINT headerLen = SBC_HEADER_LEN + frame->nrof_subbands * frame->nrof_channels / 2;
if (frame->mode == SBC_JOINT_STEREO) {
headerLen++;
}
*headerLen_ = headerLen;
return internal_CalculateFramelen(frame);
}
#define MIN(x, y) ((x) < (y) ? (x) : (y))
/*
* Computes the bit need for each sample and as also returns a counts of bit needs that are greater
* than one. This count is used in the first phase of bit allocation.
*
* We also compute a preferred bitpool value that this is the minimum bitpool needed to guarantee
* lossless representation of the audio data. The preferred bitpool may be larger than the bits
* actually required but the only input we have are the scale factors. For example, it takes 2 bits
* to represent values in the range -1 .. +1 but the scale factor is 0. To guarantee lossless
* representation we add 2 to each scale factor and sum them to come up with the preferred bitpool.
* This is not ideal because 0 requires 0 bits but we currently have no way of knowing this.
*
* @param bitneed Array to return bitneeds for each subband
*
* @param ch Channel 0 or 1
*
* @param preferredBitpool Returns the number of reserved bits
*
* @return The SBC bit need
*
*/
OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
OI_UINT8 *bitneeds,
OI_UINT ch,
OI_UINT *preferredBitpool)
{
static const OI_INT8 offset4[4][4] = {
{ -1, 0, 0, 0 },
{ -2, 0, 0, 1 },
{ -2, 0, 0, 1 },
{ -2, 0, 0, 1 }
};
static const OI_INT8 offset8[4][8] = {
{ -2, 0, 0, 0, 0, 0, 0, 1 },
{ -3, 0, 0, 0, 0, 0, 1, 2 },
{ -4, 0, 0, 0, 0, 0, 1, 2 },
{ -4, 0, 0, 0, 0, 0, 1, 2 }
};
const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
OI_UINT sb;
OI_INT8 *scale_factor = &common->scale_factor[ch ? nrof_subbands : 0];
OI_UINT bitcount = 0;
OI_UINT8 maxBits = 0;
OI_UINT8 prefBits = 0;
if (common->frameInfo.alloc == SBC_SNR) {
for (sb = 0; sb < nrof_subbands; sb++) {
OI_INT bits = scale_factor[sb];
if (bits > maxBits) {
maxBits = bits;
}
if ((bitneeds[sb] = bits) > 1) {
bitcount += bits;
}
prefBits += 2 + bits;
}
} else {
const OI_INT8 *offset;
if (nrof_subbands == 4) {
offset = offset4[common->frameInfo.freqIndex];
} else {
offset = offset8[common->frameInfo.freqIndex];
}
for (sb = 0; sb < nrof_subbands; sb++) {
OI_INT bits = scale_factor[sb];
if (bits > maxBits) {
maxBits = bits;
}
prefBits += 2 + bits;
if (bits) {
bits -= offset[sb];
if (bits > 0) {
bits /= 2;
}
bits += 5;
}
if ((bitneeds[sb] = bits) > 1) {
bitcount += bits;
}
}
}
common->maxBitneed = OI_MAX(maxBits, common->maxBitneed);
*preferredBitpool += prefBits;
return bitcount;
}
/*
* Explanation of the adjustToFitBitpool inner loop.
*
* The inner loop computes the effect of adjusting the bit allocation up or
* down. Allocations must be 0 or in the range 2..16. This is accomplished by
* the following code:
*
* for (s = bands - 1; s >= 0; --s) {
* OI_INT bits = bitadjust + bitneeds[s];
* bits = bits < 2 ? 0 : bits;
* bits = bits > 16 ? 16 : bits;
* count += bits;
* }
*
* This loop can be optimized to perform 4 operations at a time as follows:
*
* Adjustment is computed as a 7 bit signed value and added to the bitneed.
*
* Negative allocations are zeroed by masking. (n & 0x40) >> 6 puts the
* sign bit into bit 0, adding this to 0x7F give us a mask of 0x80
* for -ve values and 0x7F for +ve values.
*
* n &= 0x7F + (n & 0x40) >> 6)
*
* Allocations greater than 16 are truncated to 16. Adjusted allocations are in
* the range 0..31 so we know that bit 4 indicates values >= 16. We use this bit
* to create a mask that zeroes bits 0 .. 3 if bit 4 is set.
*
* n &= (15 + (n >> 4))
*
* Allocations of 1 are disallowed. Add and shift creates a mask that
* eliminates the illegal value
*
* n &= ((n + 14) >> 4) | 0x1E
*
* These operations can be performed in 8 bits without overflowing so we can
* operate on 4 values at once.
*/
/*
* Encoder/Decoder
*
* Computes adjustment +/- of bitneeds to fill bitpool and returns overall
* adjustment and excess bits.
*
* @param bitpool The bitpool we have to work within
*
* @param bitneeds An array of bit needs (more acturately allocation prioritities) for each
* subband across all blocks in the SBC frame
*
* @param subbands The number of subbands over which the adkustment is calculated. For mono and
* dual mode this is 4 or 8, for stereo or joint stereo this is 8 or 16.
*
* @param bitcount A starting point for the adjustment
*
* @param excess Returns the excess bits after the adjustment
*
* @return The adjustment.
*/
OI_INT adjustToFitBitpool(const OI_UINT bitpool,
OI_UINT32 *bitneeds,
const OI_UINT subbands,
OI_UINT bitcount,
OI_UINT *excess)
{
OI_INT maxBitadjust = 0;
OI_INT bitadjust = (bitcount > bitpool) ? -8 : 8;
OI_INT chop = 8;
/*
* This is essentially a binary search for the optimal adjustment value.
*/
while ((bitcount != bitpool) && chop) {
OI_UINT32 total = 0;
OI_UINT count;
OI_UINT32 adjust4;
OI_INT i;
adjust4 = bitadjust & 0x7F;
adjust4 |= (adjust4 << 8);
adjust4 |= (adjust4 << 16);
for (i = (subbands / 4 - 1); i >= 0; --i) {
OI_UINT32 mask;
OI_UINT32 n = bitneeds[i] + adjust4;
mask = 0x7F7F7F7F + ((n & 0x40404040) >> 6);
n &= mask;
mask = 0x0F0F0F0F + ((n & 0x10101010) >> 4);
n &= mask;
mask = (((n + 0x0E0E0E0E) >> 4) | 0x1E1E1E1E);
n &= mask;
total += n;
}
count = (total & 0xFFFF) + (total >> 16);
count = (count & 0xFF) + (count >> 8);
chop >>= 1;
if (count > bitpool) {
bitadjust -= chop;
} else {
maxBitadjust = bitadjust;
bitcount = count;
bitadjust += chop;
}
}
*excess = bitpool - bitcount;
return maxBitadjust;
}
/*
* The bit allocator trys to avoid single bit allocations except as a last resort. So in the case
* where a bitneed of 1 was passed over during the adsjustment phase 2 bits are now allocated.
*/
INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
OI_INT bits,
OI_INT excess)
{
if (bits < 16) {
if (bits > 1) {
if (excess) {
++bits;
--excess;
}
} else if ((bits == 1) && (excess > 1)) {
bits = 2;
excess -= 2;
} else {
bits = 0;
}
} else {
bits = 16;
}
*dest = (OI_UINT8)bits;
return excess;
}
/*
* Excess bits not allocated by allocaAdjustedBits are allocated round-robin.
*/
INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
OI_INT excess)
{
if (*dest < 16) {
*dest += 1;
return excess - 1;
} else {
return excess;
}
}
void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
BITNEED_UNION1 *bitneeds,
OI_UINT ch,
OI_UINT bitcount)
{
const OI_UINT8 nrof_subbands = common->frameInfo.nrof_subbands;
OI_UINT excess;
OI_UINT sb;
OI_INT bitadjust;
OI_UINT8 RESTRICT *allocBits;
{
OI_UINT ex;
bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds->uint32, nrof_subbands, bitcount, &ex);
/* We want the compiler to put excess into a register */
excess = ex;
}
/*
* Allocate adjusted bits
*/
allocBits = &common->bits.uint8[ch ? nrof_subbands : 0];
sb = 0;
while (sb < nrof_subbands) {
excess = allocAdjustedBits(&allocBits[sb], bitneeds->uint8[sb] + bitadjust, excess);
++sb;
}
sb = 0;
while (excess) {
excess = allocExcessBits(&allocBits[sb], excess);
++sb;
}
}
void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
{
BITNEED_UNION1 bitneeds;
OI_UINT bitcount;
OI_UINT bitpoolPreference = 0;
bitcount = computeBitneed(common, bitneeds.uint8, 0, &bitpoolPreference);
oneChannelBitAllocation(common, &bitneeds, 0, bitcount);
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,95 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Functions for manipulating input bitstreams.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include "oi_stddefs.h"
#include "oi_bitstream.h"
#include "oi_assert.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
PRIVATE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs,
const OI_BYTE *buffer)
{
bs->value = ((OI_INT32)buffer[0] << 16) | ((OI_INT32)buffer[1] << 8) | (buffer[2]);
bs->ptr.r = buffer + 3;
bs->bitPtr = 8;
}
PRIVATE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits)
{
OI_UINT32 result;
OI_BITSTREAM_READUINT(result, bits, bs->ptr.r, bs->value, bs->bitPtr);
return result;
}
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs)
{
OI_UINT32 result;
OI_ASSERT(bs->bitPtr < 16);
OI_ASSERT(bs->bitPtr % 4 == 0);
if (bs->bitPtr == 8) {
result = bs->value << 8;
bs->bitPtr = 12;
} else {
result = bs->value << 12;
bs->value = (bs->value << 8) | *bs->ptr.r++;
bs->bitPtr = 8;
}
result >>= 28;
OI_ASSERT(result < (1u << 4));
return (OI_UINT8)result;
}
PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs)
{
OI_UINT32 result;
OI_ASSERT(bs->bitPtr == 8);
result = bs->value >> 16;
bs->value = (bs->value << 8) | *bs->ptr.r++;
return (OI_UINT8)result;
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,141 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2006 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
This file exposes OINA-specific interfaces to decoder functions.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 frequency,
OI_UINT8 mode,
OI_UINT8 subbands,
OI_UINT8 blocks,
OI_UINT8 alloc,
OI_UINT8 maxBitpool)
{
if (frequency > SBC_FREQ_48000) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (enhanced) {
#ifdef SBC_ENHANCED
if (subbands != SBC_SUBBANDS_8) {
return OI_STATUS_INVALID_PARAMETERS;
}
#else
return OI_STATUS_INVALID_PARAMETERS;
#endif
}
if (mode > SBC_JOINT_STEREO) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (subbands > SBC_SUBBANDS_8) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (blocks > SBC_BLOCKS_16) {
return OI_STATUS_INVALID_PARAMETERS;
}
if (alloc > SBC_SNR) {
return OI_STATUS_INVALID_PARAMETERS;
}
#ifdef SBC_ENHANCED
context->common.frameInfo.enhanced = enhanced;
#else
context->common.frameInfo.enhanced = FALSE;
#endif
context->common.frameInfo.freqIndex = frequency;
context->common.frameInfo.mode = mode;
context->common.frameInfo.subbands = subbands;
context->common.frameInfo.blocks = blocks;
context->common.frameInfo.alloc = alloc;
context->common.frameInfo.bitpool = maxBitpool;
OI_SBC_ExpandFrameFields(&context->common.frameInfo);
if (context->common.frameInfo.nrof_channels >= context->common.pcmStride) {
return OI_STATUS_INVALID_PARAMETERS;
}
return OI_OK;
}
OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
return internal_DecodeRaw(context,
bitpool,
frameData,
frameBytes,
pcmData,
pcmBytes);
}
OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_BOOL enhanced,
OI_UINT8 subbands)
{
if (enhanced) {
#ifdef SBC_ENHANCED
context->enhancedEnabled = TRUE;
#else
context->enhancedEnabled = FALSE;
#endif
} else {
context->enhancedEnabled = FALSE;
}
context->restrictSubbands = subbands;
context->limitFrameFormat = TRUE;
return OI_OK;
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,229 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
This file drives SBC decoding.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#include "oi_bitstream.h"
#include <stdio.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
OI_CHAR *const OI_Codec_Copyright = "Copyright 2002-2007 Open Interface North America, Inc. All rights reserved";
INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_BYTE maxChannels,
OI_BYTE pcmStride,
OI_BOOL enhanced)
{
OI_UINT i;
OI_STATUS status;
for (i = 0; i < sizeof(*context); i++) {
((char *)context)[i] = 0;
}
#ifdef SBC_ENHANCED
context->enhancedEnabled = enhanced ? TRUE : FALSE;
#else
context->enhancedEnabled = FALSE;
if (enhanced) {
return OI_STATUS_INVALID_PARAMETERS;
}
#endif
status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride);
if (!OI_SUCCESS(status)) {
return status;
}
context->common.codecInfo = OI_Codec_Copyright;
context->common.maxBitneed = 0;
context->limitFrameFormat = FALSE;
OI_SBC_ExpandFrameFields(&context->common.frameInfo);
/*PLATFORM_DECODER_RESET(context);*/
return OI_OK;
}
/**
* Read the SBC header up to but not including the joint stereo mask. The syncword has already been
* examined, and the enhanced mode flag set, by FindSyncword.
*/
INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data)
{
OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo;
OI_UINT8 d1;
OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
/* Avoid filling out all these strucutures if we already remember the values
* from last time. Just in case we get a stream corresponding to data[1] ==
* 0, DecoderReset is responsible for ensuring the lookup table entries have
* already been populated
*/
d1 = data[1];
if (d1 != frame->cachedInfo) {
frame->freqIndex = (d1 & (BIT7 | BIT6)) >> 6;
frame->frequency = freq_values[frame->freqIndex];
frame->blocks = (d1 & (BIT5 | BIT4)) >> 4;
frame->nrof_blocks = block_values[frame->blocks];
frame->mode = (d1 & (BIT3 | BIT2)) >> 2;
frame->nrof_channels = channel_values[frame->mode];
frame->alloc = (d1 & BIT1) >> 1;
frame->subbands = (d1 & BIT0);
frame->nrof_subbands = band_values[frame->subbands];
frame->cachedInfo = d1;
}
/*
* For decode, the bit allocator needs to know the bitpool value
*/
frame->bitpool = data[2];
frame->crc = data[3];
}
#define LOW(x) ((x)& 0xf)
#define HIGH(x) ((x) >> 4)
/*
* Read scalefactor values and prepare the bitstream for OI_SBC_ReadSamples
*/
PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common,
const OI_BYTE *b,
OI_BITSTREAM *bs)
{
OI_UINT i = common->frameInfo.nrof_subbands * common->frameInfo.nrof_channels;
OI_INT8 *scale_factor = common->scale_factor;
OI_UINT f;
if (common->frameInfo.nrof_subbands == 8 || common->frameInfo.mode != SBC_JOINT_STEREO) {
if (common->frameInfo.mode == SBC_JOINT_STEREO) {
common->frameInfo.join = *b++;
} else {
common->frameInfo.join = 0;
}
i /= 2;
do {
*scale_factor++ = HIGH(f = *b++);
*scale_factor++ = LOW(f);
} while (--i);
/*
* In this case we know that the scale factors end on a byte boundary so all we need to do
* is initialize the bitstream.
*/
OI_BITSTREAM_ReadInit(bs, b);
} else {
OI_ASSERT(common->frameInfo.nrof_subbands == 4 && common->frameInfo.mode == SBC_JOINT_STEREO);
common->frameInfo.join = HIGH(f = *b++);
i = (i - 1) / 2;
do {
*scale_factor++ = LOW(f);
*scale_factor++ = HIGH(f = *b++);
} while (--i);
*scale_factor++ = LOW(f);
/*
* In 4-subband joint stereo mode, the joint stereo information ends on a half-byte
* boundary, so it's necessary to use the bitstream abstraction to read it, since
* OI_SBC_ReadSamples will need to pick up in mid-byte.
*/
OI_BITSTREAM_ReadInit(bs, b);
*scale_factor++ = OI_BITSTREAM_ReadUINT4Aligned(bs);
}
}
/** Read quantized subband samples from the input bitstream and expand them. */
PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT nrof_blocks = common->frameInfo.nrof_blocks;
OI_INT32 *RESTRICT s = common->subdata;
OI_UINT8 *ptr = global_bs->ptr.w;
OI_UINT32 value = global_bs->value;
OI_UINT bitPtr = global_bs->bitPtr;
const OI_UINT iter_count = common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands / 4;
do {
OI_UINT i;
for (i = 0; i < iter_count; ++i) {
OI_UINT32 sf_by4 = ((OI_UINT32 *)common->scale_factor)[i];
OI_UINT32 bits_by4 = common->bits.uint32[i];
OI_UINT n;
for (n = 0; n < 4; ++n) {
OI_INT32 dequant;
OI_UINT bits;
OI_INT sf;
if (OI_CPU_BYTE_ORDER == OI_LITTLE_ENDIAN_BYTE_ORDER) {
bits = bits_by4 & 0xFF;
bits_by4 >>= 8;
sf = sf_by4 & 0xFF;
sf_by4 >>= 8;
} else {
bits = (bits_by4 >> 24) & 0xFF;
bits_by4 <<= 8;
sf = (sf_by4 >> 24) & 0xFF;
sf_by4 <<= 8;
}
if (bits) {
OI_UINT32 raw;
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
dequant = OI_SBC_Dequant(raw, sf, bits);
} else {
dequant = 0;
}
*s++ = dequant;
}
}
} while (--nrof_blocks);
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,469 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2006 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addtogroup codec_internal */
/**@{*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#include "oi_bitstream.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
#define SPECIALIZE_READ_SAMPLES_JOINT
/**
* Scans through a buffer looking for a codec syncword. If the decoder has been
* set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
* for both a standard and an enhanced syncword.
*/
PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes)
{
#ifdef SBC_ENHANCED
OI_BYTE search1 = OI_SBC_SYNCWORD;
OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
#endif // SBC_ENHANCED
if (*frameBytes == 0) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
#ifdef SBC_ENHANCED
if (context->limitFrameFormat && context->enhancedEnabled) {
/* If the context is restricted, only search for specified SYNCWORD */
search1 = search2;
} else if (context->enhancedEnabled == FALSE) {
/* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
search2 = search1;
}
while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
(*frameBytes)--;
(*frameData)++;
}
if (*frameBytes) {
/* Syncword found, *frameData points to it, and *frameBytes correctly
* reflects the number of bytes available to read, including the
* syncword. */
context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
return OI_OK;
} else {
/* No syncword was found anywhere in the provided input data.
* *frameData points past the end of the original input, and
* *frameBytes is 0. */
return OI_CODEC_SBC_NO_SYNCWORD;
}
#else // SBC_ENHANCED
while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
(*frameBytes)--;
(*frameData)++;
}
if (*frameBytes) {
/* Syncword found, *frameData points to it, and *frameBytes correctly
* reflects the number of bytes available to read, including the
* syncword. */
context->common.frameInfo.enhanced = FALSE;
return OI_OK;
} else {
/* No syncword was found anywhere in the provided input data.
* *frameData points past the end of the original input, and
* *frameBytes is 0. */
return OI_CODEC_SBC_NO_SYNCWORD;
}
#endif // SBC_ENHANCED
}
static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE *bodyData,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes,
OI_BOOL allowPartial)
{
OI_BITSTREAM bs;
OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
OI_UINT decode_block_count;
/*
* Based on the header data, make sure that there is enough room to write the output samples.
*/
if (*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride) && !allowPartial) {
/* If we're not allowing partial decodes, we need room for the entire
* codec frame */
TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
} else if (*pcmBytes < sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride) {
/* Even if we're allowing partials, we can still only decode on a frame
* boundary */
return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
}
if (context->bufferedBlocks == 0) {
TRACE(("Reading scalefactors"));
OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
TRACE(("Computing bit allocation"));
OI_SBC_ComputeBitAllocation(&context->common);
TRACE(("Reading samples"));
if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
OI_SBC_ReadSamplesJoint(context, &bs);
} else {
OI_SBC_ReadSamples(context, &bs);
}
context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
}
if (allowPartial) {
decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands;
if (decode_block_count > context->bufferedBlocks) {
decode_block_count = context->bufferedBlocks;
}
} else {
decode_block_count = context->common.frameInfo.nrof_blocks;
}
TRACE(("Synthesizing frame"));
{
OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
}
OI_ASSERT(context->bufferedBlocks >= decode_block_count);
context->bufferedBlocks -= decode_block_count;
frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
/*
* When decoding mono into a stride-2 array, copy pcm data to second channel
*/
if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) {
OI_UINT i;
for (i = 0; i < frameSamples; ++i) {
pcmData[2 * i + 1] = pcmData[2 * i];
}
}
/*
* Return number of pcm bytes generated by the decode operation.
*/
*pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride;
if (context->bufferedBlocks > 0) {
return OI_CODEC_SBC_PARTIAL_DECODE;
} else {
return OI_OK;
}
}
PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT8 bitpool,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
OI_STATUS status;
OI_UINT bodyLen;
TRACE(("+OI_CODEC_SBC_DecodeRaw"));
if (context->bufferedBlocks == 0) {
/*
* The bitallocator needs to know the bitpool value.
*/
context->common.frameInfo.bitpool = bitpool;
/*
* Compute the frame length and check we have enough frame data to proceed
*/
bodyLen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo) - SBC_HEADER_LEN;
if (*frameBytes < bodyLen) {
TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
} else {
bodyLen = 0;
}
/*
* Decode the SBC data. Pass TRUE to DecodeBody to allow partial decoding of
* tones.
*/
status = DecodeBody(context, *frameData, pcmData, pcmBytes, TRUE);
if (OI_SUCCESS(status) || status == OI_CODEC_SBC_PARTIAL_DECODE) {
*frameData += bodyLen;
*frameBytes -= bodyLen;
}
TRACE(("-OI_CODEC_SBC_DecodeRaw: %d", status));
return status;
}
OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
OI_UINT32 *decoderData,
OI_UINT32 decoderDataBytes,
OI_UINT8 maxChannels,
OI_UINT8 pcmStride,
OI_BOOL enhanced)
{
return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
}
OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes,
OI_INT16 *pcmData,
OI_UINT32 *pcmBytes)
{
OI_STATUS status;
OI_UINT framelen;
OI_UINT8 crc;
TRACE(("+OI_CODEC_SBC_DecodeFrame"));
TRACE(("Finding syncword"));
status = FindSyncword(context, frameData, frameBytes);
if (!OI_SUCCESS(status)) {
return status;
}
/* Make sure enough data remains to read the header. */
if (*frameBytes < SBC_HEADER_LEN) {
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
TRACE(("Reading Header"));
OI_SBC_ReadHeader(&context->common, *frameData);
/*
* Some implementations load the decoder into RAM and use overlays for 4 vs 8 subbands. We need
* to ensure that the SBC parameters for this frame are compatible with the restrictions imposed
* by the loaded overlays.
*/
if (context->limitFrameFormat && (context->common.frameInfo.subbands != context->restrictSubbands)) {
ERROR(("SBC parameters incompatible with loaded overlay"));
return OI_STATUS_INVALID_PARAMETERS;
}
if (context->common.frameInfo.nrof_channels > context->common.maxChannels) {
ERROR(("SBC parameters incompatible with number of channels specified during reset"));
return OI_STATUS_INVALID_PARAMETERS;
}
if (context->common.pcmStride < 1 || context->common.pcmStride > 2) {
ERROR(("PCM stride not set correctly during reset"));
return OI_STATUS_INVALID_PARAMETERS;
}
/*
* At this point a header has been read. However, it's possible that we found a false syncword,
* so the header data might be invalid. Make sure we have enough bytes to read in the
* CRC-protected header, but don't require we have the whole frame. That way, if it turns out
* that we're acting on bogus header data, we don't stall the decoding process by waiting for
* data that we don't actually need.
*/
framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
if (*frameBytes < framelen) {
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
TRACE(("Calculating checksum"));
crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
if (crc != context->common.frameInfo.crc) {
TRACE(("CRC Mismatch: calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
return OI_CODEC_SBC_CHECKSUM_MISMATCH;
}
#ifdef OI_DEBUG
/*
* Make sure the bitpool values are sane.
*/
if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) && !context->common.frameInfo.enhanced) {
ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
return OI_STATUS_INVALID_PARAMETERS;
}
if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
return OI_STATUS_INVALID_PARAMETERS;
}
#endif
/*
* Now decode the SBC data. Partial decode is not yet implemented for an SBC
* stream, so pass FALSE to decode body to have it enforce the old rule that
* you have to decode a whole packet at a time.
*/
status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
if (OI_SUCCESS(status)) {
*frameData += framelen;
*frameBytes -= framelen;
}
TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
return status;
}
OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
const OI_BYTE **frameData,
OI_UINT32 *frameBytes)
{
OI_STATUS status;
OI_UINT framelen;
OI_UINT headerlen;
OI_UINT8 crc;
status = FindSyncword(context, frameData, frameBytes);
if (!OI_SUCCESS(status)) {
return status;
}
if (*frameBytes < SBC_HEADER_LEN) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
OI_SBC_ReadHeader(&context->common, *frameData);
framelen = OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
if (*frameBytes < headerlen) {
return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
}
crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
if (crc != context->common.frameInfo.crc) {
return OI_CODEC_SBC_CHECKSUM_MISMATCH;
}
if (*frameBytes < framelen) {
return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
}
context->bufferedBlocks = 0;
*frameData += framelen;
*frameBytes -= framelen;
return OI_OK;
}
OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE *frameData,
OI_UINT32 frameBytes)
{
OI_UINT8 mode;
OI_UINT8 blocks;
OI_UINT8 subbands;
OI_UINT8 frameCount = 0;
OI_UINT frameLen;
while (frameBytes) {
while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)) {
frameData++;
frameBytes--;
}
if (frameBytes < SBC_HEADER_LEN) {
return frameCount;
}
/* Extract and translate required fields from Header */
subbands = mode = blocks = frameData[1];;
mode = (mode & (BIT3 | BIT2)) >> 2;
blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
subbands = band_values[(subbands & BIT0)];
/* Inline logic to avoid corrupting context */
frameLen = blocks * frameData[2];
switch (mode) {
case SBC_JOINT_STEREO:
frameLen += subbands + (8 * subbands);
break;
case SBC_DUAL_CHANNEL:
frameLen *= 2;
/* fall through */
default:
if (mode == SBC_MONO) {
frameLen += 4 * subbands;
} else {
frameLen += 8 * subbands;
}
}
frameCount++;
frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
if (frameBytes > frameLen) {
frameBytes -= frameLen;
frameData += frameLen;
} else {
frameBytes = 0;
}
}
return frameCount;
}
/** Read quantized subband samples from the input bitstream and expand them. */
#ifdef SPECIALIZE_READ_SAMPLES_JOINT
PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 4
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 8
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
static const READ_SAMPLES SpecializedReadSamples[] = {
OI_SBC_ReadSamplesJoint4,
OI_SBC_ReadSamplesJoint8
};
#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
#ifdef SPECIALIZE_READ_SAMPLES_JOINT
OI_ASSERT((nrof_subbands >> 3u) <= 1u);
SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
#else
#define NROF_SUBBANDS nrof_subbands
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
}
/**@}*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,215 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Dequantizer for SBC decoder; reconstructs quantized representation of subband samples.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
/**
This function is a fixed-point approximation of a modification of the following
dequantization operation defined in the spec, as inferred from section 12.6.4:
@code
dequant = 2^(scale_factor+1) * ((raw * 2.0 + 1.0) / ((2^bits) - 1) - 1)
2 <= bits <= 16
0 <= raw < (2^bits)-1 (the -1 is because quantized values with all 1's are forbidden)
-65535 < dequant < 65535
@endcode
The code below computes the dequantized value divided by a scaling constant
equal to about 1.38. This constant is chosen to ensure that the entry in the
dequant_long_scaled table for 16 bits is as accurate as possible, since it has
the least relative precision available to it due to its small magnitude.
This routine outputs in Q16.15 format.
The helper array dequant_long is defined as follows:
@code
dequant_long_long[bits] = round(2^31 * 1/((2^bits - 1) / 1.38...) for 2 <= bits <= 16
@endcode
Additionally, the table entries have the following property:
@code
dequant_long_scaled[bits] <= 2^31 / ((2^bits - 1)) for 2 <= bits <= 16
@endcode
Therefore
@code
d = 2 * raw + 1 1 <= d <= 2^bits - 2
d' = d * dequant_long[bits]
d * dequant_long_scaled[bits] <= (2^bits - 2) * (2^31 / (2^bits - 1))
d * dequant_long_scaled[bits] <= 2^31 * (2^bits - 2)/(2^bits - 1) < 2^31
@endcode
Therefore, d' doesn't overflow a signed 32-bit value.
@code
d' =~ 2^31 * (raw * 2.0 + 1.0) / (2^bits - 1) / 1.38...
result = d' - 2^31/1.38... =~ 2^31 * ((raw * 2.0 + 1.0) / (2^bits - 1) - 1) / 1.38...
result is therefore a scaled approximation to dequant. It remains only to
turn 2^31 into 2^(scale_factor+1). Since we're aiming for Q16.15 format,
this is achieved by shifting right by (15-scale_factor):
(2^31 * x) >> (15-scale_factor) =~ 2^(31-15+scale_factor) * x = 2^15 * 2^(1+scale_factor) * x
@endcode
*/
#include "bt_target.h"
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
#ifndef SBC_DEQUANT_LONG_SCALED_OFFSET
#define SBC_DEQUANT_LONG_SCALED_OFFSET 1555931970
#endif
#ifndef SBC_DEQUANT_LONG_UNSCALED_OFFSET
#define SBC_DEQUANT_LONG_UNSCALED_OFFSET 2147483648
#endif
#ifndef SBC_DEQUANT_SCALING_FACTOR
#define SBC_DEQUANT_SCALING_FACTOR 1.38019122262781f
#endif
const OI_UINT32 dequant_long_scaled[17];
const OI_UINT32 dequant_long_unscaled[17];
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
#ifdef DEBUG_DEQUANTIZATION
#include <math.h>
INLINE float dequant_float(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
float result = (1 << (scale_factor + 1)) * ((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f);
result /= SBC_DEQUANT_SCALING_FACTOR;
/* Unless the encoder screwed up, all correct dequantized values should
* satisfy this inequality. Non-compliant encoders which generate quantized
* values with all 1-bits set can, theoretically, trigger this assert. This
* is unlikely, however, and only an issue in debug mode.
*/
OI_ASSERT(fabs(result) < 32768 * 1.6);
return result;
}
#endif
INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
OI_UINT32 d;
OI_INT32 result;
OI_ASSERT(scale_factor <= 15);
OI_ASSERT(bits <= 16);
if (bits <= 1) {
return 0;
}
d = (raw * 2) + 1;
d *= dequant_long_scaled[bits];
result = d - SBC_DEQUANT_LONG_SCALED_OFFSET;
#ifdef DEBUG_DEQUANTIZATION
{
OI_INT32 integerized_float_result;
float float_result;
float_result = dequant_float(raw, scale_factor, bits);
integerized_float_result = (OI_INT32)floor(0.5f + float_result * (1 << 15));
/* This detects overflow */
OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) ||
((result <= 0) && (integerized_float_result <= 0)));
}
#endif
return result >> (15 - scale_factor);
}
/* This version of Dequant does not incorporate the scaling factor of 1.38. It
* is intended for use with implementations of the filterbank which are
* hard-coded into a DSP. Output is Q16.4 format, so that after joint stereo
* processing (which leaves the most significant bit equal to the sign bit if
* the encoder is conformant) the result will fit a 24 bit fixed point signed
* value.*/
INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
{
OI_UINT32 d;
OI_INT32 result;
OI_ASSERT(scale_factor <= 15);
OI_ASSERT(bits <= 16);
if (bits <= 1) {
return 0;
}
if (bits == 16) {
result = (raw << 16) + raw - 0x7fff7fff;
return SCALE(result, 24 - scale_factor);
}
d = (raw * 2) + 1;
d *= dequant_long_unscaled[bits];
result = d - 0x80000000;
return SCALE(result, 24 - scale_factor);
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,59 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
const OI_CHAR *const OI_CODEC_SBC_FreqText[] = { "SBC_FREQ_16000", "SBC_FREQ_32000", "SBC_FREQ_44100", "SBC_FREQ_48000" };
const OI_CHAR *const OI_CODEC_SBC_ModeText[] = { "SBC_MONO", "SBC_DUAL_CHANNEL", "SBC_STEREO", "SBC_JOINT_STEREO" };
const OI_CHAR *const OI_CODEC_SBC_SubbandsText[] = { "SBC_SUBBANDS_4", "SBC_SUBBANDS_8" };
const OI_CHAR *const OI_CODEC_SBC_BlocksText[] = { "SBC_BLOCKS_4", "SBC_BLOCKS_8", "SBC_BLOCKS_12", "SBC_BLOCKS_16" };
const OI_CHAR *const OI_CODEC_SBC_AllocText[] = { "SBC_LOUDNESS", "SBC_SNR" };
#ifdef OI_DEBUG
void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo)
{
printf("SBC configuration\n");
printf(" enhanced: %s\n", frameInfo->enhanced ? "TRUE" : "FALSE");
printf(" frequency: %d\n", frameInfo->frequency);
printf(" subbands: %d\n", frameInfo->nrof_subbands);
printf(" blocks: %d\n", frameInfo->nrof_blocks);
printf(" channels: %d\n", frameInfo->nrof_channels);
printf(" mode: %s\n", OI_CODEC_SBC_ModeText[frameInfo->mode]);
printf(" alloc: %s\n", OI_CODEC_SBC_AllocText[frameInfo->alloc]);
printf(" bitpool: %d\n", frameInfo->bitpool);
}
#endif /* OI_DEBUG */
/**@}*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,253 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/**
@file
Checksum and header-related functions.
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#include "oi_assert.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
/* asdasd */
#define USE_NIBBLEWISE_CRC
/* #define PRINT_SAMPLES */
/* #define PRINT_SCALEFACTORS */
/* #define DEBUG_CRC */
/*
* CRC-8 table for X^8 + X^4 + X^3 + X^2 + 1; byte-wise lookup
*/
#ifdef USE_WIDE_CRC
/* Save space if a char is 16 bits, such as on the C54x */
const OI_BYTE crc8_wide[128] = {
0x001d, 0x3a27, 0x7469, 0x4e53, 0xe8f5, 0xd2cf, 0x9c81, 0xa6bb, 0xcdd0, 0xf7ea, 0xb9a4, 0x839e, 0x2538, 0x1f02, 0x514c, 0x6b76, 0x879a, 0xbda0, 0xf3ee, 0xc9d4, 0x6f72, 0x5548, 0x1b06, 0x213c, 0x4a57, 0x706d, 0x3e23, 0x0419, 0xa2bf, 0x9885, 0xd6cb, 0xecf1, 0x130e, 0x2934, 0x677a, 0x5d40, 0xfbe6, 0xc1dc, 0x8f92, 0xb5a8, 0xdec3, 0xe4f9, 0xaab7, 0x908d, 0x362b, 0x0c11, 0x425f, 0x7865, 0x9489, 0xaeb3, 0xe0fd, 0xdac7, 0x7c61, 0x465b, 0x0815, 0x322f, 0x5944, 0x637e, 0x2d30, 0x170a, 0xb1ac, 0x8b96, 0xc5d8, 0xffe2, 0x263b, 0x1c01, 0x524f, 0x6875, 0xced3, 0xf4e9, 0xbaa7, 0x809d, 0xebf6, 0xd1cc, 0x9f82, 0xa5b8, 0x031e, 0x3924, 0x776a, 0x4d50, 0xa1bc, 0x9b86, 0xd5c8, 0xeff2, 0x4954, 0x736e, 0x3d20, 0x071a, 0x6c71, 0x564b, 0x1805, 0x223f, 0x8499, 0xbea3, 0xf0ed, 0xcad7, 0x3528, 0x0f12, 0x415c, 0x7b66, 0xddc0, 0xe7fa, 0xa9b4, 0x938e, 0xf8e5, 0xc2df, 0x8c91, 0xb6ab, 0x100d, 0x2a37, 0x6479, 0x5e43, 0xb2af, 0x8895, 0xc6db, 0xfce1, 0x5a47, 0x607d, 0x2e33, 0x1409, 0x7f62, 0x4558, 0x0b16, 0x312c, 0x978a, 0xadb0, 0xe3fe, 0xd9c4,
};
#elif defined(USE_NIBBLEWISE_CRC)
const OI_BYTE crc8_narrow[16] = {
0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb
};
#else
const OI_BYTE crc8_narrow[256] = {
0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb, 0xcd, 0xd0, 0xf7, 0xea, 0xb9, 0xa4, 0x83, 0x9e, 0x25, 0x38, 0x1f, 0x02, 0x51, 0x4c, 0x6b, 0x76, 0x87, 0x9a, 0xbd, 0xa0, 0xf3, 0xee, 0xc9, 0xd4, 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x06, 0x21, 0x3c, 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x04, 0x19, 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1, 0x13, 0x0e, 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40, 0xfb, 0xe6, 0xc1, 0xdc, 0x8f, 0x92, 0xb5, 0xa8, 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, 0x90, 0x8d, 0x36, 0x2b, 0x0c, 0x11, 0x42, 0x5f, 0x78, 0x65, 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7, 0x7c, 0x61, 0x46, 0x5b, 0x08, 0x15, 0x32, 0x2f, 0x59, 0x44, 0x63, 0x7e, 0x2d, 0x30, 0x17, 0x0a, 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, 0xff, 0xe2, 0x26, 0x3b, 0x1c, 0x01, 0x52, 0x4f, 0x68, 0x75, 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d, 0xeb, 0xf6, 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8, 0x03, 0x1e, 0x39, 0x24, 0x77, 0x6a, 0x4d, 0x50, 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, 0xef, 0xf2, 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x07, 0x1a, 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x05, 0x22, 0x3f, 0x84, 0x99, 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7, 0x35, 0x28, 0x0f, 0x12, 0x41, 0x5c, 0x7b, 0x66, 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, 0x93, 0x8e, 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab, 0x10, 0x0d, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43, 0xb2, 0xaf, 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1, 0x5a, 0x47, 0x60, 0x7d, 0x2e, 0x33, 0x14, 0x09, 0x7f, 0x62, 0x45, 0x58, 0x0b, 0x16, 0x31, 0x2c, 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4
};
#endif
const OI_UINT32 dequant_long_scaled[17] = {
0,
0,
0x1ee9e116, /* bits=2 0.24151243 1/3 * (1/1.38019122262781) (0x00000008)*/
0x0d3fa99c, /* bits=3 0.10350533 1/7 * (1/1.38019122262781) (0x00000013)*/
0x062ec69e, /* bits=4 0.04830249 1/15 * (1/1.38019122262781) (0x00000029)*/
0x02fddbfa, /* bits=5 0.02337217 1/31 * (1/1.38019122262781) (0x00000055)*/
0x0178d9f5, /* bits=6 0.01150059 1/63 * (1/1.38019122262781) (0x000000ad)*/
0x00baf129, /* bits=7 0.00570502 1/127 * (1/1.38019122262781) (0x0000015e)*/
0x005d1abe, /* bits=8 0.00284132 1/255 * (1/1.38019122262781) (0x000002bf)*/
0x002e760d, /* bits=9 0.00141788 1/511 * (1/1.38019122262781) (0x00000582)*/
0x00173536, /* bits=10 0.00070825 1/1023 * (1/1.38019122262781) (0x00000b07)*/
0x000b9928, /* bits=11 0.00035395 1/2047 * (1/1.38019122262781) (0x00001612)*/
0x0005cc37, /* bits=12 0.00017693 1/4095 * (1/1.38019122262781) (0x00002c27)*/
0x0002e604, /* bits=13 0.00008846 1/8191 * (1/1.38019122262781) (0x00005852)*/
0x000172fc, /* bits=14 0.00004422 1/16383 * (1/1.38019122262781) (0x0000b0a7)*/
0x0000b97d, /* bits=15 0.00002211 1/32767 * (1/1.38019122262781) (0x00016150)*/
0x00005cbe, /* bits=16 0.00001106 1/65535 * (1/1.38019122262781) (0x0002c2a5)*/
};
const OI_UINT32 dequant_long_unscaled[17] = {
0,
0,
0x2aaaaaab, /* bits=2 0.33333333 1/3 (0x00000005)*/
0x12492492, /* bits=3 0.14285714 1/7 (0x0000000e)*/
0x08888889, /* bits=4 0.06666667 1/15 (0x0000001d)*/
0x04210842, /* bits=5 0.03225806 1/31 (0x0000003e)*/
0x02082082, /* bits=6 0.01587302 1/63 (0x0000007e)*/
0x01020408, /* bits=7 0.00787402 1/127 (0x000000fe)*/
0x00808081, /* bits=8 0.00392157 1/255 (0x000001fd)*/
0x00402010, /* bits=9 0.00195695 1/511 (0x000003fe)*/
0x00200802, /* bits=10 0.00097752 1/1023 (0x000007fe)*/
0x00100200, /* bits=11 0.00048852 1/2047 (0x00000ffe)*/
0x00080080, /* bits=12 0.00024420 1/4095 (0x00001ffe)*/
0x00040020, /* bits=13 0.00012209 1/8191 (0x00003ffe)*/
0x00020008, /* bits=14 0.00006104 1/16383 (0x00007ffe)*/
0x00010002, /* bits=15 0.00003052 1/32767 (0x0000fffe)*/
0x00008001, /* bits=16 0.00001526 1/65535 (0x0001fffc)*/
};
#if defined(OI_DEBUG) || defined(PRINT_SAMPLES) || defined(PRINT_SCALEFACTORS)
#include <stdio.h>
#endif
#ifdef USE_WIDE_CRC
INLINE OI_CHAR crc_iterate(OI_UINT8 oldcrc, OI_UINT8 next)
{
OI_UINT crc;
OI_UINT idx;
idx = oldcrc ^ next;
crc = crc8_wide[idx >> 1];
if (idx % 2) {
crc &= 0xff;
} else {
crc >>= 8;
}
return crc;
}
INLINE OI_CHAR crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
{
OI_UINT crc;
OI_UINT idx;
idx = (oldcrc ^ next) >> 4;
crc = crc8_wide[idx >> 1];
if (idx % 2) {
crc &= 0xff;
} else {
crc >>= 8;
}
return (oldcrc << 4) ^ crc;
}
#else // USE_WIDE_CRC
INLINE OI_UINT8 crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
{
return (oldcrc << 4) ^ crc8_narrow[(oldcrc ^ next) >> 4];
}
#ifdef USE_NIBBLEWISE_CRC
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
{
crc = (crc << 4) ^ crc8_narrow[(crc ^ next) >> 4];
crc = (crc << 4) ^ crc8_narrow[((crc >> 4)^next) & 0xf];
return crc;
}
#else // USE_NIBBLEWISE_CRC
INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
{
return crc8_narrow[crc ^ next];
}
#endif // USE_NIBBLEWISE_CRC
#endif // USE_WIDE_CRC
PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data)
{
OI_UINT i;
OI_UINT8 crc = 0x0f;
/* Count is the number of whole bytes subject to CRC. Actually, it's one
* more than this number, because data[3] is the CRC field itself, which is
* explicitly skipped. Since crc_iterate (should be) inlined, it's cheaper
* spacewise to include the check in the loop. This shouldn't be much of a
* bottleneck routine in the first place. */
OI_UINT count = (frame->nrof_subbands * frame->nrof_channels / 2u) + 4;
if (frame->mode == SBC_JOINT_STEREO && frame->nrof_subbands == 8) {
count++;
}
for (i = 1; i < count; i++) {
if (i != 3) {
crc = crc_iterate(crc, data[i]);
}
}
if (frame->mode == SBC_JOINT_STEREO && frame->nrof_subbands == 4) {
crc = crc_iterate_top4(crc, data[i]);
}
return crc;
}
void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame)
{
frame->nrof_blocks = block_values[frame->blocks];
frame->nrof_subbands = band_values[frame->subbands];
frame->frequency = freq_values[frame->freqIndex];
frame->nrof_channels = channel_values[frame->mode];
}
/**
* Unrolled macro to copy 4 32-bit aligned 32-bit values backward in memory
*/
#define COPY4WORDS_BACK(_dest, _src) \
do { \
OI_INT32 _a, _b, _c, _d; \
_a = *--_src; \
_b = *--_src; \
_c = *--_src; \
_d = *--_src; \
*--_dest = _a; \
*--_dest = _b; \
*--_dest = _c; \
*--_dest = _d; \
} while (0)
#if defined(USE_PLATFORM_MEMMOVE) || defined(USE_PLATFORM_MEMCPY)
#include <string.h>
#endif
PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount)
{
#ifdef USE_PLATFORM_MEMMOVE
memmove(dest, src, wordCount * sizeof(SBC_BUFFER_T));
#elif defined(USE_PLATFORM_MEMCPY)
OI_ASSERT(((OI_CHAR *)(dest) - (OI_CHAR *)(src)) >= wordCount * sizeof(*dest));
memcpy(dest, src, wordCount * sizeof(SBC_BUFFER_T));
#else
OI_UINT n;
OI_INT32 *d;
OI_INT32 *s;
n = wordCount / 4 / (sizeof(OI_INT32) / sizeof(*dest));
OI_ASSERT((n * 4 * (sizeof(OI_INT32) / sizeof(*dest))) == wordCount);
d = (void *)(dest + wordCount);
s = (void *)(src + wordCount);
do {
COPY4WORDS_BACK(d, s);
} while (--n);
#endif
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,61 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**
@file
This file contains a single function, which returns a string indicating the
version number of the eSBC codec
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
#include "bt_target.h"
#include "oi_stddefs.h"
#include "oi_codec_sbc_private.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
/** Version string for the BLUEmagic 3.0 protocol stack and profiles */
PRIVATE OI_CHAR *const codecVersion = "v1.5"
#ifdef OI_SBC_EVAL
" (Evaluation version)"
#endif
;
/** This function returns the version string for the BLUEmagic 3.0 protocol stack
and profiles */
OI_CHAR *OI_CODEC_Version(void)
{
return codecVersion;
}
/**********************************************************************************/
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/*******************************************************************************
* @file readsamplesjoint.inc
*
* This is the body of the generic version of OI_SBC_ReadSamplesJoint().
* It is designed to be \#included into a function as follows:
\code
void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 4
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
#define NROF_SUBBANDS 8
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
\endcode
* Or to make a generic version:
\code
void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
{
OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
#define NROF_SUBBANDS nrof_subbands
#include "readsamplesjoint.inc"
#undef NROF_SUBBANDS
}
\endcode
* @ingroup codec_internal
*******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
{
OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
OI_UINT bl = common->frameInfo.nrof_blocks;
OI_INT32 * RESTRICT s = common->subdata;
OI_UINT8 *ptr = global_bs->ptr.w;
OI_UINT32 value = global_bs->value;
OI_UINT bitPtr = global_bs->bitPtr;
OI_UINT8 jmask = common->frameInfo.join << (8 - NROF_SUBBANDS);
do {
OI_INT8 *sf_array = &common->scale_factor[0];
OI_UINT8 *bits_array = &common->bits.uint8[0];
OI_UINT8 joint = jmask;
OI_UINT sb;
/*
* Left channel
*/
sb = NROF_SUBBANDS;
do {
OI_UINT32 raw;
OI_INT32 dequant;
OI_UINT8 bits = *bits_array++;
OI_INT sf = *sf_array++;
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
dequant = OI_SBC_Dequant(raw, sf, bits);
*s++ = dequant;
} while (--sb);
/*
* Right channel
*/
sb = NROF_SUBBANDS;
do {
OI_UINT32 raw;
OI_INT32 dequant;
OI_UINT8 bits = *bits_array++;
OI_INT sf = *sf_array++;
OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
dequant = OI_SBC_Dequant(raw, sf, bits);
/*
* Check if we need to do mid/side
*/
if (joint & 0x80) {
OI_INT32 mid = *(s - NROF_SUBBANDS);
OI_INT32 side = dequant;
*(s - NROF_SUBBANDS) = mid + side;
dequant = mid - side;
}
joint <<= 1;
*s++ = dequant;
} while (--sb);
} while (--bl);
}

View File

@ -0,0 +1,139 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**
@file
DO NOT EDIT THIS FILE DIRECTLY
This file is automatically generated by the "synthesis-gen.pl" script.
Any changes to this generated file will be lost when the script is re-run.
These functions are called by functions in synthesis.c to perform the synthesis
filterbank computations for the SBC decoder.
*/
#include "bt_target.h"
#include <oi_codec_sbc_private.h>
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
#ifndef CLIP_INT16
#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
#endif
#define MUL_16S_16S(_x, _y) ((_x) * (_y))
PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const *RESTRICT buffer, OI_UINT strideShift)
{
OI_INT32 pcm_a, pcm_b;
/* 1 - stage 0 */ pcm_b = 0;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(8235, buffer[ 12])) >> 3;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(-23167, buffer[ 20])) >> 3;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(26479, buffer[ 28])) >> 2;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(-17397, buffer[ 36])) << 1;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(9399, buffer[ 44])) << 3;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(17397, buffer[ 52])) << 1;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(26479, buffer[ 60])) >> 2;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(23167, buffer[ 68])) >> 3;
/* 1 - stage 0 */ pcm_b += (MUL_16S_16S(8235, buffer[ 76])) >> 3;
/* 1 - stage 0 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[0 << strideShift] = (OI_INT16)pcm_b;
/* 1 - stage 1 */ pcm_a = 0;
/* 1 - stage 1 */ pcm_b = 0;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(-3263, buffer[ 5])) >> 5;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(9293, buffer[ 5])) >> 3;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(29293, buffer[ 11])) >> 5;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(-6087, buffer[ 11])) >> 2;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(-5229, buffer[ 21]));
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(1247, buffer[ 21])) << 3;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(30835, buffer[ 27])) >> 3;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(-2893, buffer[ 27])) << 3;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(-27021, buffer[ 37])) << 1;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(23671, buffer[ 37])) << 2;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(31633, buffer[ 43])) << 1;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(18055, buffer[ 43])) << 1;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(17319, buffer[ 53])) << 1;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(11537, buffer[ 53])) >> 1;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(26663, buffer[ 59])) >> 2;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(1747, buffer[ 59])) << 1;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(4555, buffer[ 69])) >> 1;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(685, buffer[ 69])) << 1;
/* 1 - stage 1 */ pcm_a += (MUL_16S_16S(12419, buffer[ 75])) >> 4;
/* 1 - stage 1 */ pcm_b += (MUL_16S_16S(8721, buffer[ 75])) >> 7;
/* 1 - stage 1 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[1 << strideShift] = (OI_INT16)pcm_a;
/* 1 - stage 1 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[7 << strideShift] = (OI_INT16)pcm_b;
/* 1 - stage 2 */ pcm_a = 0;
/* 1 - stage 2 */ pcm_b = 0;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(-10385, buffer[ 6])) >> 6;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(11167, buffer[ 6])) >> 4;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(24995, buffer[ 10])) >> 5;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(-10337, buffer[ 10])) >> 4;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(-309, buffer[ 22])) << 4;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(1917, buffer[ 22])) << 2;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(9161, buffer[ 26])) >> 3;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(-30605, buffer[ 26])) >> 1;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(-23063, buffer[ 38])) << 1;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(8317, buffer[ 38])) << 3;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(27561, buffer[ 42])) << 1;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(9553, buffer[ 42])) << 2;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(2309, buffer[ 54])) << 3;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(22117, buffer[ 54])) >> 4;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(12705, buffer[ 58])) >> 1;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(16383, buffer[ 58])) >> 2;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(6239, buffer[ 70])) >> 3;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(7543, buffer[ 70])) >> 3;
/* 1 - stage 2 */ pcm_a += (MUL_16S_16S(9251, buffer[ 74])) >> 4;
/* 1 - stage 2 */ pcm_b += (MUL_16S_16S(8603, buffer[ 74])) >> 6;
/* 1 - stage 2 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[2 << strideShift] = (OI_INT16)pcm_a;
/* 1 - stage 2 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[6 << strideShift] = (OI_INT16)pcm_b;
/* 1 - stage 3 */ pcm_a = 0;
/* 1 - stage 3 */ pcm_b = 0;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(-16457, buffer[ 7])) >> 6;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(16913, buffer[ 7])) >> 5;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(19083, buffer[ 9])) >> 5;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(-8443, buffer[ 9])) >> 7;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(-23641, buffer[ 23])) >> 2;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(3687, buffer[ 23])) << 1;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(-29015, buffer[ 25])) >> 4;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(-301, buffer[ 25])) << 5;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(-12889, buffer[ 39])) << 2;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(15447, buffer[ 39])) << 2;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(6145, buffer[ 41])) << 3;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(10255, buffer[ 41])) << 2;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(24211, buffer[ 55])) >> 1;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(-18233, buffer[ 55])) >> 3;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(23469, buffer[ 57])) >> 2;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(9405, buffer[ 57])) >> 1;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(21223, buffer[ 71])) >> 8;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(1499, buffer[ 71])) >> 1;
/* 1 - stage 3 */ pcm_a += (MUL_16S_16S(26913, buffer[ 73])) >> 6;
/* 1 - stage 3 */ pcm_b += (MUL_16S_16S(26189, buffer[ 73])) >> 7;
/* 1 - stage 3 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[3 << strideShift] = (OI_INT16)pcm_a;
/* 1 - stage 3 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[5 << strideShift] = (OI_INT16)pcm_b;
/* 1 - stage 4 */ pcm_a = 0;
/* 1 - stage 4 */ pcm_a += (MUL_16S_16S(10445, buffer[ 8])) >> 4;
/* 1 - stage 4 */ pcm_a += (MUL_16S_16S(-5297, buffer[ 24])) << 1;
/* 1 - stage 4 */ pcm_a += (MUL_16S_16S(22299, buffer[ 40])) << 2;
/* 1 - stage 4 */ pcm_a += (MUL_16S_16S(10603, buffer[ 56]));
/* 1 - stage 4 */ pcm_a += (MUL_16S_16S(9539, buffer[ 72])) >> 4;
/* 1 - stage 4 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[4 << strideShift] = (OI_INT16)pcm_a;
}
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,308 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
@ingroup codec_internal
*/
/**@addgroup codec_internal*/
/**@{*/
/*
* Performs an 8-point Type-II scaled DCT using the Arai-Agui-Nakajima
* factorization. The scaling factors are folded into the windowing
* constants. 29 adds and 5 16x32 multiplies per 8 samples.
*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
#define AAN_C4_FIX (759250125)/* S1.30 759250125 0.707107*/
#define AAN_C6_FIX (410903207)/* S1.30 410903207 0.382683*/
#define AAN_Q0_FIX (581104888)/* S1.30 581104888 0.541196*/
#define AAN_Q1_FIX (1402911301)/* S1.30 1402911301 1.306563*/
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
/**
* Default C language implementation of a 32x32->32 multiply. This function may
* be replaced by a platform-specific version for speed.
*
* @param u A signed 32-bit multiplicand
* @param v A signed 32-bit multiplier
* @return A signed 32-bit value corresponding to the 32 most significant bits
* of the 64-bit product of u and v.
*/
INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v)
{
OI_UINT32 u0, v0;
OI_INT32 u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u >> 16;
v0 = v & 0xFFFF; v1 = v >> 16;
t = u0 * v0;
t = u1 * v0 + ((OI_UINT32)t >> 16);
w1 = t & 0xFFFF;
w2 = t >> 16;
w1 = u0 * v1 + w1;
return u1 * v1 + w2 + (w1 >> 16);
}
#define MUL_32S_32S_HI(_x, _y) default_mul_32s_32s_hi(_x, _y)
#ifdef DEBUG_DCT
PRIVATE void float_dct2_8(float *RESTRICT out, OI_INT32 const *RESTRICT in)
{
#define FIX(x,bits) (((int)floor(0.5f+((x)*((float)(1<<bits)))))/((float)(1<<bits)))
#define FLOAT_BUTTERFLY(x,y) x += y; y = x - (y*2); OI_ASSERT(VALID_INT32(x)); OI_ASSERT(VALID_INT32(y));
#define FLOAT_MULT_DCT(K, sample) (FIX(K,20) * sample)
#define FLOAT_SCALE(x, y) (((x) / (double)(1 << (y))))
double L00, L01, L02, L03, L04, L05, L06, L07;
double L25;
double in0, in1, in2, in3;
double in4, in5, in6, in7;
in0 = FLOAT_SCALE(in[0], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in0));
in1 = FLOAT_SCALE(in[1], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in1));
in2 = FLOAT_SCALE(in[2], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in2));
in3 = FLOAT_SCALE(in[3], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in3));
in4 = FLOAT_SCALE(in[4], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in4));
in5 = FLOAT_SCALE(in[5], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in5));
in6 = FLOAT_SCALE(in[6], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in6));
in7 = FLOAT_SCALE(in[7], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in7));
L00 = (in0 + in7); OI_ASSERT(VALID_INT32(L00));
L01 = (in1 + in6); OI_ASSERT(VALID_INT32(L01));
L02 = (in2 + in5); OI_ASSERT(VALID_INT32(L02));
L03 = (in3 + in4); OI_ASSERT(VALID_INT32(L03));
L04 = (in3 - in4); OI_ASSERT(VALID_INT32(L04));
L05 = (in2 - in5); OI_ASSERT(VALID_INT32(L05));
L06 = (in1 - in6); OI_ASSERT(VALID_INT32(L06));
L07 = (in0 - in7); OI_ASSERT(VALID_INT32(L07));
FLOAT_BUTTERFLY(L00, L03);
FLOAT_BUTTERFLY(L01, L02);
L02 += L03; OI_ASSERT(VALID_INT32(L02));
L02 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L02); OI_ASSERT(VALID_INT32(L02));
FLOAT_BUTTERFLY(L00, L01);
out[0] = (float)FLOAT_SCALE(L00, DCTII_8_SHIFT_0); OI_ASSERT(VALID_INT16(out[0]));
out[4] = (float)FLOAT_SCALE(L01, DCTII_8_SHIFT_4); OI_ASSERT(VALID_INT16(out[4]));
FLOAT_BUTTERFLY(L03, L02);
out[6] = (float)FLOAT_SCALE(L02, DCTII_8_SHIFT_6); OI_ASSERT(VALID_INT16(out[6]));
out[2] = (float)FLOAT_SCALE(L03, DCTII_8_SHIFT_2); OI_ASSERT(VALID_INT16(out[2]));
L04 += L05; OI_ASSERT(VALID_INT32(L04));
L05 += L06; OI_ASSERT(VALID_INT32(L05));
L06 += L07; OI_ASSERT(VALID_INT32(L06));
L04 /= 2;
L05 /= 2;
L06 /= 2;
L07 /= 2;
L05 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L05); OI_ASSERT(VALID_INT32(L05));
L25 = L06 - L04; OI_ASSERT(VALID_INT32(L25));
L25 = FLOAT_MULT_DCT(AAN_C6_FLOAT, L25); OI_ASSERT(VALID_INT32(L25));
L04 = FLOAT_MULT_DCT(AAN_Q0_FLOAT, L04); OI_ASSERT(VALID_INT32(L04));
L04 -= L25; OI_ASSERT(VALID_INT32(L04));
L06 = FLOAT_MULT_DCT(AAN_Q1_FLOAT, L06); OI_ASSERT(VALID_INT32(L06));
L06 -= L25; OI_ASSERT(VALID_INT32(L25));
FLOAT_BUTTERFLY(L07, L05);
FLOAT_BUTTERFLY(L05, L04);
out[3] = (float)(FLOAT_SCALE(L04, DCTII_8_SHIFT_3 - 1)); OI_ASSERT(VALID_INT16(out[3]));
out[5] = (float)(FLOAT_SCALE(L05, DCTII_8_SHIFT_5 - 1)); OI_ASSERT(VALID_INT16(out[5]));
FLOAT_BUTTERFLY(L07, L06);
out[7] = (float)(FLOAT_SCALE(L06, DCTII_8_SHIFT_7 - 1)); OI_ASSERT(VALID_INT16(out[7]));
out[1] = (float)(FLOAT_SCALE(L07, DCTII_8_SHIFT_1 - 1)); OI_ASSERT(VALID_INT16(out[1]));
}
#undef BUTTERFLY
#endif
/*
* This function calculates the AAN DCT. Its inputs are in S16.15 format, as
* returned by OI_SBC_Dequant. In practice, abs(in[x]) < 52429.0 / 1.38
* (1244918057 integer). The function it computes is an approximation to the array defined
* by:
*
* diag(aan_s) * AAN= C2
*
* or
*
* AAN = diag(1/aan_s) * C2
*
* where C2 is as it is defined in the comment at the head of this file, and
*
* aan_s[i] = aan_s = 1/(2*cos(i*pi/16)) with i = 1..7, aan_s[0] = 1;
*
* aan_s[i] = [ 1.000 0.510 0.541 0.601 0.707 0.900 1.307 2.563 ]
*
* The output ranges are shown as follows:
*
* Let Y[0..7] = AAN * X[0..7]
*
* Without loss of generality, assume the input vector X consists of elements
* between -1 and 1. The maximum possible value of a given output element occurs
* with some particular combination of input vector elements each of which is -1
* or 1. Consider the computation of Y[i]. Y[i] = sum t=0..7 of AAN[t,i]*X[i]. Y is
* maximized if the sign of X[i] matches the sign of AAN[t,i], ensuring a
* positive contribution to the sum. Equivalently, one may simply sum
* abs(AAN)[t,i] over t to get the maximum possible value of Y[i].
*
* This yields approximately [8.00 10.05 9.66 8.52 8.00 5.70 4.00 2.00]
*
* Given the maximum magnitude sensible input value of +/-37992, this yields the
* following vector of maximum output magnitudes:
*
* [ 303936 381820 367003 323692 303936 216555 151968 75984 ]
*
* Ultimately, these values must fit into 16 bit signed integers, so they must
* be scaled. A non-uniform scaling helps maximize the kept precision. The
* relative number of extra bits of precision maintainable with respect to the
* largest value is given here:
*
* [ 0 0 0 0 0 0 1 2 ]
*
*/
PRIVATE void dct2_8(SBC_BUFFER_T *RESTRICT out, OI_INT32 const *RESTRICT in)
{
#define BUTTERFLY(x,y) x += y; y = x - (y<<1);
#define FIX_MULT_DCT(K, x) (MUL_32S_32S_HI(K,x)<<2)
OI_INT32 L00, L01, L02, L03, L04, L05, L06, L07;
OI_INT32 L25;
OI_INT32 in0, in1, in2, in3;
OI_INT32 in4, in5, in6, in7;
#if DCTII_8_SHIFT_IN != 0
in0 = SCALE(in[0], DCTII_8_SHIFT_IN);
in1 = SCALE(in[1], DCTII_8_SHIFT_IN);
in2 = SCALE(in[2], DCTII_8_SHIFT_IN);
in3 = SCALE(in[3], DCTII_8_SHIFT_IN);
in4 = SCALE(in[4], DCTII_8_SHIFT_IN);
in5 = SCALE(in[5], DCTII_8_SHIFT_IN);
in6 = SCALE(in[6], DCTII_8_SHIFT_IN);
in7 = SCALE(in[7], DCTII_8_SHIFT_IN);
#else
in0 = in[0];
in1 = in[1];
in2 = in[2];
in3 = in[3];
in4 = in[4];
in5 = in[5];
in6 = in[6];
in7 = in[7];
#endif
L00 = in0 + in7;
L01 = in1 + in6;
L02 = in2 + in5;
L03 = in3 + in4;
L04 = in3 - in4;
L05 = in2 - in5;
L06 = in1 - in6;
L07 = in0 - in7;
BUTTERFLY(L00, L03);
BUTTERFLY(L01, L02);
L02 += L03;
L02 = FIX_MULT_DCT(AAN_C4_FIX, L02);
BUTTERFLY(L00, L01);
out[0] = (OI_INT16)SCALE(L00, DCTII_8_SHIFT_0);
out[4] = (OI_INT16)SCALE(L01, DCTII_8_SHIFT_4);
BUTTERFLY(L03, L02);
out[6] = (OI_INT16)SCALE(L02, DCTII_8_SHIFT_6);
out[2] = (OI_INT16)SCALE(L03, DCTII_8_SHIFT_2);
L04 += L05;
L05 += L06;
L06 += L07;
L04 /= 2;
L05 /= 2;
L06 /= 2;
L07 /= 2;
L05 = FIX_MULT_DCT(AAN_C4_FIX, L05);
L25 = L06 - L04;
L25 = FIX_MULT_DCT(AAN_C6_FIX, L25);
L04 = FIX_MULT_DCT(AAN_Q0_FIX, L04);
L04 -= L25;
L06 = FIX_MULT_DCT(AAN_Q1_FIX, L06);
L06 -= L25;
BUTTERFLY(L07, L05);
BUTTERFLY(L05, L04);
out[3] = (OI_INT16)SCALE(L04, DCTII_8_SHIFT_3 - 1);
out[5] = (OI_INT16)SCALE(L05, DCTII_8_SHIFT_5 - 1);
BUTTERFLY(L07, L06);
out[7] = (OI_INT16)SCALE(L06, DCTII_8_SHIFT_7 - 1);
out[1] = (OI_INT16)SCALE(L07, DCTII_8_SHIFT_1 - 1);
#undef BUTTERFLY
#ifdef DEBUG_DCT
{
float float_out[8];
float_dct2_8(float_out, in);
}
#endif
}
/**@}*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,511 @@
/******************************************************************************
*
* Copyright (C) 2014 The Android Open Source Project
* Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
*
* 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.
*
******************************************************************************/
/**********************************************************************************
$Revision: #1 $
***********************************************************************************/
/** @file
This file, along with synthesis-generated.c, contains the synthesis
filterbank routines. The operations performed correspond to the
operations described in A2DP Appendix B, Figure 12.3. Several
mathematical optimizations are performed, particularly for the
8-subband case.
One important optimization is to note that the "matrixing" operation
can be decomposed into the product of a type II discrete cosine kernel
and another, sparse matrix.
According to Fig 12.3, in the 8-subband case,
@code
N[k][i] = cos((i+0.5)*(k+4)*pi/8), k = 0..15 and i = 0..7
@endcode
N can be factored as R * C2, where C2 is an 8-point type II discrete
cosine kernel given by
@code
C2[k][i] = cos((i+0.5)*k*pi/8)), k = 0..7 and i = 0..7
@endcode
R turns out to be a sparse 16x8 matrix with the following non-zero
entries:
@code
R[k][k+4] = 1, k = 0..3
R[k][abs(12-k)] = -1, k = 5..15
@endcode
The spec describes computing V[0..15] as N * R.
@code
V[0..15] = N * R = (R * C2) * R = R * (C2 * R)
@endcode
C2 * R corresponds to computing the discrete cosine transform of R, so
V[0..15] can be computed by taking the DCT of R followed by assignment
and selective negation of the DCT result into V.
Although this was derived empirically using GNU Octave, it is
formally demonstrated in, e.g., Liu, Chi-Min and Lee,
Wen-Chieh. "A Unified Fast Algorithm for Cosine Modulated
Filter Banks in Current Audio Coding Standards." Journal of
the AES 47 (December 1999): 1061.
Given the shift operation performed prior to computing V[0..15], it is
clear that V[0..159] represents a rolling history of the 10 most
recent groups of blocks input to the synthesis operation. Interpreting
the matrix N in light of its factorization into C2 and R, R's
sparseness has implications for interpreting the values in V. In
particular, there is considerable redundancy in the values stored in
V. Furthermore, since R[4][0..7] are all zeros, one out of every 16
values in V will be zero regardless of the input data. Within each
block of 16 values in V, fully half of them are redundant or
irrelevant:
@code
V[ 0] = DCT[4]
V[ 1] = DCT[5]
V[ 2] = DCT[6]
V[ 3] = DCT[7]
V[ 4] = 0
V[ 5] = -DCT[7] = -V[3] (redundant)
V[ 6] = -DCT[6] = -V[2] (redundant)
V[ 7] = -DCT[5] = -V[1] (redundant)
V[ 8] = -DCT[4] = -V[0] (redundant)
V[ 9] = -DCT[3]
V[10] = -DCT[2]
V[11] = -DCT[1]
V[12] = -DCT[0]
V[13] = -DCT[1] = V[11] (redundant)
V[14] = -DCT[2] = V[10] (redundant)
V[15] = -DCT[3] = V[ 9] (redundant)
@endcode
Since the elements of V beyond 15 were originally computed the same
way during a previous run, what holds true for V[x] also holds true
for V[x+16]. Thus, so long as care is taken to maintain the mapping,
we need only actually store the unique values, which correspond to the
output of the DCT, in some cases inverted. In fact, instead of storing
V[0..159], we could store DCT[0..79] which would contain a history of
DCT results. More on this in a bit.
Going back to figure 12.3 in the spec, it should be clear that the
vector U need not actually be explicitly constructed, but that with
suitable indexing into V during the window operation, the same end can
be accomplished. In the same spirit of the pseudocode shown in the
figure, the following is the construction of W without using U:
@code
for i=0 to 79 do
W[i] = D[i]*VSIGN(i)*V[remap_V(i)] where remap_V(i) = 32*(int(i/16)) + (i % 16) + (i % 16 >= 8 ? 16 : 0)
and VSIGN(i) maps i%16 into {1, 1, 1, 1, 0, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1 }
These values correspond to the
signs of the redundant values as
shown in the explanation three
paragraphs above.
@endcode
We saw above how V[4..8,13..15] (and by extension
V[(4..8,13..15)+16*n]) can be defined in terms of other elements
within the subblock of V. V[0..3,9..12] correspond to DCT elements.
@code
for i=0 to 79 do
W[i] = D[i]*DSIGN(i)*DCT[remap_DCT(i)]
@endcode
The DCT is calculated using the Arai-Agui-Nakajima factorization,
which saves some computation by producing output that needs to be
multiplied by scaling factors before being used.
@code
for i=0 to 79 do
W[i] = D[i]*SCALE[i%8]*AAN_DCT[remap_DCT(i)]
@endcode
D can be premultiplied with the DCT scaling factors to yield
@code
for i=0 to 79 do
W[i] = DSCALED[i]*AAN_DCT[remap_DCT(i)] where DSCALED[i] = D[i]*SCALE[i%8]
@endcode
The output samples X[0..7] are defined as sums of W:
@code
X[j] = sum{i=0..9}(W[j+8*i])
@endcode
@ingroup codec_internal
*/
/**
@addtogroup codec_internal
@{
*/
#include "bt_target.h"
#include "oi_codec_sbc_private.h"
#if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
const OI_INT32 dec_window_4[21] = {
0, /* +0.00000000E+00 */
97, /* +5.36548976E-04 */
270, /* +1.49188357E-03 */
495, /* +2.73370904E-03 */
694, /* +3.83720193E-03 */
704, /* +3.89205149E-03 */
338, /* +1.86581691E-03 */
-554, /* -3.06012286E-03 */
1974, /* +1.09137620E-02 */
3697, /* +2.04385087E-02 */
5224, /* +2.88757392E-02 */
5824, /* +3.21939290E-02 */
4681, /* +2.58767811E-02 */
1109, /* +6.13245186E-03 */
-5214, /* -2.88217274E-02 */
-14047, /* -7.76463494E-02 */
24529, /* +1.35593274E-01 */
35274, /* +1.94987841E-01 */
44618, /* +2.46636662E-01 */
50984, /* +2.81828203E-01 */
53243, /* +2.94315332E-01 */
};
#define DCTII_4_K06_FIX ( 11585)/* S1.14 11585 0.707107*/
#define DCTII_4_K08_FIX ( 21407)/* S1.14 21407 1.306563*/
#define DCTII_4_K09_FIX (-15137)/* S1.14 -15137 -0.923880*/
#define DCTII_4_K10_FIX ( -8867)/* S1.14 -8867 -0.541196*/
/** Scales x by y bits to the right, adding a rounding factor.
*/
#ifndef SCALE
#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
#endif
#ifndef CLIP_INT16
#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
#endif
/**
* Default C language implementation of a 16x32->32 multiply. This function may
* be replaced by a platform-specific version for speed.
*
* @param u A signed 16-bit multiplicand
* @param v A signed 32-bit multiplier
* @return A signed 32-bit value corresponding to the 32 most significant bits
* of the 48-bit product of u and v.
*/
INLINE OI_INT32 default_mul_16s_32s_hi(OI_INT16 u, OI_INT32 v)
{
OI_UINT16 v0;
OI_INT16 v1;
OI_INT32 w, x;
v0 = (OI_UINT16)(v & 0xffff);
v1 = (OI_INT16) (v >> 16);
w = v1 * u;
x = u * v0;
return w + (x >> 16);
}
#define MUL_16S_32S_HI(_x, _y) default_mul_16s_32s_hi(_x, _y)
#define LONG_MULT_DCT(K, sample) (MUL_16S_32S_HI(K, sample)<<2)
PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const *RESTRICT buffer, OI_UINT strideShift);
PRIVATE void SynthWindow112_generated(OI_INT16 *pcm, SBC_BUFFER_T const *RESTRICT buffer, OI_UINT strideShift);
PRIVATE void dct2_8(SBC_BUFFER_T *RESTRICT out, OI_INT32 const *RESTRICT x);
typedef void (*SYNTH_FRAME)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount);
#ifndef COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS
#define COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(dest, src) do { shift_buffer(dest, src, 72); } while (0)
#endif
#ifndef DCT2_8
#define DCT2_8(dst, src) dct2_8(dst, src)
#endif
#ifndef SYNTH80
#define SYNTH80 SynthWindow80_generated
#endif
#ifndef SYNTH112
#define SYNTH112 SynthWindow112_generated
#endif
PRIVATE void OI_SBC_SynthFrame_80(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72, context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72, context->common.filterBuffer[1]);
}
offset = context->common.filterBufferLen - 80;
} else {
offset -= 1 * 8;
}
for (ch = 0; ch < nrof_channels; ch++) {
DCT2_8(context->common.filterBuffer[ch] + offset, s);
SYNTH80(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
s += 8;
}
pcm += (8 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
PRIVATE void OI_SBC_SynthFrame_4SB(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72, context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72, context->common.filterBuffer[1]);
}
offset = context->common.filterBufferLen - 80;
} else {
offset -= 8;
}
for (ch = 0; ch < nrof_channels; ch++) {
cosineModulateSynth4(context->common.filterBuffer[ch] + offset, s);
SynthWindow40_int32_int32_symmetry_with_sum(pcm + ch,
context->common.filterBuffer[ch] + offset,
pcmStrideShift);
s += 4;
}
pcm += (4 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
#ifdef SBC_ENHANCED
PRIVATE void OI_SBC_SynthFrame_Enhanced(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
{
OI_UINT blk;
OI_UINT ch;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
OI_UINT offset = context->common.filterBufferOffset;
OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
OI_UINT blkstop = blkstart + blkcount;
for (blk = blkstart; blk < blkstop; blk++) {
if (offset == 0) {
COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 104, context->common.filterBuffer[0]);
if (nrof_channels == 2) {
COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 104, context->common.filterBuffer[1]);
}
offset = context->common.filterBufferLen - 112;
} else {
offset -= 8;
}
for (ch = 0; ch < nrof_channels; ++ch) {
DCT2_8(context->common.filterBuffer[ch] + offset, s);
SYNTH112(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
s += 8;
}
pcm += (8 << pcmStrideShift);
}
context->common.filterBufferOffset = offset;
}
static const SYNTH_FRAME SynthFrameEnhanced[] = {
NULL, /* invalid */
OI_SBC_SynthFrame_Enhanced, /* mono */
OI_SBC_SynthFrame_Enhanced /* stereo */
};
#endif
static const SYNTH_FRAME SynthFrame8SB[] = {
NULL, /* invalid */
OI_SBC_SynthFrame_80, /* mono */
OI_SBC_SynthFrame_80 /* stereo */
};
static const SYNTH_FRAME SynthFrame4SB[] = {
NULL, /* invalid */
OI_SBC_SynthFrame_4SB, /* mono */
OI_SBC_SynthFrame_4SB /* stereo */
};
PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks)
{
OI_UINT nrof_subbands = context->common.frameInfo.nrof_subbands;
OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
OI_ASSERT(nrof_subbands == 4 || nrof_subbands == 8);
if (nrof_subbands == 4) {
SynthFrame4SB[nrof_channels](context, pcm, start_block, nrof_blocks);
#ifdef SBC_ENHANCED
} else if (context->common.frameInfo.enhanced) {
SynthFrameEnhanced[nrof_channels](context, pcm, start_block, nrof_blocks);
#endif /* SBC_ENHANCED */
} else {
SynthFrame8SB[nrof_channels](context, pcm, start_block, nrof_blocks);
}
}
void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift)
{
OI_INT32 pa;
OI_INT32 pb;
/* These values should be zero, since out[2] of the 4-band cosine modulation
* is always zero. */
OI_ASSERT(buffer[ 2] == 0);
OI_ASSERT(buffer[10] == 0);
OI_ASSERT(buffer[18] == 0);
OI_ASSERT(buffer[26] == 0);
OI_ASSERT(buffer[34] == 0);
OI_ASSERT(buffer[42] == 0);
OI_ASSERT(buffer[50] == 0);
OI_ASSERT(buffer[58] == 0);
OI_ASSERT(buffer[66] == 0);
OI_ASSERT(buffer[74] == 0);
pa = dec_window_4[ 4] * (buffer[12] + buffer[76]);
pa += dec_window_4[ 8] * (buffer[16] - buffer[64]);
pa += dec_window_4[12] * (buffer[28] + buffer[60]);
pa += dec_window_4[16] * (buffer[32] - buffer[48]);
pa += dec_window_4[20] * buffer[44];
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[0 << strideShift] = (OI_INT16)pa;
pa = dec_window_4[ 1] * buffer[ 1]; pb = dec_window_4[ 1] * buffer[79];
pb += dec_window_4[ 3] * buffer[ 3]; pa += dec_window_4[ 3] * buffer[77];
pa += dec_window_4[ 5] * buffer[13]; pb += dec_window_4[ 5] * buffer[67];
pb += dec_window_4[ 7] * buffer[15]; pa += dec_window_4[ 7] * buffer[65];
pa += dec_window_4[ 9] * buffer[17]; pb += dec_window_4[ 9] * buffer[63];
pb += dec_window_4[11] * buffer[19]; pa += dec_window_4[11] * buffer[61];
pa += dec_window_4[13] * buffer[29]; pb += dec_window_4[13] * buffer[51];
pb += dec_window_4[15] * buffer[31]; pa += dec_window_4[15] * buffer[49];
pa += dec_window_4[17] * buffer[33]; pb += dec_window_4[17] * buffer[47];
pb += dec_window_4[19] * buffer[35]; pa += dec_window_4[19] * buffer[45];
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[1 << strideShift] = (OI_INT16)(pa);
pb = SCALE(-pb, 15);
CLIP_INT16(pb);
pcm[3 << strideShift] = (OI_INT16)(pb);
pa = dec_window_4[2] * (/*buffer[ 2] + */ buffer[78]); /* buffer[ 2] is always zero */
pa += dec_window_4[6] * (buffer[14] /* + buffer[66]*/); /* buffer[66] is always zero */
pa += dec_window_4[10] * (/*buffer[18] + */ buffer[62]); /* buffer[18] is always zero */
pa += dec_window_4[14] * (buffer[30] /* + buffer[50]*/); /* buffer[50] is always zero */
pa += dec_window_4[18] * (/*buffer[34] + */ buffer[46]); /* buffer[34] is always zero */
pa = SCALE(-pa, 15);
CLIP_INT16(pa);
pcm[2 << strideShift] = (OI_INT16)(pa);
}
/**
This routine implements the cosine modulation matrix for 4-subband
synthesis. This is called "matrixing" in the SBC specification. This
matrix, M4, can be factored into an 8-point Type II Discrete Cosine
Transform, DCTII_4 and a matrix S4, given here:
@code
__ __
| 0 0 1 0 |
| 0 0 0 1 |
| 0 0 0 0 |
| 0 0 0 -1 |
S4 = | 0 0 -1 0 |
| 0 -1 0 0 |
| -1 0 0 0 |
|__ 0 -1 0 0 __|
M4 * in = S4 * (DCTII_4 * in)
@endcode
(DCTII_4 * in) is computed using a Fast Cosine Transform. The algorithm
here is based on an implementation computed by the SPIRAL computer
algebra system, manually converted to fixed-point arithmetic. S4 can be
implemented using only assignment and negation.
*/
PRIVATE void cosineModulateSynth4(SBC_BUFFER_T *RESTRICT out, OI_INT32 const *RESTRICT in)
{
OI_INT32 f0, f1, f2, f3, f4, f7, f8, f9, f10;
OI_INT32 y0, y1, y2, y3;
f0 = (in[0] - in[3]);
f1 = (in[0] + in[3]);
f2 = (in[1] - in[2]);
f3 = (in[1] + in[2]);
f4 = f1 - f3;
y0 = -SCALE(f1 + f3, DCT_SHIFT);
y2 = -SCALE(LONG_MULT_DCT(DCTII_4_K06_FIX, f4), DCT_SHIFT);
f7 = f0 + f2;
f8 = LONG_MULT_DCT(DCTII_4_K08_FIX, f0);
f9 = LONG_MULT_DCT(DCTII_4_K09_FIX, f7);
f10 = LONG_MULT_DCT(DCTII_4_K10_FIX, f2);
y3 = -SCALE(f8 + f9, DCT_SHIFT);
y1 = -SCALE(f10 - f9, DCT_SHIFT);
out[0] = (OI_INT16) - y2;
out[1] = (OI_INT16) - y3;
out[2] = (OI_INT16)0;
out[3] = (OI_INT16)y3;
out[4] = (OI_INT16)y2;
out[5] = (OI_INT16)y1;
out[6] = (OI_INT16)y0;
out[7] = (OI_INT16)y1;
}
/**
@}
*/
#endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */

View File

@ -0,0 +1,91 @@
/******************************************************************************
*
* 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.
*
******************************************************************************/
/******************************************************************************
*
* Definitions for the fast DCT.
*
******************************************************************************/
#ifndef SBC_DCT_H
#define SBC_DCT_H
#if (SBC_ARM_ASM_OPT==TRUE)
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1, s32OutLow) \
{ \
__asm \
{ \
MUL s32OutLow,(SINT32)s16In2, (s32In1>>15) \
} \
}
#else
#if (SBC_DSP_OPT==TRUE)
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow = SBC_Multiply_32_16_Simplified((SINT32)s16In2,s32In1);
#else
#if (SBC_IPAQ_OPT==TRUE)
/*#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)((SINT32)(s16In2)*(SINT32)(s32In1>>15)); */
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)(((SINT64)s16In2*(SINT64)s32In1)>>15);
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \
{ \
s64Temp = ((SINT64) s32In2) * ((SINT64) s32In1)>>31; \
s32OutLow = (SINT32) s64Temp; \
}
#endif
#else
#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) \
{ \
s32In1Temp = s32In1; \
s32In2Temp = (SINT32)s16In2; \
\
/* Multiply one +ve and the other -ve number */ \
if (s32In1Temp < 0) \
{ \
s32In1Temp ^= 0xFFFFFFFF; \
s32In1Temp++; \
s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \
s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \
s32OutLow ^= 0xFFFFFFFF; \
s32OutLow++; \
} \
else \
{ \
s32OutLow = (s32In2Temp * (s32In1Temp >> 16)); \
s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16); \
} \
s32OutLow <<= 1; \
}
#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
#define SBC_MULT_64(s32In1, s32In2, s32OutLow, s32OutHi) \
{\
s32OutLow=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)& 0x00000000FFFFFFFF);\
s32OutHi=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)>>32);\
}
#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow) \
{ \
s32HiTemp = 0; \
SBC_MULT_64(s32In2,s32In1 , s32OutLow, s32HiTemp); \
s32OutLow = (((s32OutLow>>15)&0x1FFFF) | (s32HiTemp << 17)); \
}
#endif
#endif
#endif
#endif
#endif

View File

@ -0,0 +1,57 @@
/******************************************************************************
*
* 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.
*
******************************************************************************/
/******************************************************************************
*
* Function declarations.
*
******************************************************************************/
#ifndef SBC_FUNCDECLARE_H
#define SBC_FUNCDECLARE_H
/*#include "sbc_encoder.h"*/
/* Global data */
#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE)
extern const SINT16 gas32CoeffFor4SBs[];
extern const SINT16 gas32CoeffFor8SBs[];
#else
extern const SINT32 gas32CoeffFor4SBs[];
extern const SINT32 gas32CoeffFor8SBs[];
#endif
/* Global functions*/
extern void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *CodecParams);
extern void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *CodecParams);
extern void SbcAnalysisInit (void);
extern void SbcAnalysisFilter4(SBC_ENC_PARAMS *strEncParams);
extern void SbcAnalysisFilter8(SBC_ENC_PARAMS *strEncParams);
extern void SBC_FastIDCT8 (SINT32 *pInVect, SINT32 *pOutVect);
extern void SBC_FastIDCT4 (SINT32 *x0, SINT32 *pOutVect);
extern void EncPacking(SBC_ENC_PARAMS *strEncParams);
extern void EncQuantizer(SBC_ENC_PARAMS *);
#if (SBC_DSP_OPT==TRUE)
SINT32 SBC_Multiply_32_16_Simplified(SINT32 s32In2Temp, SINT32 s32In1Temp);
#endif
#endif

View File

@ -0,0 +1,201 @@
/******************************************************************************
*
* 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 constants and structures used by Encoder.
*
******************************************************************************/
#ifndef SBC_ENCODER_H
#define SBC_ENCODER_H
#define ENCODER_VERSION "0025"
#ifdef BUILDCFG
#include "bt_target.h"
#endif
/*DEFINES*/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#define SBC_MAX_NUM_OF_SUBBANDS 8
#define SBC_MAX_NUM_OF_CHANNELS 2
#define SBC_MAX_NUM_OF_BLOCKS 16
#define SBC_LOUDNESS 0
#define SBC_SNR 1
#define SUB_BANDS_8 8
#define SUB_BANDS_4 4
#define SBC_sf16000 0
#define SBC_sf32000 1
#define SBC_sf44100 2
#define SBC_sf48000 3
#define SBC_MONO 0
#define SBC_DUAL 1
#define SBC_STEREO 2
#define SBC_JOINT_STEREO 3
#define SBC_BLOCK_0 4
#define SBC_BLOCK_1 8
#define SBC_BLOCK_2 12
#define SBC_BLOCK_3 16
#define SBC_NULL 0
#ifndef SBC_MAX_NUM_FRAME
#define SBC_MAX_NUM_FRAME 1
#endif
#ifndef SBC_DSP_OPT
#define SBC_DSP_OPT FALSE
#endif
/* Set SBC_USE_ARM_PRAGMA to TRUE to use "#pragma arm section zidata" */
#ifndef SBC_USE_ARM_PRAGMA
#define SBC_USE_ARM_PRAGMA FALSE
#endif
/* Set SBC_ARM_ASM_OPT to TRUE in case the target is an ARM */
/* this will replace all the 32 and 64 bit mult by in line assembly code */
#ifndef SBC_ARM_ASM_OPT
#define SBC_ARM_ASM_OPT FALSE
#endif
/* green hill compiler option -> Used to distinguish the syntax for inline assembly code*/
#ifndef SBC_GHS_COMPILER
#define SBC_GHS_COMPILER FALSE
#endif
/* ARM compiler option -> Used to distinguish the syntax for inline assembly code */
#ifndef SBC_ARM_COMPILER
#define SBC_ARM_COMPILER TRUE
#endif
/* Set SBC_IPAQ_OPT to TRUE in case the target is an ARM */
/* 32 and 64 bit mult will be performed using SINT64 ( usualy __int64 ) cast that usualy give optimal performance if supported */
#ifndef SBC_IPAQ_OPT
#define SBC_IPAQ_OPT TRUE
#endif
/* Debug only: set SBC_IS_64_MULT_IN_WINDOW_ACCU to TRUE to use 64 bit multiplication in the windowing */
/* -> not recomended, more MIPS for the same restitution. */
#ifndef SBC_IS_64_MULT_IN_WINDOW_ACCU
#define SBC_IS_64_MULT_IN_WINDOW_ACCU FALSE
#endif /*SBC_IS_64_MULT_IN_WINDOW_ACCU */
/* Set SBC_IS_64_MULT_IN_IDCT to TRUE to use 64 bits multiplication in the DCT of Matrixing */
/* -> more MIPS required for a better audio quality. comparasion with the SIG utilities shows a division by 10 of the RMS */
/* CAUTION: It only apply in the if SBC_FAST_DCT is set to TRUE */
#ifndef SBC_IS_64_MULT_IN_IDCT
#define SBC_IS_64_MULT_IN_IDCT FALSE
#endif /*SBC_IS_64_MULT_IN_IDCT */
/* set SBC_IS_64_MULT_IN_QUANTIZER to TRUE to use 64 bits multiplication in the quantizer */
/* setting this flag to FALSE add whistling noise at 5.5 and 11 KHz usualy not perceptible by human's hears. */
#ifndef SBC_IS_64_MULT_IN_QUANTIZER
#define SBC_IS_64_MULT_IN_QUANTIZER TRUE
#endif /*SBC_IS_64_MULT_IN_IDCT */
/* Debug only: set this flag to FALSE to disable fast DCT algorithm */
#ifndef SBC_FAST_DCT
#define SBC_FAST_DCT TRUE
#endif /*SBC_FAST_DCT */
/* In case we do not use joint stereo mode the flag save some RAM and ROM in case it is set to FALSE */
#ifndef SBC_JOINT_STE_INCLUDED
#define SBC_JOINT_STE_INCLUDED TRUE
#endif
/* TRUE -> application should provide PCM buffer, FALSE PCM buffer reside in SBC_ENC_PARAMS */
#ifndef SBC_NO_PCM_CPY_OPTION
#define SBC_NO_PCM_CPY_OPTION FALSE
#endif
#define MINIMUM_ENC_VX_BUFFER_SIZE (8*10*2)
#ifndef ENC_VX_BUFFER_SIZE
#define ENC_VX_BUFFER_SIZE (MINIMUM_ENC_VX_BUFFER_SIZE + 64)
/*#define ENC_VX_BUFFER_SIZE MINIMUM_ENC_VX_BUFFER_SIZE + 1024*/
#endif
#ifndef SBC_FOR_EMBEDDED_LINUX
#define SBC_FOR_EMBEDDED_LINUX FALSE
#endif
/*constants used for index calculation*/
#define SBC_BLK (SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS)
#include "sbc_types.h"
typedef struct SBC_ENC_PARAMS_TAG {
SINT16 s16SamplingFreq; /* 16k, 32k, 44.1k or 48k*/
SINT16 s16ChannelMode; /* mono, dual, streo or joint streo*/
SINT16 s16NumOfSubBands; /* 4 or 8 */
SINT16 s16NumOfChannels;
SINT16 s16NumOfBlocks; /* 4, 8, 12 or 16*/
SINT16 s16AllocationMethod; /* loudness or SNR*/
SINT16 s16BitPool; /* 16*numOfSb for mono & dual;
32*numOfSb for stereo & joint stereo */
UINT16 u16BitRate;
UINT8 u8NumPacketToEncode; /* number of sbc frame to encode. Default is 1 */
#if (SBC_JOINT_STE_INCLUDED == TRUE)
SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS]; /*1 if JS, 0 otherwise*/
#endif
SINT16 s16MaxBitNeed;
SINT16 as16ScaleFactor[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
SINT16 *ps16NextPcmBuffer;
#if (SBC_NO_PCM_CPY_OPTION == TRUE)
SINT16 *ps16PcmBuffer;
#else
SINT16 as16PcmBuffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
#endif
SINT16 s16ScartchMemForBitAlloc[16];
SINT32 s32SbBuffer[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * SBC_MAX_NUM_OF_BLOCKS];
SINT16 as16Bits[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
UINT8 *pu8Packet;
UINT8 *pu8NextPacket;
UINT16 FrameHeader;
UINT16 u16PacketLength;
} SBC_ENC_PARAMS;
#ifdef __cplusplus
extern "C"
{
#endif
extern void SBC_Encoder(SBC_ENC_PARAMS *strEncParams);
extern void SBC_Encoder_Init(SBC_ENC_PARAMS *strEncParams);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,47 @@
/******************************************************************************
*
* 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 _SBC_IF_H
#define _SBC_IF_H
#define PCM_BUFFER_SIZE 512
/*
SBC_Init - called once for each track played
pcm_sample_freq - 4000 to 48000
channels - 1 mono 2 stereo
bits_per_sample - 8 or 16
return - 0 sucess
*/
int SBC_init(int pcm_sample_freq, int channels, int bits_per_sample);
/*
SBC_write - called repeatedly with pcm_in pointer
increasing by length until track is finished.
pcm_in - pointer to PCM buffer
length - any
sbc_out - pointer to SBC output buffer
return - number of bytes written to sbc_out
*/
int SBC_write(unsigned char *pcm_in, int length, unsigned char *sbc_out);
#endif

Some files were not shown because too many files have changed in this diff Show More