commit
e20ebe7574
@ -0,0 +1,4 @@ |
|||||||
|
$repo_dir="$(pwd)".replace("`\", "/") |
||||||
|
$env:PROJ_PATH="$repo_dir" |
||||||
|
$env:IDF_PATH="$repo_dir/lib/esp-idf" |
||||||
|
. "$($env:IDF_PATH)/export.ps1" |
@ -1,7 +1,6 @@ |
|||||||
{ |
{ |
||||||
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", |
"$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", |
||||||
"workspace.library": ["lib/luavgl/src", "luals-stubs"], |
"workspace.library": ["luals-stubs"], |
||||||
"workspace.ignoreDir": ["ldoc-stubs"], |
|
||||||
"runtime.version": "Lua 5.4", |
"runtime.version": "Lua 5.4", |
||||||
} |
} |
||||||
|
|
||||||
|
@ -1,3 +0,0 @@ |
|||||||
file = {'ldoc-stubs'} |
|
||||||
project = "Tangara" |
|
||||||
description = "Lua modules provided by Tangara's firmware" |
|
@ -1,13 +0,0 @@ |
|||||||
--- Module for interacting with playback volume. The Bluetooth and wired outputs store their current volume separately; this API only allows interacting with the volume of the currently used output device. |
|
||||||
-- @module alerts |
|
||||||
|
|
||||||
local alerts = {} |
|
||||||
|
|
||||||
--- Returns the current volume as a percentage of the current volume limit. |
|
||||||
-- @tparam function constructor Called to create the UI for the alert. A new default root object and group will be set before calling this function.i Alerts are non-interactable; the group created for the constructor will not be granted focus. |
|
||||||
function alerts.show(constructor) end |
|
||||||
|
|
||||||
--- Dismisses any visible alerts, removing them from the screen. |
|
||||||
function alerts.hide() end |
|
||||||
|
|
||||||
return alerts |
|
@ -1,13 +0,0 @@ |
|||||||
--- Module for adding and removing screens from the system's backstack. |
|
||||||
-- @module backstack |
|
||||||
|
|
||||||
local backstack = {} |
|
||||||
|
|
||||||
--- Pushes a new screen onto the backstack. |
|
||||||
-- @tparam function constructor Called to create the UI for the new screen. A new default root object and group will be set before calling this function. The function provided should return a table holding any bindings used by this screen; the returned value is retained so long as this screen is present in the backstack. |
|
||||||
function backstack.push(constructor) end |
|
||||||
|
|
||||||
--- Removes the currently active screen, and instead shows the screen underneath it on the backstack. Does nothing if this is the only existing screen. |
|
||||||
function backstack.pop() end |
|
||||||
|
|
||||||
return backstack |
|
@ -1,13 +0,0 @@ |
|||||||
--- Properties and functions for handling Bluetooth connectivity |
|
||||||
-- @module bluetooth |
|
||||||
local bluetooth = {} |
|
||||||
|
|
||||||
--- Whether or not the Bluetooth stack is currently enabled. This property is writeable, and can be used to enable or disable Bluetooth. |
|
||||||
-- @see types.Property |
|
||||||
bluetooth.enabled = types.Property |
|
||||||
|
|
||||||
--- Whether or not there is an active connection to another Bluetooth device. |
|
||||||
-- @see types.Property |
|
||||||
bluetooth.connected = types.Property |
|
||||||
|
|
||||||
return bluetooth |
|
@ -1,59 +0,0 @@ |
|||||||
--- Module for accessing and updating data about the user's library of tracks. |
|
||||||
-- @module database |
|
||||||
|
|
||||||
local database = {} |
|
||||||
|
|
||||||
--- Returns a list of all indexes in the database. |
|
||||||
-- @treturn Array(Index) |
|
||||||
function database.indexes() end |
|
||||||
|
|
||||||
--- An iterator is a userdata type that behaves like an ordinary Lua iterator. |
|
||||||
-- @type Iterator |
|
||||||
local Iterator = {} |
|
||||||
|
|
||||||
--- A TrackId is a unique identifier, representing a playable track in the |
|
||||||
--- user's library. |
|
||||||
-- @type TrackId |
|
||||||
local TrackId = {} |
|
||||||
|
|
||||||
--- A record is an item within an Index, representing some value at a specific |
|
||||||
--- depth. |
|
||||||
-- @type Record |
|
||||||
local Record = {} |
|
||||||
|
|
||||||
--- Gets the human-readable text representing this record. The `__tostring` |
|
||||||
--- metatable function is an alias of this function. |
|
||||||
-- @treturn string |
|
||||||
function Record:title() end |
|
||||||
|
|
||||||
--- Returns the value that this record represents. This may be either a track |
|
||||||
--- id, for records which uniquely identify a track, or it may be a new |
|
||||||
--- Iterator representing the next level of depth for the current index. |
|
||||||
--- |
|
||||||
--- For example, each Record in the "All Albums" index corresponds to an entire |
|
||||||
--- album of tracks; the 'contents' of such a Record is an iterator returning |
|
||||||
--- each track in the album represented by the Record. The contents of each of |
|
||||||
--- the returned 'track' Records would be a full Track, as there is no further |
|
||||||
--- disambiguation needed. |
|
||||||
-- @treturn TrackId|Iterator(Record) |
|
||||||
function Record:contents() end |
|
||||||
|
|
||||||
--- An index is heirarchical, sorted, view of the tracks within the database. |
|
||||||
--- For example, the 'All Albums' index contains, first, a sorted list of every |
|
||||||
--- album name in the library. Then, at the second level of the index, a sorted |
|
||||||
--- list of every track within each album. |
|
||||||
-- @type Index |
|
||||||
local Index = {} |
|
||||||
|
|
||||||
--- Gets the human-readable name of this index. This is typically something |
|
||||||
--- like "All Albums", or "Albums by Artist". The `__tostring` metatable |
|
||||||
--- function is an alias of this function. |
|
||||||
-- @treturn string |
|
||||||
function Index:name() end |
|
||||||
|
|
||||||
--- Returns a new iterator that can be used to access every record within the |
|
||||||
--- first level of this index. |
|
||||||
-- @treturn Iterator(Record) |
|
||||||
function Index:iter() end |
|
||||||
|
|
||||||
return database |
|
@ -1,19 +0,0 @@ |
|||||||
--- Properties for interacting with the audio playback system |
|
||||||
-- @module playback |
|
||||||
|
|
||||||
local playback = {} |
|
||||||
|
|
||||||
--- Whether or not any audio is *allowed* to be played. If there is a current track, then this is essentially an indicator of whether playback is paused or unpaused. |
|
||||||
-- @see types.Property |
|
||||||
playback.playing = types.Property |
|
||||||
|
|
||||||
--- Rich information about the currently playing track. |
|
||||||
-- @see types.Property |
|
||||||
-- @see types.Track |
|
||||||
playback.track = types.Property |
|
||||||
|
|
||||||
--- The current playback position within the current track, in seconds. |
|
||||||
-- @see types.Property |
|
||||||
playback.position = types.Property |
|
||||||
|
|
||||||
return playback |
|
@ -1,18 +0,0 @@ |
|||||||
--- Properties and functions that deal with the device's battery and power state |
|
||||||
-- @module power |
|
||||||
|
|
||||||
local power = {} |
|
||||||
|
|
||||||
--- The battery's current charge as a percentage |
|
||||||
-- @see types.Property |
|
||||||
power.battery_pct = types.Property |
|
||||||
|
|
||||||
--- The battery's current voltage, in millivolts. |
|
||||||
-- @see types.Property |
|
||||||
power.battery_millivolts = types.Property |
|
||||||
|
|
||||||
--- Whether or not the device is currently receiving external power |
|
||||||
-- @see types.Property |
|
||||||
power.plugged_in = types.Property |
|
||||||
|
|
||||||
return power |
|
@ -1,32 +0,0 @@ |
|||||||
--- Properties and functions for inspecting and manipulating the track playback queue |
|
||||||
-- @module queue |
|
||||||
|
|
||||||
local queue = {} |
|
||||||
|
|
||||||
--- The index in the queue of the currently playing track. This may be zero if the queue is empty. |
|
||||||
-- @see types.Property |
|
||||||
queue.position = types.Property |
|
||||||
|
|
||||||
--- The total number of tracks in the queue, including tracks which have already been played. |
|
||||||
-- @see types.Property |
|
||||||
queue.size = types.Property |
|
||||||
|
|
||||||
--- Determines whether or not the queue will be restarted after the final track is played. |
|
||||||
-- @see types.Property |
|
||||||
queue.replay = types.Property |
|
||||||
|
|
||||||
-- Determines whether or not the current track will repeat indefinitely |
|
||||||
-- @see types.Property |
|
||||||
queue.repeat_track = types.Property |
|
||||||
|
|
||||||
--- Determines whether, when progressing to the next track in the queue, the next track will be chosen randomly. The random selection algorithm used is a Miller Shuffle, which guarantees that no repeat selections will be made until every item in the queue has been played. |
|
||||||
-- @see types.Property |
|
||||||
queue.random = types.Property |
|
||||||
|
|
||||||
--- Moves forward in the play queue, looping back around to the beginning if repeat is on. |
|
||||||
function queue.next() end |
|
||||||
|
|
||||||
--- Moves backward in the play queue, looping back around to the end if repeat is on. |
|
||||||
function queue.previous() end |
|
||||||
|
|
||||||
return queue |
|
@ -1,35 +0,0 @@ |
|||||||
--- Userdata-based types used throughout the rest of the API. These types are |
|
||||||
--- not generally constructable within Lua code. |
|
||||||
-- @module types |
|
||||||
local types = {} |
|
||||||
|
|
||||||
--- A observable value, owned by the C++ firmware. |
|
||||||
-- @type Property |
|
||||||
types.Property = {} |
|
||||||
|
|
||||||
--- Gets the current value |
|
||||||
-- @return The property's current value. |
|
||||||
function Property:get() end |
|
||||||
|
|
||||||
--- Sets a new value. Not all properties may be set from within Lua code. For |
|
||||||
--- example, it makes little sense to attempt to override the current battery |
|
||||||
--- level. |
|
||||||
-- @param val The new value. This should generally be of the same type as the existing value. |
|
||||||
-- @return true if the new value was applied, or false if the backing C++ code rejected the new value (e.g. if it was out of range, or the wrong type). |
|
||||||
function Property:set(val) end |
|
||||||
|
|
||||||
--- Invokes the given function once immediately with the current value, and then again whenever the value changes. |
|
||||||
--- The function is invoked for *all* changes; both from the underlying C++ data, and from calls to `set` (if this is a Lua-writeable property). |
|
||||||
--- The binding will be active **only** so long as the given function remains in scope. |
|
||||||
-- @param fn callback function to apply property values. Must accept one argument; the updated value. |
|
||||||
-- @return fn, for more ergonmic use with anonymous closures. |
|
||||||
function Property:bind(fn) end |
|
||||||
|
|
||||||
--- Table containing information about a track. Most fields are optional. |
|
||||||
-- @type Track |
|
||||||
types.Track = {} |
|
||||||
|
|
||||||
--- The title of the track, or the filename if no title is available. |
|
||||||
types.Track.title = "" |
|
||||||
|
|
||||||
return Property |
|
@ -1,14 +0,0 @@ |
|||||||
--- Module for interacting with playback volume. The Bluetooth and wired outputs store their current volume separately; this API only allows interacting with the volume of the currently used output device. |
|
||||||
-- @module volume |
|
||||||
|
|
||||||
local volume = {} |
|
||||||
|
|
||||||
--- The current volume as a percentage of the current volume limit. |
|
||||||
-- @see types.Property |
|
||||||
volume.current_pct = types.Property |
|
||||||
|
|
||||||
--- The current volume in terms of decibels relative to line level. |
|
||||||
-- @see types.Property |
|
||||||
volume.current_db = types.Property |
|
||||||
|
|
||||||
return volume |
|
@ -0,0 +1,899 @@ |
|||||||
|
idf_build_get_property(target IDF_TARGET) |
||||||
|
|
||||||
|
if(${target} STREQUAL "linux") |
||||||
|
return() # This component is not supported by the POSIX/Linux simulator |
||||||
|
endif() |
||||||
|
|
||||||
|
# API headers that are used in the docs are also compiled |
||||||
|
# even if CONFIG_BT_ENABLED=n as long as CONFIG_IDF_DOC_BUILD=y |
||||||
|
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32) |
||||||
|
set(target_specific_include_dirs include/esp32/include) |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C3) |
||||||
|
set(target_specific_include_dirs include/esp32c3/include) |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32S3) |
||||||
|
set(target_specific_include_dirs include/esp32c3/include) |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C2) |
||||||
|
set(target_specific_include_dirs include/esp32c2/include) |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C6) |
||||||
|
set(target_specific_include_dirs include/esp32c6/include) |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32H2) |
||||||
|
set(target_specific_include_dirs include/esp32h2/include) |
||||||
|
endif() |
||||||
|
|
||||||
|
set(common_include_dirs |
||||||
|
common/api/include/api |
||||||
|
common/btc/profile/esp/blufi/include |
||||||
|
common/btc/profile/esp/include |
||||||
|
) |
||||||
|
|
||||||
|
set(ble_mesh_include_dirs |
||||||
|
"esp_ble_mesh/common/include" |
||||||
|
"esp_ble_mesh/common/tinycrypt/include" |
||||||
|
"esp_ble_mesh/core" |
||||||
|
"esp_ble_mesh/core/include" |
||||||
|
"esp_ble_mesh/core/storage" |
||||||
|
"esp_ble_mesh/btc/include" |
||||||
|
"esp_ble_mesh/models/common/include" |
||||||
|
"esp_ble_mesh/models/client/include" |
||||||
|
"esp_ble_mesh/models/server/include" |
||||||
|
"esp_ble_mesh/api/core/include" |
||||||
|
"esp_ble_mesh/api/models/include" |
||||||
|
"esp_ble_mesh/api" |
||||||
|
"esp_ble_mesh/lib/include" |
||||||
|
"esp_ble_mesh/v1.1/api/core/include" |
||||||
|
"esp_ble_mesh/v1.1/api/models/include" |
||||||
|
"esp_ble_mesh/v1.1/btc/include" |
||||||
|
) |
||||||
|
|
||||||
|
set(bluedroid_include_dirs host/bluedroid/api/include/api) |
||||||
|
|
||||||
|
if(CONFIG_BT_CONTROLLER_ENABLED OR CONFIG_IDF_DOC_BUILD) |
||||||
|
set(nimble_hci_include_dirs host/nimble/esp-hci/include) |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_IDF_DOC_BUILD) |
||||||
|
list(APPEND include_dirs |
||||||
|
${target_specific_include_dirs} |
||||||
|
${common_include_dirs} |
||||||
|
${ble_mesh_include_dirs} |
||||||
|
${bluedroid_include_dirs} |
||||||
|
${nimble_hci_include_dirs}) |
||||||
|
endif() |
||||||
|
|
||||||
|
|
||||||
|
if(CONFIG_BT_ENABLED) |
||||||
|
|
||||||
|
set(srcs "") |
||||||
|
set(include_dirs "") |
||||||
|
set(ldfragments "linker.lf") |
||||||
|
if(CONFIG_BT_CONTROLLER_ENABLED) |
||||||
|
if(CONFIG_IDF_TARGET_ESP32) |
||||||
|
list(APPEND srcs "controller/esp32/bt.c" |
||||||
|
"controller/esp32/hli_api.c" |
||||||
|
"controller/esp32/hli_vectors.S") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C3) |
||||||
|
list(APPEND srcs "controller/esp32c3/bt.c") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32S3) |
||||||
|
list(APPEND srcs "controller/esp32c3/bt.c") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C2) |
||||||
|
list(APPEND srcs "controller/esp32c2/bt.c") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C2) |
||||||
|
set(ldfragments "linker.lf.esp32c2") |
||||||
|
list(APPEND srcs "controller/esp32c2/bt.c") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C6) |
||||||
|
list(APPEND srcs "controller/esp32c6/bt.c") |
||||||
|
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32H2) |
||||||
|
list(APPEND srcs "controller/esp32h2/bt.c") |
||||||
|
endif() |
||||||
|
|
||||||
|
list(APPEND include_dirs ${target_specific_include_dirs}) |
||||||
|
|
||||||
|
endif() |
||||||
|
|
||||||
|
# Common |
||||||
|
list(APPEND include_dirs common/osi/include) |
||||||
|
|
||||||
|
list(APPEND priv_include_dirs |
||||||
|
common/btc/include |
||||||
|
common/include |
||||||
|
porting/mem/ |
||||||
|
) |
||||||
|
list(APPEND include_dirs ${common_include_dirs}) |
||||||
|
|
||||||
|
list(APPEND srcs "common/btc/core/btc_alarm.c" |
||||||
|
"common/api/esp_blufi_api.c" |
||||||
|
"common/btc/core/btc_manage.c" |
||||||
|
"common/btc/core/btc_task.c" |
||||||
|
"common/btc/profile/esp/blufi/blufi_prf.c" |
||||||
|
"common/btc/profile/esp/blufi/blufi_protocol.c" |
||||||
|
"common/osi/alarm.c" |
||||||
|
"common/osi/allocator.c" |
||||||
|
"common/osi/buffer.c" |
||||||
|
"common/osi/config.c" |
||||||
|
"common/osi/fixed_queue.c" |
||||||
|
"common/osi/pkt_queue.c" |
||||||
|
"common/osi/fixed_pkt_queue.c" |
||||||
|
"common/osi/future.c" |
||||||
|
"common/osi/hash_functions.c" |
||||||
|
"common/osi/hash_map.c" |
||||||
|
"common/osi/list.c" |
||||||
|
"common/osi/mutex.c" |
||||||
|
"common/osi/thread.c" |
||||||
|
"common/osi/osi.c" |
||||||
|
"common/osi/semaphore.c" |
||||||
|
"porting/mem/bt_osi_mem.c" |
||||||
|
) |
||||||
|
|
||||||
|
# Host Bluedroid |
||||||
|
if(CONFIG_BT_BLUEDROID_ENABLED) |
||||||
|
|
||||||
|
list(APPEND priv_include_dirs |
||||||
|
host/bluedroid/bta/include |
||||||
|
host/bluedroid/bta/ar/include |
||||||
|
host/bluedroid/bta/av/include |
||||||
|
host/bluedroid/bta/dm/include |
||||||
|
host/bluedroid/bta/gatt/include |
||||||
|
host/bluedroid/bta/hf_ag/include |
||||||
|
host/bluedroid/bta/hf_client/include |
||||||
|
host/bluedroid/bta/hd/include |
||||||
|
host/bluedroid/bta/hh/include |
||||||
|
host/bluedroid/bta/jv/include |
||||||
|
host/bluedroid/bta/sdp/include |
||||||
|
host/bluedroid/bta/sys/include |
||||||
|
host/bluedroid/device/include |
||||||
|
host/bluedroid/hci/include |
||||||
|
host/bluedroid/external/sbc/decoder/include |
||||||
|
host/bluedroid/external/sbc/encoder/include |
||||||
|
host/bluedroid/external/sbc/plc/include |
||||||
|
host/bluedroid/btc/profile/esp/include |
||||||
|
host/bluedroid/btc/profile/std/a2dp/include |
||||||
|
host/bluedroid/btc/profile/std/include |
||||||
|
host/bluedroid/btc/include |
||||||
|
host/bluedroid/stack/btm/include |
||||||
|
host/bluedroid/stack/gap/include |
||||||
|
host/bluedroid/stack/gatt/include |
||||||
|
host/bluedroid/stack/hid/include |
||||||
|
host/bluedroid/stack/l2cap/include |
||||||
|
host/bluedroid/stack/sdp/include |
||||||
|
host/bluedroid/stack/smp/include |
||||||
|
host/bluedroid/stack/avct/include |
||||||
|
host/bluedroid/stack/avrc/include |
||||||
|
host/bluedroid/stack/avdt/include |
||||||
|
host/bluedroid/stack/a2dp/include |
||||||
|
host/bluedroid/stack/rfcomm/include |
||||||
|
host/bluedroid/stack/include |
||||||
|
host/bluedroid/common/include |
||||||
|
host/bluedroid/config/include) |
||||||
|
|
||||||
|
list(APPEND include_dirs ${bluedroid_include_dirs}) |
||||||
|
|
||||||
|
list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c" |
||||||
|
"host/bluedroid/api/esp_avrc_api.c" |
||||||
|
"host/bluedroid/api/esp_bluedroid_hci.c" |
||||||
|
"host/bluedroid/api/esp_bt_device.c" |
||||||
|
"host/bluedroid/api/esp_bt_main.c" |
||||||
|
"host/bluedroid/api/esp_gap_ble_api.c" |
||||||
|
"host/bluedroid/api/esp_gap_bt_api.c" |
||||||
|
"host/bluedroid/api/esp_gatt_common_api.c" |
||||||
|
"host/bluedroid/api/esp_gattc_api.c" |
||||||
|
"host/bluedroid/api/esp_gatts_api.c" |
||||||
|
"host/bluedroid/api/esp_hidd_api.c" |
||||||
|
"host/bluedroid/api/esp_hidh_api.c" |
||||||
|
"host/bluedroid/api/esp_hf_ag_api.c" |
||||||
|
"host/bluedroid/api/esp_hf_client_api.c" |
||||||
|
"host/bluedroid/api/esp_spp_api.c" |
||||||
|
"host/bluedroid/api/esp_sdp_api.c" |
||||||
|
"host/bluedroid/api/esp_l2cap_bt_api.c" |
||||||
|
"host/bluedroid/bta/ar/bta_ar.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_aact.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_act.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_api.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_cfg.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_ci.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_main.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_sbc.c" |
||||||
|
"host/bluedroid/bta/av/bta_av_ssm.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_act.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_api.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_cfg.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_ci.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_co.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_main.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_pm.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_sco.c" |
||||||
|
"host/bluedroid/bta/dm/bta_dm_qos.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatt_common.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_act.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_api.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_cache.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_ci.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_co.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_main.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_utils.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatts_act.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatts_api.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatts_co.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatts_main.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gatts_utils.c" |
||||||
|
"host/bluedroid/bta/hd/bta_hd_api.c" |
||||||
|
"host/bluedroid/bta/hd/bta_hd_act.c" |
||||||
|
"host/bluedroid/bta/hd/bta_hd_main.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_act.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_api.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_cfg.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_le.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_main.c" |
||||||
|
"host/bluedroid/bta/hh/bta_hh_utils.c" |
||||||
|
"host/bluedroid/bta/jv/bta_jv_act.c" |
||||||
|
"host/bluedroid/bta/jv/bta_jv_api.c" |
||||||
|
"host/bluedroid/bta/jv/bta_jv_cfg.c" |
||||||
|
"host/bluedroid/bta/jv/bta_jv_main.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_act.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_api.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_at.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_cfg.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_cmd.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_main.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_rfc.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_sco.c" |
||||||
|
"host/bluedroid/bta/hf_ag/bta_ag_sdp.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_act.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_api.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_at.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_cmd.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_main.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_rfc.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_sco.c" |
||||||
|
"host/bluedroid/bta/hf_client/bta_hf_client_sdp.c" |
||||||
|
"host/bluedroid/bta/sdp/bta_sdp.c" |
||||||
|
"host/bluedroid/bta/sdp/bta_sdp_act.c" |
||||||
|
"host/bluedroid/bta/sdp/bta_sdp_api.c" |
||||||
|
"host/bluedroid/bta/sdp/bta_sdp_cfg.c" |
||||||
|
"host/bluedroid/bta/sys/bta_sys_conn.c" |
||||||
|
"host/bluedroid/bta/sys/bta_sys_main.c" |
||||||
|
"host/bluedroid/bta/sys/utl.c" |
||||||
|
"host/bluedroid/btc/core/btc_ble_storage.c" |
||||||
|
"host/bluedroid/btc/core/btc_config.c" |
||||||
|
"host/bluedroid/btc/core/btc_dev.c" |
||||||
|
"host/bluedroid/btc/core/btc_dm.c" |
||||||
|
"host/bluedroid/btc/core/btc_main.c" |
||||||
|
"host/bluedroid/btc/core/btc_profile_queue.c" |
||||||
|
"host/bluedroid/btc/core/btc_sec.c" |
||||||
|
"host/bluedroid/btc/core/btc_sm.c" |
||||||
|
"host/bluedroid/btc/core/btc_storage.c" |
||||||
|
"host/bluedroid/btc/core/btc_util.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/bta_av_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_control.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_sink.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c" |
||||||
|
"host/bluedroid/btc/profile/std/a2dp/btc_av.c" |
||||||
|
"host/bluedroid/btc/profile/std/avrc/btc_avrc.c" |
||||||
|
"host/bluedroid/btc/profile/std/avrc/bta_avrc_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c" |
||||||
|
"host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c" |
||||||
|
"host/bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/hid/btc_hd.c" |
||||||
|
"host/bluedroid/btc/profile/std/hid/btc_hh.c" |
||||||
|
"host/bluedroid/btc/profile/std/hid/bta_hh_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/gap/btc_gap_ble.c" |
||||||
|
"host/bluedroid/btc/profile/std/gap/btc_gap_bt.c" |
||||||
|
"host/bluedroid/btc/profile/std/gap/bta_gap_bt_co.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gattc.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c" |
||||||
|
"host/bluedroid/btc/profile/std/spp/btc_spp.c" |
||||||
|
"host/bluedroid/btc/profile/std/sdp/btc_sdp.c" |
||||||
|
"host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c" |
||||||
|
"host/bluedroid/device/bdaddr.c" |
||||||
|
"host/bluedroid/device/controller.c" |
||||||
|
"host/bluedroid/device/interop.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/alloc.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/bitalloc-sbc.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/bitalloc.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/bitstream-decode.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/decoder-oina.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/decoder-private.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/decoder-sbc.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/dequant.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/framing-sbc.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/framing.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/oi_codec_version.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-8-generated.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-dct8.c" |
||||||
|
"host/bluedroid/external/sbc/decoder/srce/synthesis-sbc.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_analysis.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_dct.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_dct_coeffs.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_enc_coeffs.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_encoder.c" |
||||||
|
"host/bluedroid/external/sbc/encoder/srce/sbc_packing.c" |
||||||
|
"host/bluedroid/external/sbc/plc/sbc_plc.c" |
||||||
|
"host/bluedroid/hci/hci_audio.c" |
||||||
|
"host/bluedroid/hci/hci_hal_h4.c" |
||||||
|
"host/bluedroid/hci/hci_layer.c" |
||||||
|
"host/bluedroid/hci/hci_packet_factory.c" |
||||||
|
"host/bluedroid/hci/hci_packet_parser.c" |
||||||
|
"host/bluedroid/hci/packet_fragmenter.c" |
||||||
|
"host/bluedroid/main/bte_init.c" |
||||||
|
"host/bluedroid/main/bte_main.c" |
||||||
|
"host/bluedroid/stack/a2dp/a2d_api.c" |
||||||
|
"host/bluedroid/stack/a2dp/a2d_sbc.c" |
||||||
|
"host/bluedroid/stack/avct/avct_api.c" |
||||||
|
"host/bluedroid/stack/avct/avct_ccb.c" |
||||||
|
"host/bluedroid/stack/avct/avct_l2c.c" |
||||||
|
"host/bluedroid/stack/avct/avct_lcb.c" |
||||||
|
"host/bluedroid/stack/avct/avct_lcb_act.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_ad.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_api.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_ccb.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_ccb_act.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_l2c.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_msg.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_scb.c" |
||||||
|
"host/bluedroid/stack/avdt/avdt_scb_act.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_api.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_bld_ct.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_bld_tg.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_opt.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_pars_ct.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_pars_tg.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_sdp.c" |
||||||
|
"host/bluedroid/stack/avrc/avrc_utils.c" |
||||||
|
"host/bluedroid/stack/hid/hidd_api.c" |
||||||
|
"host/bluedroid/stack/hid/hidd_conn.c" |
||||||
|
"host/bluedroid/stack/hid/hidh_api.c" |
||||||
|
"host/bluedroid/stack/hid/hidh_conn.c" |
||||||
|
"host/bluedroid/stack/btm/btm_acl.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_addr.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_adv_filter.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_batchscan.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_bgconn.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_cont_energy.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_gap.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_5_gap.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_multi_adv.c" |
||||||
|
"host/bluedroid/stack/btm/btm_ble_privacy.c" |
||||||
|
"host/bluedroid/stack/btm/btm_dev.c" |
||||||
|
"host/bluedroid/stack/btm/btm_devctl.c" |
||||||
|
"host/bluedroid/stack/btm/btm_inq.c" |
||||||
|
"host/bluedroid/stack/btm/btm_main.c" |
||||||
|
"host/bluedroid/stack/btm/btm_pm.c" |
||||||
|
"host/bluedroid/stack/btm/btm_sco.c" |
||||||
|
"host/bluedroid/stack/btm/btm_sec.c" |
||||||
|
"host/bluedroid/stack/btu/btu_hcif.c" |
||||||
|
"host/bluedroid/stack/btu/btu_init.c" |
||||||
|
"host/bluedroid/stack/btu/btu_task.c" |
||||||
|
"host/bluedroid/stack/gap/gap_api.c" |
||||||
|
"host/bluedroid/stack/gap/gap_ble.c" |
||||||
|
"host/bluedroid/stack/gap/gap_conn.c" |
||||||
|
"host/bluedroid/stack/gap/gap_utils.c" |
||||||
|
"host/bluedroid/stack/gatt/att_protocol.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_api.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_attr.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_auth.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_cl.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_db.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_main.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_sr.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_sr_hash.c" |
||||||
|
"host/bluedroid/stack/gatt/gatt_utils.c" |
||||||
|
"host/bluedroid/stack/hcic/hciblecmds.c" |
||||||
|
"host/bluedroid/stack/hcic/hcicmds.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_api.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_ble.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_csm.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_fcr.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_link.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_main.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_ucd.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2c_utils.c" |
||||||
|
"host/bluedroid/stack/l2cap/l2cap_client.c" |
||||||
|
"host/bluedroid/stack/rfcomm/port_api.c" |
||||||
|
"host/bluedroid/stack/rfcomm/port_rfc.c" |
||||||
|
"host/bluedroid/stack/rfcomm/port_utils.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_l2cap_if.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_mx_fsm.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_port_fsm.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_port_if.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_ts_frames.c" |
||||||
|
"host/bluedroid/stack/rfcomm/rfc_utils.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_api.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_db.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_discovery.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_main.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_server.c" |
||||||
|
"host/bluedroid/stack/sdp/sdp_utils.c" |
||||||
|
"host/bluedroid/stack/smp/aes.c" |
||||||
|
"host/bluedroid/stack/smp/p_256_curvepara.c" |
||||||
|
"host/bluedroid/stack/smp/p_256_ecc_pp.c" |
||||||
|
"host/bluedroid/stack/smp/p_256_multprecision.c" |
||||||
|
"host/bluedroid/stack/smp/smp_act.c" |
||||||
|
"host/bluedroid/stack/smp/smp_api.c" |
||||||
|
"host/bluedroid/stack/smp/smp_br_main.c" |
||||||
|
"host/bluedroid/stack/smp/smp_cmac.c" |
||||||
|
"host/bluedroid/stack/smp/smp_keys.c" |
||||||
|
"host/bluedroid/stack/smp/smp_l2c.c" |
||||||
|
"host/bluedroid/stack/smp/smp_main.c" |
||||||
|
"host/bluedroid/stack/smp/smp_utils.c" |
||||||
|
"host/bluedroid/config/stack_config.c") |
||||||
|
|
||||||
|
|
||||||
|
list(APPEND srcs "common/btc/profile/esp/blufi/bluedroid_host/esp_blufi.c") |
||||||
|
|
||||||
|
if(CONFIG_BLE_MESH) |
||||||
|
list(APPEND srcs "esp_ble_mesh/core/bluedroid_host/adapter.c") |
||||||
|
endif() |
||||||
|
|
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BLE_MESH) |
||||||
|
list(APPEND include_dirs ${ble_mesh_include_dirs}) |
||||||
|
|
||||||
|
list(APPEND srcs "esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_common_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c" |
||||||
|
"esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c" |
||||||
|
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_ble.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_prov.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c" |
||||||
|
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/aes_decrypt.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/aes_encrypt.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/cbc_mode.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ccm_mode.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/cmac_mode.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ctr_mode.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ctr_prng.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ecc_dh.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ecc_dsa.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ecc_platform_specific.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/ecc.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/hmac_prng.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/hmac.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/sha256.c" |
||||||
|
"esp_ble_mesh/common/tinycrypt/src/utils.c" |
||||||
|
"esp_ble_mesh/common/atomic.c" |
||||||
|
"esp_ble_mesh/common/buf.c" |
||||||
|
"esp_ble_mesh/common/common.c" |
||||||
|
"esp_ble_mesh/common/kernel.c" |
||||||
|
"esp_ble_mesh/common/mutex.c" |
||||||
|
"esp_ble_mesh/common/timer.c" |
||||||
|
"esp_ble_mesh/common/utils.c" |
||||||
|
"esp_ble_mesh/core/storage/settings_nvs.c" |
||||||
|
"esp_ble_mesh/core/storage/settings_uid.c" |
||||||
|
"esp_ble_mesh/core/storage/settings.c" |
||||||
|
"esp_ble_mesh/core/access.c" |
||||||
|
"esp_ble_mesh/core/adv.c" |
||||||
|
"esp_ble_mesh/core/beacon.c" |
||||||
|
"esp_ble_mesh/core/cfg_cli.c" |
||||||
|
"esp_ble_mesh/core/cfg_srv.c" |
||||||
|
"esp_ble_mesh/core/crypto.c" |
||||||
|
"esp_ble_mesh/core/fast_prov.c" |
||||||
|
"esp_ble_mesh/core/friend.c" |
||||||
|
"esp_ble_mesh/core/health_cli.c" |
||||||
|
"esp_ble_mesh/core/health_srv.c" |
||||||
|
"esp_ble_mesh/core/heartbeat.c" |
||||||
|
"esp_ble_mesh/core/local.c" |
||||||
|
"esp_ble_mesh/core/lpn.c" |
||||||
|
"esp_ble_mesh/core/main.c" |
||||||
|
"esp_ble_mesh/core/net.c" |
||||||
|
"esp_ble_mesh/core/prov_common.c" |
||||||
|
"esp_ble_mesh/core/prov_node.c" |
||||||
|
"esp_ble_mesh/core/prov_pvnr.c" |
||||||
|
"esp_ble_mesh/core/proxy_client.c" |
||||||
|
"esp_ble_mesh/core/proxy_server.c" |
||||||
|
"esp_ble_mesh/core/pvnr_mgmt.c" |
||||||
|
"esp_ble_mesh/core/rpl.c" |
||||||
|
"esp_ble_mesh/core/scan.c" |
||||||
|
"esp_ble_mesh/core/test.c" |
||||||
|
"esp_ble_mesh/models/common/device_property.c" |
||||||
|
"esp_ble_mesh/models/common/model_common.c" |
||||||
|
"esp_ble_mesh/models/client/client_common.c" |
||||||
|
"esp_ble_mesh/models/client/generic_client.c" |
||||||
|
"esp_ble_mesh/models/client/lighting_client.c" |
||||||
|
"esp_ble_mesh/models/client/sensor_client.c" |
||||||
|
"esp_ble_mesh/models/client/time_scene_client.c" |
||||||
|
"esp_ble_mesh/models/server/generic_server.c" |
||||||
|
"esp_ble_mesh/models/server/lighting_server.c" |
||||||
|
"esp_ble_mesh/models/server/sensor_server.c" |
||||||
|
"esp_ble_mesh/models/server/server_common.c" |
||||||
|
"esp_ble_mesh/models/server/state_binding.c" |
||||||
|
"esp_ble_mesh/models/server/state_transition.c" |
||||||
|
"esp_ble_mesh/models/server/time_scene_server.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_agg_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_brc_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_cm_data_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_df_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_lcd_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_odp_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_prb_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_sar_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/core/esp_ble_mesh_srpl_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/api/models/esp_ble_mesh_mbt_model_api.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_agg_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_brc_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_df_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_lcd_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_mbt_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_odp_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_prb_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c" |
||||||
|
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c" |
||||||
|
"esp_ble_mesh/lib/ext.c") |
||||||
|
|
||||||
|
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT) |
||||||
|
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c") |
||||||
|
else() |
||||||
|
list(APPEND srcs "esp_ble_mesh/core/transport.c") |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) |
||||||
|
list(APPEND srcs |
||||||
|
"porting/npl/freertos/src/npl_os_freertos.c" |
||||||
|
"porting/nimble/src/os_msys_init.c" |
||||||
|
) |
||||||
|
|
||||||
|
if(CONFIG_BT_CONTROLLER_DISABLED) |
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/nimble/porting/nimble/src/hal_uart.c" |
||||||
|
) |
||||||
|
endif() |
||||||
|
list(APPEND include_dirs |
||||||
|
porting/include |
||||||
|
porting/nimble/include |
||||||
|
porting/npl/freertos/include |
||||||
|
porting/transport/include |
||||||
|
) |
||||||
|
|
||||||
|
if(CONFIG_BT_LE_HCI_INTERFACE_USE_UART) |
||||||
|
list(APPEND srcs |
||||||
|
"porting/transport/uart/hci_uart.c" |
||||||
|
) |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
|
||||||
|
|
||||||
|
if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)) |
||||||
|
list(APPEND include_dirs |
||||||
|
porting/ext/tinycrypt/include |
||||||
|
) |
||||||
|
list(APPEND srcs "porting/ext/tinycrypt/src/utils.c" |
||||||
|
"porting/ext/tinycrypt/src/sha256.c" |
||||||
|
"porting/ext/tinycrypt/src/ecc.c" |
||||||
|
"porting/ext/tinycrypt/src/ctr_prng.c" |
||||||
|
"porting/ext/tinycrypt/src/ctr_mode.c" |
||||||
|
"porting/ext/tinycrypt/src/aes_decrypt.c" |
||||||
|
"porting/ext/tinycrypt/src/aes_encrypt.c" |
||||||
|
"porting/ext/tinycrypt/src/ccm_mode.c" |
||||||
|
"porting/ext/tinycrypt/src/ecc_dsa.c" |
||||||
|
"porting/ext/tinycrypt/src/cmac_mode.c" |
||||||
|
"porting/ext/tinycrypt/src/ecc_dh.c" |
||||||
|
"porting/ext/tinycrypt/src/hmac_prng.c" |
||||||
|
"porting/ext/tinycrypt/src/ecc_platform_specific.c" |
||||||
|
"porting/ext/tinycrypt/src/hmac.c" |
||||||
|
"porting/ext/tinycrypt/src/cbc_mode.c") |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_ENABLED) |
||||||
|
|
||||||
|
list(APPEND include_dirs |
||||||
|
|
||||||
|
host/nimble/nimble/nimble/host/include |
||||||
|
host/nimble/nimble/nimble/include |
||||||
|
host/nimble/nimble/nimble/host/services/ans/include |
||||||
|
host/nimble/nimble/nimble/host/services/bas/include |
||||||
|
host/nimble/nimble/nimble/host/services/dis/include |
||||||
|
host/nimble/nimble/nimble/host/services/gap/include |
||||||
|
host/nimble/nimble/nimble/host/services/gatt/include |
||||||
|
host/nimble/nimble/nimble/host/services/hr/include |
||||||
|
host/nimble/nimble/nimble/host/services/htp/include |
||||||
|
host/nimble/nimble/nimble/host/services/ias/include |
||||||
|
host/nimble/nimble/nimble/host/services/ipss/include |
||||||
|
host/nimble/nimble/nimble/host/services/lls/include |
||||||
|
host/nimble/nimble/nimble/host/services/prox/include |
||||||
|
host/nimble/nimble/nimble/host/services/cts/include |
||||||
|
host/nimble/nimble/nimble/host/services/tps/include |
||||||
|
host/nimble/nimble/nimble/host/services/hid/include |
||||||
|
host/nimble/nimble/nimble/host/services/sps/include |
||||||
|
host/nimble/nimble/nimble/host/util/include |
||||||
|
host/nimble/nimble/nimble/host/store/ram/include |
||||||
|
host/nimble/nimble/nimble/host/store/config/include |
||||||
|
) |
||||||
|
|
||||||
|
list(APPEND srcs "host/nimble/nimble/nimble/transport/src/transport.c" |
||||||
|
"host/nimble/nimble/nimble/host/util/src/addr.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/gatt/src/ble_svc_gatt.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/tps/src/ble_svc_tps.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/ias/src/ble_svc_ias.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c" |
||||||
|
"host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_conn.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_store_util.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_shutdown.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig_cmd.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_id.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_svr.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gatts_lcl.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_ibeacon.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_atomic.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_alg.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_stop.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_periodic_sync.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_ead.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_aes_ccm.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gattc.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_store.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_lgcy.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_cfg.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_clt.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_coc.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_mbuf.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_att_cmd.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_log.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_eddystone.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_startup.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap_sig.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gap.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_cmd.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_uuid.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_pvcy.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_flow.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_l2cap.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_sm_sc.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_misc.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gatts.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_adv.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_hci_util.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_hs_resolv.c" |
||||||
|
"host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c" |
||||||
|
"host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c" |
||||||
|
"host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gattc_cache.c" |
||||||
|
"host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c" |
||||||
|
) |
||||||
|
|
||||||
|
if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART) |
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c" |
||||||
|
"host/nimble/nimble/nimble/transport/common/hci_h4/src/hci_h4.c" |
||||||
|
) |
||||||
|
endif() |
||||||
|
|
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/nimble/porting/nimble/src/nimble_port.c" |
||||||
|
"host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c" |
||||||
|
"host/nimble/port/src/nvs_port.c" |
||||||
|
) |
||||||
|
list(APPEND include_dirs |
||||||
|
porting/include |
||||||
|
host/nimble/nimble/porting/nimble/include |
||||||
|
host/nimble/port/include |
||||||
|
host/nimble/nimble/nimble/transport/include |
||||||
|
) |
||||||
|
|
||||||
|
if(CONFIG_BT_CONTROLLER_DISABLED) |
||||||
|
list(APPEND include_dirs |
||||||
|
host/nimble/nimble/nimble/transport/common/hci_h4/include |
||||||
|
) |
||||||
|
endif() |
||||||
|
|
||||||
|
if(NOT CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) |
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/nimble/porting/nimble/src/endian.c" |
||||||
|
"host/nimble/nimble/porting/nimble/src/os_mempool.c" |
||||||
|
"host/nimble/nimble/porting/nimble/src/mem.c" |
||||||
|
"host/nimble/nimble/porting/nimble/src/os_mbuf.c" |
||||||
|
"host/nimble/nimble/porting/nimble/src/os_msys_init.c" |
||||||
|
"host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c" |
||||||
|
) |
||||||
|
|
||||||
|
if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART) |
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/nimble/porting/nimble/src/hal_uart.c" |
||||||
|
) |
||||||
|
endif() |
||||||
|
|
||||||
|
list(APPEND include_dirs |
||||||
|
host/nimble/nimble/porting/npl/freertos/include |
||||||
|
host/nimble/nimble/porting/nimble/include |
||||||
|
host/nimble/nimble/nimble/include |
||||||
|
) |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE AND CONFIG_BT_CONTROLLER_ENABLED) |
||||||
|
list(APPEND srcs |
||||||
|
"host/nimble/esp-hci/src/esp_nimble_hci.c" |
||||||
|
) |
||||||
|
list(APPEND include_dirs ${nimble_hci_include_dirs}) |
||||||
|
endif() |
||||||
|
|
||||||
|
list(APPEND srcs |
||||||
|
"common/btc/profile/esp/blufi/nimble_host/esp_blufi.c") |
||||||
|
|
||||||
|
if(CONFIG_BLE_MESH) |
||||||
|
list(APPEND srcs "esp_ble_mesh/core/nimble_host/adapter.c") |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_MESH) |
||||||
|
|
||||||
|
list(APPEND include_dirs |
||||||
|
host/nimble/nimble/nimble/host/mesh/include |
||||||
|
host/nimble/nimble/nimble/host/include/host) |
||||||
|
|
||||||
|
list(APPEND srcs "host/nimble/nimble/nimble/host/mesh/src/shell.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/friend.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/crypto.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/settings.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/adv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/adv_ext.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/adv_legacy.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/model_srv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/msg.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/beacon.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/glue.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/model_cli.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/transport.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/prov.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/mesh.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/access.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cfg_srv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cfg_cli.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/light_model.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/health_cli.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/lpn.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/health_srv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/testing.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/aes-ccm.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/app_keys.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cdb.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/cfg.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/pb_adv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/pb_gatt.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/pb_gatt_srv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/prov_device.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/provisioner.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/heartbeat.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/rpl.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/subnet.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/proxy_msg.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/proxy_srv.c" |
||||||
|
"host/nimble/nimble/nimble/host/mesh/src/net.c") |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
|
||||||
|
endif() |
||||||
|
|
||||||
|
idf_component_register(SRCS "${srcs}" |
||||||
|
INCLUDE_DIRS "${include_dirs}" |
||||||
|
PRIV_INCLUDE_DIRS "${priv_include_dirs}" |
||||||
|
REQUIRES esp_timer esp_wifi |
||||||
|
PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs |
||||||
|
LDFRAGMENTS "${ldfragments}") |
||||||
|
|
||||||
|
if(CONFIG_BT_ENABLED) |
||||||
|
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) |
||||||
|
if(CONFIG_IDF_TARGET_ESP32) |
||||||
|
target_link_directories(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32/esp32") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app) |
||||||
|
|
||||||
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_hli_vectors_bt") |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C3) |
||||||
|
target_link_directories(${COMPONENT_LIB} INTERFACE |
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32c3") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32S3) |
||||||
|
target_link_directories(${COMPONENT_LIB} INTERFACE |
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C2) |
||||||
|
add_prebuilt_library(libble_app "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C6) |
||||||
|
add_prebuilt_library(libble_app "controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32H2) |
||||||
|
add_prebuilt_library(libble_app "controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) |
||||||
|
endif() |
||||||
|
|
||||||
|
set_source_files_properties( |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_act.c" |
||||||
|
"host/bluedroid/bta/gatt/bta_gattc_cache.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c" |
||||||
|
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c" |
||||||
|
PROPERTIES COMPILE_FLAGS -Wno-address-of-packed-member) |
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BLE_MESH) |
||||||
|
if(CONFIG_IDF_TARGET_ESP32) |
||||||
|
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32/libble_mesh.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32S3) |
||||||
|
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C3) |
||||||
|
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C6) |
||||||
|
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh) |
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32H2) |
||||||
|
add_prebuilt_library(ble_mesh "esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a") |
||||||
|
target_link_libraries(${COMPONENT_LIB} PRIVATE ble_mesh) |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_BT_NIMBLE_MESH) |
||||||
|
set_source_files_properties("host/nimble/nimble/nimble/host/mesh/src/net.c" |
||||||
|
PROPERTIES COMPILE_FLAGS -Wno-type-limits) |
||||||
|
endif() |
||||||
|
|
||||||
|
if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE AND CONFIG_BT_NIMBLE_ENABLED) |
||||||
|
# some variables in NimBLE are only used by asserts |
||||||
|
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-but-set-variable -Wno-unused-variable) |
||||||
|
endif() |
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_EARLY_EXPANSION) |
||||||
|
set(jump_table_opts "-fjump-tables") |
||||||
|
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang") ) |
||||||
|
set(jump_table_opts "${jump_table_opts} -ftree-switch-conversion") |
||||||
|
endif() |
||||||
|
set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/bta/hf_ag/bta_ag_cmd.c" |
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c" |
||||||
|
PROPERTIES COMPILE_FLAGS "${jump_table_opts}") |
||||||
|
endif() |
@ -0,0 +1,93 @@ |
|||||||
|
menu "Bluetooth" |
||||||
|
|
||||||
|
config BT_ENABLED |
||||||
|
bool "Bluetooth" |
||||||
|
depends on !APP_NO_BLOBS |
||||||
|
help |
||||||
|
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices. |
||||||
|
|
||||||
|
choice BT_HOST |
||||||
|
prompt "Host" |
||||||
|
depends on BT_ENABLED |
||||||
|
default BT_BLUEDROID_ENABLED |
||||||
|
help |
||||||
|
This helps to choose Bluetooth host stack |
||||||
|
|
||||||
|
config BT_BLUEDROID_ENABLED |
||||||
|
bool "Bluedroid - Dual-mode" |
||||||
|
help |
||||||
|
This option is recommended for classic Bluetooth or for dual-mode |
||||||
|
usecases |
||||||
|
|
||||||
|
config BT_NIMBLE_ENABLED |
||||||
|
bool "NimBLE - BLE only" |
||||||
|
help |
||||||
|
This option is recommended for BLE only usecases to save on memory |
||||||
|
|
||||||
|
config BT_CONTROLLER_ONLY |
||||||
|
depends on SOC_BT_SUPPORTED |
||||||
|
bool "Disabled" |
||||||
|
help |
||||||
|
This option is recommended when you want to communicate directly with the |
||||||
|
controller (without any host) or when you are using any other host stack |
||||||
|
not supported by Espressif (not mentioned here). |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
choice BT_CONTROLLER |
||||||
|
prompt "Controller" |
||||||
|
depends on BT_ENABLED |
||||||
|
default BT_CONTROLLER_ENABLED |
||||||
|
help |
||||||
|
This helps to choose Bluetooth controller stack |
||||||
|
|
||||||
|
config BT_CONTROLLER_ENABLED |
||||||
|
depends on SOC_BT_SUPPORTED |
||||||
|
bool "Enabled" |
||||||
|
help |
||||||
|
This option is recommended for Bluetooth controller usecases |
||||||
|
|
||||||
|
config BT_CONTROLLER_DISABLED |
||||||
|
bool "Disabled" |
||||||
|
help |
||||||
|
This option is recommended for Bluetooth Host only usecases |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
menu "Bluedroid Options" |
||||||
|
depends on BT_BLUEDROID_ENABLED |
||||||
|
source "$IDF_PATH/components/bt/host/bluedroid/Kconfig.in" |
||||||
|
endmenu |
||||||
|
|
||||||
|
menu "NimBLE Options" |
||||||
|
depends on BT_NIMBLE_ENABLED |
||||||
|
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in" |
||||||
|
endmenu |
||||||
|
|
||||||
|
menu "Controller Options" |
||||||
|
depends on BT_CONTROLLER_ENABLED |
||||||
|
source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in" |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_RELEASE_IRAM |
||||||
|
depends on BT_ENABLED && BT_LE_RELEASE_IRAM_SUPPORTED |
||||||
|
bool "Release Bluetooth text (READ DOCS FIRST)" |
||||||
|
default n |
||||||
|
help |
||||||
|
This option release Bluetooth text section and merge Bluetooth data, bss & text into |
||||||
|
a large free heap region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM. |
||||||
|
ESP32-C2 only 3 configurable PMP entries available, rest of them are hard-coded. |
||||||
|
We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM). |
||||||
|
So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT) |
||||||
|
|
||||||
|
endmenu |
||||||
|
|
||||||
|
menuconfig BLE_MESH |
||||||
|
bool "ESP BLE Mesh Support" |
||||||
|
depends on BT_ENABLED |
||||||
|
help |
||||||
|
This option enables ESP BLE Mesh support. The specific features that are |
||||||
|
available may depend on other features that have been enabled in the |
||||||
|
stack, such as Bluetooth Support, Bluedroid Support & GATT support. |
||||||
|
|
||||||
|
source "$IDF_PATH/components/bt/esp_ble_mesh/Kconfig.in" |
@ -0,0 +1,126 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "btc/btc_manage.h" |
||||||
|
#include "osi/future.h" |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks) |
||||||
|
{ |
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
if (callbacks == NULL) { |
||||||
|
return ESP_FAIL; |
||||||
|
} |
||||||
|
|
||||||
|
btc_blufi_set_callbacks(callbacks); |
||||||
|
return (btc_profile_cb_set(BTC_PID_BLUFI, callbacks->event_cb) == 0 ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
btc_blufi_args_t arg; |
||||||
|
|
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT; |
||||||
|
arg.wifi_conn_report.opmode = opmode; |
||||||
|
arg.wifi_conn_report.sta_conn_state = sta_conn_state; |
||||||
|
arg.wifi_conn_report.softap_conn_num = softap_conn_num; |
||||||
|
arg.wifi_conn_report.extra_info = extra_info; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy, |
||||||
|
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
btc_blufi_args_t arg; |
||||||
|
|
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_SEND_WIFI_LIST; |
||||||
|
arg.wifi_list.apCount = apCount; |
||||||
|
arg.wifi_list.list = list; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy, |
||||||
|
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_profile_init(void) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
|
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_INIT; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_profile_deinit(void) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
|
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_DEINIT; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
uint16_t esp_blufi_get_version(void) |
||||||
|
{ |
||||||
|
return btc_blufi_get_version(); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
btc_blufi_args_t arg; |
||||||
|
|
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_SEND_ERR_INFO; |
||||||
|
arg.blufi_err_infor.state = state; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
btc_blufi_args_t arg; |
||||||
|
if(data == NULL || data_len == 0) { |
||||||
|
return ESP_ERR_INVALID_ARG; |
||||||
|
} |
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = BTC_BLUFI_ACT_SEND_CUSTOM_DATA; |
||||||
|
arg.custom_data.data = data; |
||||||
|
arg.custom_data.data_len = data_len; |
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy, |
||||||
|
btc_blufi_call_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
@ -0,0 +1,436 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ESP_BLUFI_API_H__ |
||||||
|
#define __ESP_BLUFI_API_H__ |
||||||
|
|
||||||
|
#include "esp_err.h" |
||||||
|
#include "esp_wifi_types.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
ESP_BLUFI_EVENT_INIT_FINISH = 0, /*<! When BLUFI init complete, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_DEINIT_FINISH, /*<! When BLUFI deinit complete, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_SET_WIFI_OPMODE, /*<! When Phone set ESP32 wifi operation mode(AP/STA/AP_STA), this event happen */ |
||||||
|
ESP_BLUFI_EVENT_BLE_CONNECT, /*<! When Phone connect to ESP32 with BLE, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_BLE_DISCONNECT, /*<! When Phone disconnect with BLE, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, /*<! When Phone request ESP32's STA connect to AP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, /*<! When Phone request ESP32's STA disconnect from AP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_GET_WIFI_STATUS, /*<! When Phone get ESP32 wifi status, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, /*<! When Phone deauthenticate sta from SOFTAP, this event happen */ |
||||||
|
/* recv data */ |
||||||
|
ESP_BLUFI_EVENT_RECV_STA_BSSID, /*<! When Phone send STA BSSID to ESP32 to connect, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_STA_SSID, /*<! When Phone send STA SSID to ESP32 to connect, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_STA_PASSWD, /*<! When Phone send STA PASSWORD to ESP32 to connect, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, /*<! When Phone send SOFTAP SSID to ESP32 to start SOFTAP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, /*<! When Phone send SOFTAP PASSWORD to ESP32 to start SOFTAP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, /*<! When Phone send SOFTAP max connection number to ESP32 to start SOFTAP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, /*<! When Phone send SOFTAP authentication mode to ESP32 to start SOFTAP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, /*<! When Phone send SOFTAP channel to ESP32 to start SOFTAP, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_USERNAME, /*<! When Phone send username to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_CA_CERT, /*<! When Phone send CA certificate to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_CLIENT_CERT, /*<! When Phone send Client certificate to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SERVER_CERT, /*<! When Phone send Server certificate to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, /*<! When Phone send Client Private key to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, /*<! When Phone send Server Private key to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, /*<! When Phone send Disconnect key to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_GET_WIFI_LIST, /*<! When Phone send get wifi list command to ESP32, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_REPORT_ERROR, /*<! When Blufi report error, this event happen */ |
||||||
|
ESP_BLUFI_EVENT_RECV_CUSTOM_DATA, /*<! When Phone send custom data to ESP32, this event happen */ |
||||||
|
} esp_blufi_cb_event_t; |
||||||
|
|
||||||
|
/// BLUFI config status
|
||||||
|
typedef enum { |
||||||
|
ESP_BLUFI_STA_CONN_SUCCESS = 0x00, |
||||||
|
ESP_BLUFI_STA_CONN_FAIL = 0x01, |
||||||
|
ESP_BLUFI_STA_CONNECTING = 0x02, |
||||||
|
ESP_BLUFI_STA_NO_IP = 0x03, |
||||||
|
} esp_blufi_sta_conn_state_t; |
||||||
|
|
||||||
|
/// BLUFI init status
|
||||||
|
typedef enum { |
||||||
|
ESP_BLUFI_INIT_OK = 0, |
||||||
|
ESP_BLUFI_INIT_FAILED, |
||||||
|
} esp_blufi_init_state_t; |
||||||
|
|
||||||
|
/// BLUFI deinit status
|
||||||
|
typedef enum { |
||||||
|
ESP_BLUFI_DEINIT_OK = 0, |
||||||
|
ESP_BLUFI_DEINIT_FAILED, |
||||||
|
} esp_blufi_deinit_state_t; |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
ESP_BLUFI_SEQUENCE_ERROR = 0, |
||||||
|
ESP_BLUFI_CHECKSUM_ERROR, |
||||||
|
ESP_BLUFI_DECRYPT_ERROR, |
||||||
|
ESP_BLUFI_ENCRYPT_ERROR, |
||||||
|
ESP_BLUFI_INIT_SECURITY_ERROR, |
||||||
|
ESP_BLUFI_DH_MALLOC_ERROR, |
||||||
|
ESP_BLUFI_DH_PARAM_ERROR, |
||||||
|
ESP_BLUFI_READ_PARAM_ERROR, |
||||||
|
ESP_BLUFI_MAKE_PUBLIC_ERROR, |
||||||
|
ESP_BLUFI_DATA_FORMAT_ERROR, |
||||||
|
ESP_BLUFI_CALC_MD5_ERROR, |
||||||
|
ESP_BLUFI_WIFI_SCAN_FAIL, |
||||||
|
ESP_BLUFI_MSG_STATE_ERROR, |
||||||
|
} esp_blufi_error_state_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI extra information structure |
||||||
|
*/ |
||||||
|
typedef struct { |
||||||
|
//station
|
||||||
|
uint8_t sta_bssid[6]; /*!< BSSID of station interface */ |
||||||
|
bool sta_bssid_set; /*!< is BSSID of station interface set */ |
||||||
|
uint8_t *sta_ssid; /*!< SSID of station interface */ |
||||||
|
int sta_ssid_len; /*!< length of SSID of station interface */ |
||||||
|
uint8_t *sta_passwd; /*!< password of station interface */ |
||||||
|
int sta_passwd_len; /*!< length of password of station interface */ |
||||||
|
uint8_t *softap_ssid; /*!< SSID of softap interface */ |
||||||
|
int softap_ssid_len; /*!< length of SSID of softap interface */ |
||||||
|
uint8_t *softap_passwd; /*!< password of station interface */ |
||||||
|
int softap_passwd_len; /*!< length of password of station interface */ |
||||||
|
uint8_t softap_authmode; /*!< authentication mode of softap interface */ |
||||||
|
bool softap_authmode_set; /*!< is authentication mode of softap interface set */ |
||||||
|
uint8_t softap_max_conn_num; /*!< max connection number of softap interface */ |
||||||
|
bool softap_max_conn_num_set; /*!< is max connection number of softap interface set */ |
||||||
|
uint8_t softap_channel; /*!< channel of softap interface */ |
||||||
|
bool softap_channel_set; /*!< is channel of softap interface set */ |
||||||
|
uint8_t sta_max_conn_retry; /*!< max retry of sta establish connection */ |
||||||
|
bool sta_max_conn_retry_set; /*!< is max retry of sta establish connection set */ |
||||||
|
uint8_t sta_conn_end_reason; /*!< reason of sta connection end */ |
||||||
|
bool sta_conn_end_reason_set; /*!< is reason of sta connection end set */ |
||||||
|
int8_t sta_conn_rssi; /*!< rssi of sta connection */ |
||||||
|
bool sta_conn_rssi_set; /*!< is rssi of sta connection set */ |
||||||
|
} esp_blufi_extra_info_t; |
||||||
|
|
||||||
|
/** @brief Description of an WiFi AP */ |
||||||
|
typedef struct { |
||||||
|
uint8_t ssid[33]; /**< SSID of AP */ |
||||||
|
int8_t rssi; /**< signal strength of AP */ |
||||||
|
} esp_blufi_ap_record_t; |
||||||
|
|
||||||
|
/// Bluetooth address length
|
||||||
|
#define ESP_BLUFI_BD_ADDR_LEN 6 |
||||||
|
/// Bluetooth device address
|
||||||
|
typedef uint8_t esp_blufi_bd_addr_t[ESP_BLUFI_BD_ADDR_LEN]; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI callback parameters union |
||||||
|
*/ |
||||||
|
typedef union { |
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_INIT_FINISH |
||||||
|
*/ |
||||||
|
struct blufi_init_finish_evt_param { |
||||||
|
esp_blufi_init_state_t state; /*!< Initial status */ |
||||||
|
} init_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_DEINIT_FINISH |
||||||
|
*/ |
||||||
|
struct blufi_deinit_finish_evt_param { |
||||||
|
esp_blufi_deinit_state_t state; /*!< De-initial status */ |
||||||
|
} deinit_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_DEINIT_FINISH */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_SET_WIFI_MODE |
||||||
|
*/ |
||||||
|
struct blufi_set_wifi_mode_evt_param { |
||||||
|
wifi_mode_t op_mode; /*!< Wifi operation mode */ |
||||||
|
} wifi_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_CONNECT |
||||||
|
*/ |
||||||
|
struct blufi_connect_evt_param { |
||||||
|
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */ |
||||||
|
uint8_t server_if; /*!< server interface */ |
||||||
|
uint16_t conn_id; /*!< Connection id */ |
||||||
|
} connect; /*!< Blufi callback param of ESP_BLUFI_EVENT_CONNECT */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_DISCONNECT |
||||||
|
*/ |
||||||
|
struct blufi_disconnect_evt_param { |
||||||
|
esp_blufi_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */ |
||||||
|
} disconnect; /*!< Blufi callback param of ESP_BLUFI_EVENT_DISCONNECT */ |
||||||
|
|
||||||
|
/* ESP_BLUFI_EVENT_REQ_WIFI_CONNECT */ /* No callback param */ |
||||||
|
/* ESP_BLUFI_EVENT_REQ_WIFI_DISCONNECT */ /* No callback param */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_STA_BSSID |
||||||
|
*/ |
||||||
|
struct blufi_recv_sta_bssid_evt_param { |
||||||
|
uint8_t bssid[6]; /*!< BSSID */ |
||||||
|
} sta_bssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_BSSID */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_STA_SSID |
||||||
|
*/ |
||||||
|
struct blufi_recv_sta_ssid_evt_param { |
||||||
|
uint8_t *ssid; /*!< SSID */ |
||||||
|
int ssid_len; /*!< SSID length */ |
||||||
|
} sta_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_SSID */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_RECV_STA_PASSWD |
||||||
|
*/ |
||||||
|
struct blufi_recv_sta_passwd_evt_param { |
||||||
|
uint8_t *passwd; /*!< Password */ |
||||||
|
int passwd_len; /*!< Password Length */ |
||||||
|
} sta_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_PASSWD */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_SSID |
||||||
|
*/ |
||||||
|
struct blufi_recv_softap_ssid_evt_param { |
||||||
|
uint8_t *ssid; /*!< SSID */ |
||||||
|
int ssid_len; /*!< SSID length */ |
||||||
|
} softap_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_SSID */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD |
||||||
|
*/ |
||||||
|
struct blufi_recv_softap_passwd_evt_param { |
||||||
|
uint8_t *passwd; /*!< Password */ |
||||||
|
int passwd_len; /*!< Password Length */ |
||||||
|
} softap_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM |
||||||
|
*/ |
||||||
|
struct blufi_recv_softap_max_conn_num_evt_param { |
||||||
|
int max_conn_num; /*!< SSID */ |
||||||
|
} softap_max_conn_num; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE |
||||||
|
*/ |
||||||
|
struct blufi_recv_softap_auth_mode_evt_param { |
||||||
|
wifi_auth_mode_t auth_mode; /*!< Authentication mode */ |
||||||
|
} softap_auth_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL |
||||||
|
*/ |
||||||
|
struct blufi_recv_softap_channel_evt_param { |
||||||
|
uint8_t channel; /*!< Authentication mode */ |
||||||
|
} softap_channel; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_USERNAME |
||||||
|
*/ |
||||||
|
struct blufi_recv_username_evt_param { |
||||||
|
uint8_t *name; /*!< Username point */ |
||||||
|
int name_len; /*!< Username length */ |
||||||
|
} username; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_USERNAME*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP_BLUFI_EVENT_RECV_CA_CERT |
||||||
|
*/ |
||||||
|
struct blufi_recv_ca_evt_param { |
||||||
|
uint8_t *cert; /*!< CA certificate point */ |
||||||
|
int cert_len; /*!< CA certificate length */ |
||||||
|
} ca; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CA_CERT */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* ESP_BLUFI_EVENT_RECV_CLIENT_CERT |
||||||
|
*/ |
||||||
|
struct blufi_recv_client_cert_evt_param { |
||||||
|
uint8_t *cert; /*!< Client certificate point */ |
||||||
|
int cert_len; /*!< Client certificate length */ |
||||||
|
} client_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_CERT */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* ESP_BLUFI_EVENT_RECV_SERVER_CERT |
||||||
|
*/ |
||||||
|
struct blufi_recv_server_cert_evt_param { |
||||||
|
uint8_t *cert; /*!< Client certificate point */ |
||||||
|
int cert_len; /*!< Client certificate length */ |
||||||
|
} server_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_CERT */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY |
||||||
|
*/ |
||||||
|
struct blufi_recv_client_pkey_evt_param { |
||||||
|
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */ |
||||||
|
int pkey_len; /*!< Client Private key length */ |
||||||
|
} client_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY */ |
||||||
|
/**
|
||||||
|
* ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY |
||||||
|
*/ |
||||||
|
struct blufi_recv_server_pkey_evt_param { |
||||||
|
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */ |
||||||
|
int pkey_len; /*!< Client Private key length */ |
||||||
|
} server_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY */ |
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_REPORT_ERROR |
||||||
|
*/ |
||||||
|
struct blufi_get_error_evt_param { |
||||||
|
esp_blufi_error_state_t state; /*!< Blufi error state */ |
||||||
|
} report_error; /*!< Blufi callback param of ESP_BLUFI_EVENT_REPORT_ERROR */ |
||||||
|
/**
|
||||||
|
* @brief |
||||||
|
* ESP_BLUFI_EVENT_RECV_CUSTOM_DATA |
||||||
|
*/ |
||||||
|
struct blufi_recv_custom_data_evt_param { |
||||||
|
uint8_t *data; /*!< Custom data */ |
||||||
|
uint32_t data_len; /*!< Custom data Length */ |
||||||
|
} custom_data; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CUSTOM_DATA */ |
||||||
|
} esp_blufi_cb_param_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI event callback function type |
||||||
|
* @param event : Event type |
||||||
|
* @param param : Point to callback parameter, currently is union type |
||||||
|
*/ |
||||||
|
typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param); |
||||||
|
|
||||||
|
/* security function declare */ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI negotiate data handler |
||||||
|
* @param data : data from phone |
||||||
|
* @param len : length of data from phone |
||||||
|
* @param output_data : data want to send to phone |
||||||
|
* @param output_len : length of data want to send to phone |
||||||
|
* @param need_free : output reporting if memory needs to be freed or not * |
||||||
|
*/ |
||||||
|
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI encrypt the data after negotiate a share key |
||||||
|
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number |
||||||
|
* @param crypt_data : plain text and encrypted data, the encrypt function must support autochthonous encrypt |
||||||
|
* @param crypt_len : length of plain text |
||||||
|
* @return Nonnegative number is encrypted length, if error, return negative number; |
||||||
|
*/ |
||||||
|
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI decrypt the data after negotiate a share key |
||||||
|
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number |
||||||
|
* @param crypt_data : encrypted data and plain text, the encrypt function must support autochthonous decrypt |
||||||
|
* @param crypt_len : length of encrypted text |
||||||
|
* @return Nonnegative number is decrypted length, if error, return negative number; |
||||||
|
*/ |
||||||
|
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI checksum |
||||||
|
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number |
||||||
|
* @param data : data need to checksum |
||||||
|
* @param len : length of data |
||||||
|
*/ |
||||||
|
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BLUFI callback functions type |
||||||
|
*/ |
||||||
|
typedef struct { |
||||||
|
esp_blufi_event_cb_t event_cb; /*!< BLUFI event callback */ |
||||||
|
esp_blufi_negotiate_data_handler_t negotiate_data_handler; /*!< BLUFI negotiate data function for negotiate share key */ |
||||||
|
esp_blufi_encrypt_func_t encrypt_func; /*!< BLUFI encrypt data function with share key generated by negotiate_data_handler */ |
||||||
|
esp_blufi_decrypt_func_t decrypt_func; /*!< BLUFI decrypt data function with share key generated by negotiate_data_handler */ |
||||||
|
esp_blufi_checksum_func_t checksum_func; /*!< BLUFI check sum function (FCS) */ |
||||||
|
} esp_blufi_callbacks_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to receive blufi callback event |
||||||
|
* |
||||||
|
* @param[in] callbacks: callback functions |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to initialize blufi_profile |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_profile_init(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to de-initialize blufi_profile |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_profile_deinit(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to send wifi connection report |
||||||
|
* @param opmode : wifi opmode |
||||||
|
* @param sta_conn_state : station is already in connection or not |
||||||
|
* @param softap_conn_num : softap connection number |
||||||
|
* @param extra_info : extra information, such as sta_ssid, softap_ssid and etc. |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to send wifi list |
||||||
|
* @param apCount : wifi list count |
||||||
|
* @param list : wifi list |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief Get BLUFI profile version |
||||||
|
* |
||||||
|
* @return Most 8bit significant is Great version, Least 8bit is Sub version |
||||||
|
* |
||||||
|
*/ |
||||||
|
uint16_t esp_blufi_get_version(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to send blufi error information |
||||||
|
* @param state : error state |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state); |
||||||
|
/**
|
||||||
|
* |
||||||
|
* @brief This function is called to custom data |
||||||
|
* @param data : custom data value |
||||||
|
* @param data_len : the length of custom data |
||||||
|
* |
||||||
|
* @return ESP_OK - success, other - failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_send_custom_data(uint8_t *data, uint32_t data_len); |
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* _ESP_BLUFI_API_ */ |
@ -0,0 +1,20 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc/btc_alarm.h" |
||||||
|
#include "esp_log.h" |
||||||
|
|
||||||
|
void btc_alarm_handler(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
btc_alarm_args_t *arg = (btc_alarm_args_t *)msg->arg; |
||||||
|
|
||||||
|
BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act); |
||||||
|
|
||||||
|
if (arg->cb) { |
||||||
|
arg->cb(arg->cb_data); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "osi/thread.h" |
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY == FALSE |
||||||
|
void *btc_profile_cb_tab[BTC_PID_NUM] = {}; |
||||||
|
#else |
||||||
|
void **btc_profile_cb_tab; |
||||||
|
#endif |
||||||
|
|
||||||
|
void esp_profile_cb_reset(void) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i = 0; i < BTC_PID_NUM; i++) { |
||||||
|
btc_profile_cb_tab[i] = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int btc_profile_cb_set(btc_pid_t profile_id, void *cb) |
||||||
|
{ |
||||||
|
if (profile_id < 0 || profile_id >= BTC_PID_NUM) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
btc_profile_cb_tab[profile_id] = cb; |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void *btc_profile_cb_get(btc_pid_t profile_id) |
||||||
|
{ |
||||||
|
if (profile_id < 0 || profile_id >= BTC_PID_NUM) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
return btc_profile_cb_tab[profile_id]; |
||||||
|
} |
@ -0,0 +1,549 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "osi/thread.h" |
||||||
|
#include "esp_log.h" |
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "btc/btc_alarm.h" |
||||||
|
|
||||||
|
#include "btc/btc_manage.h" |
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "blufi_int.h" |
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#include "common/bt_target.h" |
||||||
|
#include "btc/btc_main.h" |
||||||
|
#include "btc/btc_dev.h" |
||||||
|
#include "btc_gatts.h" |
||||||
|
#include "btc_gattc.h" |
||||||
|
#include "btc_gatt_common.h" |
||||||
|
#include "btc_gap_ble.h" |
||||||
|
#include "btc/btc_dm.h" |
||||||
|
#include "bta/bta_gatt_api.h" |
||||||
|
#if CLASSIC_BT_INCLUDED |
||||||
|
#include "btc/btc_profile_queue.h" |
||||||
|
#if (BTC_GAP_BT_INCLUDED == TRUE) |
||||||
|
#include "btc_gap_bt.h" |
||||||
|
#endif /* BTC_GAP_BT_INCLUDED == TRUE */ |
||||||
|
#if BTC_AV_INCLUDED |
||||||
|
#include "btc_av.h" |
||||||
|
#include "btc_avrc.h" |
||||||
|
#include "btc_av_co.h" |
||||||
|
#endif /* #if BTC_AV_INCLUDED */ |
||||||
|
#if (BTC_SPP_INCLUDED == TRUE) |
||||||
|
#include "btc_spp.h" |
||||||
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */ |
||||||
|
#if (BTC_L2CAP_INCLUDED == TRUE) |
||||||
|
#include "btc_l2cap.h" |
||||||
|
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ |
||||||
|
#if (BTC_SDP_INCLUDED == TRUE) |
||||||
|
#include "btc_sdp.h" |
||||||
|
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */ |
||||||
|
#if BTC_HF_INCLUDED |
||||||
|
#include "btc_hf_ag.h" |
||||||
|
#endif/* #if BTC_HF_INCLUDED */ |
||||||
|
#if BTC_HF_CLIENT_INCLUDED |
||||||
|
#include "btc_hf_client.h" |
||||||
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */ |
||||||
|
#if BTC_HD_INCLUDED == TRUE |
||||||
|
#include "btc_hd.h" |
||||||
|
#endif /* BTC_HD_INCLUDED */ |
||||||
|
#if BTC_HH_INCLUDED == TRUE |
||||||
|
#include "btc_hh.h" |
||||||
|
#endif /* BTC_HH_INCLUDED */ |
||||||
|
#endif /* #if CLASSIC_BT_INCLUDED */ |
||||||
|
#endif |
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
#include "btc_gap_ble.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#if CONFIG_BLE_MESH |
||||||
|
#include "btc_ble_mesh_ble.h" |
||||||
|
#include "btc_ble_mesh_prov.h" |
||||||
|
#include "btc_ble_mesh_health_model.h" |
||||||
|
#include "btc_ble_mesh_config_model.h" |
||||||
|
#include "btc_ble_mesh_agg_model.h" |
||||||
|
#include "btc_ble_mesh_brc_model.h" |
||||||
|
#include "btc_ble_mesh_df_model.h" |
||||||
|
#include "btc_ble_mesh_lcd_model.h" |
||||||
|
#include "btc_ble_mesh_odp_model.h" |
||||||
|
#include "btc_ble_mesh_prb_model.h" |
||||||
|
#include "btc_ble_mesh_rpr_model.h" |
||||||
|
#include "btc_ble_mesh_sar_model.h" |
||||||
|
#include "btc_ble_mesh_srpl_model.h" |
||||||
|
#include "btc_ble_mesh_generic_model.h" |
||||||
|
#include "btc_ble_mesh_lighting_model.h" |
||||||
|
#include "btc_ble_mesh_sensor_model.h" |
||||||
|
#include "btc_ble_mesh_time_scene_model.h" |
||||||
|
#include "btc_ble_mesh_mbt_model.h" |
||||||
|
#endif /* #if CONFIG_BLE_MESH */ |
||||||
|
|
||||||
|
#define BTC_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE) |
||||||
|
#define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
|
||||||
|
#define BTC_TASK_NAME "BTC_TASK" |
||||||
|
#define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6) |
||||||
|
#define BTC_TASK_WORKQUEUE_NUM (2) |
||||||
|
#define BTC_TASK_WORKQUEUE0_LEN (0) |
||||||
|
#define BTC_TASK_WORKQUEUE1_LEN (5) |
||||||
|
|
||||||
|
osi_thread_t *btc_thread; |
||||||
|
|
||||||
|
static const btc_func_t profile_tab[BTC_PID_NUM] = { |
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL }, |
||||||
|
[BTC_PID_DEV] = {btc_dev_call_handler, NULL }, |
||||||
|
#if (GATTS_INCLUDED == TRUE) |
||||||
|
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler }, |
||||||
|
#endif ///GATTS_INCLUDED == TRUE
|
||||||
|
#if (GATTC_INCLUDED == TRUE) |
||||||
|
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler }, |
||||||
|
#endif ///GATTC_INCLUDED == TRUE
|
||||||
|
#if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE) |
||||||
|
[BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL }, |
||||||
|
#endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
|
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler }, |
||||||
|
#else |
||||||
|
[BTC_PID_GAP_BLE] = {NULL, NULL}, |
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
[BTC_PID_BLE_HID] = {NULL, NULL}, |
||||||
|
[BTC_PID_SPPLIKE] = {NULL, NULL}, |
||||||
|
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler }, |
||||||
|
#endif |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler }, |
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
||||||
|
[BTC_PID_ALARM] = {btc_alarm_handler, NULL }, |
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#if CLASSIC_BT_INCLUDED |
||||||
|
#if (BTC_GAP_BT_INCLUDED == TRUE) |
||||||
|
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, btc_gap_bt_cb_handler }, |
||||||
|
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */ |
||||||
|
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL }, |
||||||
|
#if BTC_AV_INCLUDED |
||||||
|
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler }, |
||||||
|
[BTC_PID_AVRC_CT] = {btc_avrc_ct_call_handler, NULL }, |
||||||
|
[BTC_PID_AVRC_TG] = {btc_avrc_tg_call_handler, NULL }, |
||||||
|
#endif /* #if BTC_AV_INCLUDED */ |
||||||
|
#if (BTC_SPP_INCLUDED == TRUE) |
||||||
|
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler }, |
||||||
|
#endif /* #if (BTC_SPP_INCLUDED == TRUE) */ |
||||||
|
#if (BTC_L2CAP_INCLUDED == TRUE) |
||||||
|
[BTC_PID_L2CAP] = {btc_l2cap_call_handler, btc_l2cap_cb_handler }, |
||||||
|
#endif /* #if (BTC_L2CAP_INCLUDED == TRUE) */ |
||||||
|
#if (BTC_SDP_INCLUDED == TRUE) |
||||||
|
[BTC_PID_SDP] = {btc_sdp_call_handler, btc_sdp_cb_handler }, |
||||||
|
#endif /* #if (BTC_SDP_INCLUDED == TRUE) */ |
||||||
|
#if BTC_HF_INCLUDED |
||||||
|
[BTC_PID_HF] = {btc_hf_call_handler, btc_hf_cb_handler}, |
||||||
|
#endif /* #if BTC_HF_INCLUDED */ |
||||||
|
#if BTC_HF_CLIENT_INCLUDED |
||||||
|
[BTC_PID_HF_CLIENT] = {btc_hf_client_call_handler, btc_hf_client_cb_handler}, |
||||||
|
#endif /* #if BTC_HF_CLIENT_INCLUDED */ |
||||||
|
#if BTC_HD_INCLUDED |
||||||
|
[BTC_PID_HD] = {btc_hd_call_handler, btc_hd_cb_handler }, |
||||||
|
#endif |
||||||
|
#if BTC_HH_INCLUDED |
||||||
|
[BTC_PID_HH] = {btc_hh_call_handler, btc_hh_cb_handler }, |
||||||
|
#endif |
||||||
|
#endif /* #if CLASSIC_BT_INCLUDED */ |
||||||
|
#endif |
||||||
|
#if CONFIG_BLE_MESH |
||||||
|
[BTC_PID_PROV] = {btc_ble_mesh_prov_call_handler, btc_ble_mesh_prov_cb_handler }, |
||||||
|
[BTC_PID_MODEL] = {btc_ble_mesh_model_call_handler, btc_ble_mesh_model_cb_handler }, |
||||||
|
#if CONFIG_BLE_MESH_HEALTH_CLI |
||||||
|
[BTC_PID_HEALTH_CLIENT] = {btc_ble_mesh_health_client_call_handler, btc_ble_mesh_health_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_HEALTH_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_HEALTH_SRV |
||||||
|
[BTC_PID_HEALTH_SERVER] = {btc_ble_mesh_health_server_call_handler, btc_ble_mesh_health_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_HEALTH_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_CFG_CLI |
||||||
|
[BTC_PID_CONFIG_CLIENT] = {btc_ble_mesh_config_client_call_handler, btc_ble_mesh_config_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_CFG_CLI */ |
||||||
|
[BTC_PID_CONFIG_SERVER] = {NULL, btc_ble_mesh_config_server_cb_handler }, |
||||||
|
#if CONFIG_BLE_MESH_AGG_CLI |
||||||
|
[BTC_PID_AGG_CLIENT] = {btc_ble_mesh_agg_client_call_handler, btc_ble_mesh_agg_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_AGG_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_AGG_SRV |
||||||
|
[BTC_PID_AGG_SERVER] = {NULL, btc_ble_mesh_agg_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_AGG_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_BRC_CLI |
||||||
|
[BTC_PID_BRC_CLIENT] = {btc_ble_mesh_brc_client_call_handler, btc_ble_mesh_brc_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_BRC_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_BRC_SRV |
||||||
|
[BTC_PID_BRC_SERVER] = {NULL, btc_ble_mesh_brc_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_BRC_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_DF_CLI |
||||||
|
[BTC_PID_DF_CLIENT] = {btc_ble_mesh_df_client_call_handler, btc_ble_mesh_df_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_DF_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_DF_SRV |
||||||
|
[BTC_PID_DF_SERVER] = {NULL, btc_ble_mesh_df_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_DF_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_LCD_CLI |
||||||
|
[BTC_PID_LCD_CLIENT] = {btc_ble_mesh_lcd_client_call_handler, btc_ble_mesh_lcd_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_LCD_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_LCD_SRV |
||||||
|
[BTC_PID_LCD_SERVER] = {NULL, btc_ble_mesh_lcd_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_LCD_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_ODP_CLI |
||||||
|
[BTC_PID_ODP_CLIENT] = {btc_ble_mesh_odp_client_call_handler, btc_ble_mesh_odp_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_ODP_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_ODP_SRV |
||||||
|
[BTC_PID_ODP_SERVER] = {NULL, btc_ble_mesh_odp_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_ODP_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_PRB_CLI |
||||||
|
[BTC_PID_PRB_CLIENT] = {btc_ble_mesh_prb_client_call_handler, btc_ble_mesh_prb_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_PRB_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_PRB_SRV |
||||||
|
[BTC_PID_PRB_SERVER] = {NULL, btc_ble_mesh_prb_server_cb_handler }, |
||||||
|
#endif /*CONFIG_BLE_MESH_PRB_SRV*/ |
||||||
|
#if CONFIG_BLE_MESH_RPR_CLI |
||||||
|
[BTC_PID_RPR_CLIENT] = {btc_ble_mesh_rpr_client_call_handler, btc_ble_mesh_rpr_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_RPR_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_RPR_SRV |
||||||
|
[BTC_PID_RPR_SERVER] = {NULL, btc_ble_mesh_rpr_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_RPR_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_SAR_CLI |
||||||
|
[BTC_PID_SAR_CLIENT] = {btc_ble_mesh_sar_client_call_handler, btc_ble_mesh_sar_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SAR_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_SAR_SRV |
||||||
|
[BTC_PID_SAR_SERVER] = {NULL, btc_ble_mesh_sar_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SAR_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_SRPL_CLI |
||||||
|
[BTC_PID_SRPL_CLIENT] = {btc_ble_mesh_srpl_client_call_handler, btc_ble_mesh_srpl_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SRPL_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_SRPL_SRV |
||||||
|
[BTC_PID_SRPL_SERVER] = {NULL, btc_ble_mesh_srpl_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SRPL_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_GENERIC_CLIENT |
||||||
|
[BTC_PID_GENERIC_CLIENT] = {btc_ble_mesh_generic_client_call_handler, btc_ble_mesh_generic_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_GENERIC_CLIENT */ |
||||||
|
#if CONFIG_BLE_MESH_LIGHTING_CLIENT |
||||||
|
[BTC_PID_LIGHTING_CLIENT] = {btc_ble_mesh_lighting_client_call_handler, btc_ble_mesh_lighting_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_LIGHTING_CLIENT */ |
||||||
|
#if CONFIG_BLE_MESH_SENSOR_CLI |
||||||
|
[BTC_PID_SENSOR_CLIENT] = {btc_ble_mesh_sensor_client_call_handler, btc_ble_mesh_sensor_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SENSOR_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_TIME_SCENE_CLIENT |
||||||
|
[BTC_PID_TIME_SCENE_CLIENT] = {btc_ble_mesh_time_scene_client_call_handler, btc_ble_mesh_time_scene_client_cb_handler}, |
||||||
|
#endif /* CONFIG_BLE_MESH_TIME_SCENE_CLIENT */ |
||||||
|
#if CONFIG_BLE_MESH_GENERIC_SERVER |
||||||
|
[BTC_PID_GENERIC_SERVER] = {NULL, btc_ble_mesh_generic_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_GENERIC_SERVER */ |
||||||
|
#if CONFIG_BLE_MESH_LIGHTING_SERVER |
||||||
|
[BTC_PID_LIGHTING_SERVER] = {NULL, btc_ble_mesh_lighting_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_LIGHTING_SERVER */ |
||||||
|
#if CONFIG_BLE_MESH_SENSOR_SERVER |
||||||
|
[BTC_PID_SENSOR_SERVER] = {NULL, btc_ble_mesh_sensor_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_SENSOR_SERVER */ |
||||||
|
#if CONFIG_BLE_MESH_TIME_SCENE_SERVER |
||||||
|
[BTC_PID_TIME_SCENE_SERVER] = {NULL, btc_ble_mesh_time_scene_server_cb_handler}, |
||||||
|
#endif /* CONFIG_BLE_MESH_TIME_SCENE_SERVER */ |
||||||
|
#if CONFIG_BLE_MESH_MBT_CLI |
||||||
|
[BTC_PID_MBT_CLIENT] = {btc_ble_mesh_mbt_client_call_handler, btc_ble_mesh_mbt_client_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_MBT_CLI */ |
||||||
|
#if CONFIG_BLE_MESH_MBT_SRV |
||||||
|
[BTC_PID_MBT_SERVER] = {btc_ble_mesh_mbt_server_call_handler, btc_ble_mesh_mbt_server_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_MBT_SRV */ |
||||||
|
#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT |
||||||
|
[BTC_PID_BLE_MESH_BLE_COEX] = {btc_ble_mesh_ble_call_handler, btc_ble_mesh_ble_cb_handler }, |
||||||
|
#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */ |
||||||
|
#endif /* #if CONFIG_BLE_MESH */ |
||||||
|
}; |
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** |
||||||
|
** Function btc_task |
||||||
|
** |
||||||
|
** Description Process profile Task Thread. |
||||||
|
******************************************************************************/ |
||||||
|
static void btc_thread_handler(void *arg) |
||||||
|
{ |
||||||
|
btc_msg_t *msg = (btc_msg_t *)arg; |
||||||
|
|
||||||
|
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, msg->arg); |
||||||
|
switch (msg->sig) { |
||||||
|
case BTC_SIG_API_CALL: |
||||||
|
profile_tab[msg->pid].btc_call(msg); |
||||||
|
break; |
||||||
|
case BTC_SIG_API_CB: |
||||||
|
profile_tab[msg->pid].btc_cb(msg); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
osi_free(msg); |
||||||
|
} |
||||||
|
|
||||||
|
static bt_status_t btc_task_post(btc_msg_t *msg, uint32_t timeout) |
||||||
|
{ |
||||||
|
if (osi_thread_post(btc_thread, btc_thread_handler, msg, 0, timeout) == false) { |
||||||
|
return BT_STATUS_BUSY; |
||||||
|
} |
||||||
|
|
||||||
|
return BT_STATUS_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* transfer an message to another module in the different task. |
||||||
|
* @param msg message |
||||||
|
* @param arg paramter |
||||||
|
* @param arg_len length of paramter |
||||||
|
* @param copy_func deep copy function |
||||||
|
* @param free_func deep free function |
||||||
|
* @return BT_STATUS_SUCCESS: success |
||||||
|
* others: fail |
||||||
|
*/ |
||||||
|
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func, |
||||||
|
btc_arg_deep_free_t free_func) |
||||||
|
{ |
||||||
|
btc_msg_t* lmsg; |
||||||
|
bt_status_t ret; |
||||||
|
// arg XOR arg_len
|
||||||
|
if ((msg == NULL) || ((arg == NULL) == !(arg_len == 0))) { |
||||||
|
BTC_TRACE_WARNING("%s Invalid parameters\n", __func__); |
||||||
|
return BT_STATUS_PARM_INVALID; |
||||||
|
} |
||||||
|
|
||||||
|
BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg); |
||||||
|
|
||||||
|
lmsg = (btc_msg_t *)osi_malloc(sizeof(btc_msg_t) + arg_len); |
||||||
|
if (lmsg == NULL) { |
||||||
|
BTC_TRACE_WARNING("%s No memory\n", __func__); |
||||||
|
return BT_STATUS_NOMEM; |
||||||
|
} |
||||||
|
|
||||||
|
memcpy(lmsg, msg, sizeof(btc_msg_t)); |
||||||
|
if (arg) { |
||||||
|
memset(lmsg->arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||||
|
memcpy(lmsg->arg, arg, arg_len); |
||||||
|
if (copy_func) { |
||||||
|
copy_func(lmsg, lmsg->arg, arg); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ret = btc_task_post(lmsg, OSI_THREAD_MAX_TIMEOUT); |
||||||
|
if (ret != BT_STATUS_SUCCESS) { |
||||||
|
if (copy_func && free_func) { |
||||||
|
free_func(lmsg); |
||||||
|
} |
||||||
|
osi_free(lmsg); |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* transfer an message to another module in tha same task. |
||||||
|
* @param msg message |
||||||
|
* @return BT_STATUS_SUCCESS: success |
||||||
|
* others: fail |
||||||
|
*/ |
||||||
|
bt_status_t btc_inter_profile_call(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
if (msg == NULL) { |
||||||
|
return BT_STATUS_PARM_INVALID; |
||||||
|
} |
||||||
|
|
||||||
|
switch (msg->sig) { |
||||||
|
case BTC_SIG_API_CALL: |
||||||
|
profile_tab[msg->pid].btc_call(msg); |
||||||
|
break; |
||||||
|
case BTC_SIG_API_CB: |
||||||
|
profile_tab[msg->pid].btc_cb(msg); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
return BT_STATUS_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY |
||||||
|
|
||||||
|
static void btc_deinit_mem(void) { |
||||||
|
if (btc_dm_cb_ptr) { |
||||||
|
osi_free(btc_dm_cb_ptr); |
||||||
|
btc_dm_cb_ptr = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (btc_profile_cb_tab) { |
||||||
|
osi_free(btc_profile_cb_tab); |
||||||
|
btc_profile_cb_tab = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
if (gl_bta_adv_data_ptr) { |
||||||
|
osi_free(gl_bta_adv_data_ptr); |
||||||
|
gl_bta_adv_data_ptr = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (gl_bta_scan_rsp_data_ptr) { |
||||||
|
osi_free(gl_bta_scan_rsp_data_ptr); |
||||||
|
gl_bta_scan_rsp_data_ptr = NULL; |
||||||
|
} |
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE |
||||||
|
if (btc_creat_tab_env_ptr) { |
||||||
|
osi_free(btc_creat_tab_env_ptr); |
||||||
|
btc_creat_tab_env_ptr = NULL; |
||||||
|
} |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
if (blufi_env_ptr) { |
||||||
|
osi_free(blufi_env_ptr); |
||||||
|
blufi_env_ptr = NULL; |
||||||
|
} |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE |
||||||
|
if (hf_client_local_param_ptr) { |
||||||
|
osi_free(hf_client_local_param_ptr); |
||||||
|
hf_client_local_param_ptr = NULL; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE |
||||||
|
if (btc_rc_cb_ptr) { |
||||||
|
osi_free(btc_rc_cb_ptr); |
||||||
|
btc_rc_cb_ptr = NULL; |
||||||
|
} |
||||||
|
if (bta_av_co_cb_ptr) { |
||||||
|
osi_free(bta_av_co_cb_ptr); |
||||||
|
bta_av_co_cb_ptr = NULL; |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
static bt_status_t btc_init_mem(void) { |
||||||
|
if ((btc_dm_cb_ptr = (btc_dm_cb_t *)osi_malloc(sizeof(btc_dm_cb_t))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)btc_dm_cb_ptr, 0, sizeof(btc_dm_cb_t)); |
||||||
|
|
||||||
|
if ((btc_profile_cb_tab = (void **)osi_malloc(sizeof(void *) * BTC_PID_NUM)) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)btc_profile_cb_tab, 0, sizeof(void *) * BTC_PID_NUM); |
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
if ((gl_bta_adv_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)gl_bta_adv_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA)); |
||||||
|
|
||||||
|
if ((gl_bta_scan_rsp_data_ptr = (tBTA_BLE_ADV_DATA *)osi_malloc(sizeof(tBTA_BLE_ADV_DATA))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)gl_bta_scan_rsp_data_ptr, 0, sizeof(tBTA_BLE_ADV_DATA)); |
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if GATTS_INCLUDED == TRUE && GATT_DYNAMIC_MEMORY == TRUE |
||||||
|
if ((btc_creat_tab_env_ptr = (esp_btc_creat_tab_t *)osi_malloc(sizeof(esp_btc_creat_tab_t))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)btc_creat_tab_env_ptr, 0, sizeof(esp_btc_creat_tab_t)); |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
if ((blufi_env_ptr = (tBLUFI_ENV *)osi_malloc(sizeof(tBLUFI_ENV))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)blufi_env_ptr, 0, sizeof(tBLUFI_ENV)); |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE |
||||||
|
if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)hf_client_local_param_ptr, 0, sizeof(hf_client_local_param_t)); |
||||||
|
#endif |
||||||
|
|
||||||
|
#if BTC_AV_INCLUDED == TRUE && AVRC_DYNAMIC_MEMORY == TRUE |
||||||
|
if ((btc_rc_cb_ptr = (btc_rc_cb_t *)osi_malloc(sizeof(btc_rc_cb_t))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)btc_rc_cb_ptr, 0, sizeof(btc_rc_cb_t)); |
||||||
|
if ((bta_av_co_cb_ptr = (tBTA_AV_CO_CB *)osi_malloc(sizeof(tBTA_AV_CO_CB))) == NULL) { |
||||||
|
goto error_exit; |
||||||
|
} |
||||||
|
memset((void *)bta_av_co_cb_ptr, 0, sizeof(tBTA_AV_CO_CB)); |
||||||
|
#endif |
||||||
|
|
||||||
|
return BT_STATUS_SUCCESS; |
||||||
|
|
||||||
|
error_exit:; |
||||||
|
btc_deinit_mem(); |
||||||
|
return BT_STATUS_NOMEM; |
||||||
|
} |
||||||
|
#endif ///BTC_DYNAMIC_MEMORY
|
||||||
|
|
||||||
|
bt_status_t btc_init(void) |
||||||
|
{ |
||||||
|
const size_t workqueue_len[] = {BTC_TASK_WORKQUEUE0_LEN, BTC_TASK_WORKQUEUE1_LEN}; |
||||||
|
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, |
||||||
|
BTC_TASK_WORKQUEUE_NUM, workqueue_len); |
||||||
|
if (btc_thread == NULL) { |
||||||
|
return BT_STATUS_NOMEM; |
||||||
|
} |
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY |
||||||
|
if (btc_init_mem() != BT_STATUS_SUCCESS){ |
||||||
|
return BT_STATUS_NOMEM; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
btc_gap_callback_init(); |
||||||
|
btc_gap_ble_init(); |
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
|
||||||
|
#if SCAN_QUEUE_CONGEST_CHECK |
||||||
|
btc_adv_list_init(); |
||||||
|
#endif |
||||||
|
/* TODO: initial the profile_tab */ |
||||||
|
return BT_STATUS_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
void btc_deinit(void) |
||||||
|
{ |
||||||
|
#if BTC_DYNAMIC_MEMORY |
||||||
|
btc_deinit_mem(); |
||||||
|
#endif |
||||||
|
|
||||||
|
osi_thread_free(btc_thread); |
||||||
|
btc_thread = NULL; |
||||||
|
#if (BLE_INCLUDED == TRUE) |
||||||
|
btc_gap_ble_deinit(); |
||||||
|
#endif ///BLE_INCLUDED == TRUE
|
||||||
|
#if SCAN_QUEUE_CONGEST_CHECK |
||||||
|
btc_adv_list_deinit(); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
bool btc_check_queue_is_congest(void) |
||||||
|
{ |
||||||
|
if (osi_thread_queue_wait_size(btc_thread, 0) >= BT_QUEUE_CONGEST_SIZE) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
int get_btc_work_queue_size(void) |
||||||
|
{ |
||||||
|
return osi_thread_queue_wait_size(btc_thread, 0); |
||||||
|
} |
||||||
|
|
||||||
|
osi_thread_t *btc_get_current_thread(void) |
||||||
|
{ |
||||||
|
return btc_thread; |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#ifndef __BTC_ALARM_H__ |
||||||
|
#define __BTC_ALARM_H__ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include "osi/alarm.h" |
||||||
|
|
||||||
|
/* btc_alarm_args_t */ |
||||||
|
typedef struct { |
||||||
|
osi_alarm_callback_t cb; |
||||||
|
void *cb_data; |
||||||
|
} btc_alarm_args_t; |
||||||
|
|
||||||
|
void btc_alarm_handler(btc_msg_t *msg); |
||||||
|
|
||||||
|
#endif /* __BTC_ALARM_H__ */ |
@ -0,0 +1,23 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __BTC_MANAGE_H__ |
||||||
|
#define __BTC_MANAGE_H__ |
||||||
|
|
||||||
|
#include "btc/btc_task.h" |
||||||
|
|
||||||
|
#if BTC_DYNAMIC_MEMORY == FALSE |
||||||
|
extern void *btc_profile_cb_tab[BTC_PID_NUM]; |
||||||
|
#else |
||||||
|
extern void **btc_profile_cb_tab; |
||||||
|
#endif |
||||||
|
/* reset gatt callback table */ |
||||||
|
void esp_profile_cb_reset(void); |
||||||
|
|
||||||
|
int btc_profile_cb_set(btc_pid_t profile_id, void *cb); |
||||||
|
void *btc_profile_cb_get(btc_pid_t profile_id); |
||||||
|
|
||||||
|
#endif /* __BTC_MANAGE_H__ */ |
@ -0,0 +1,160 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __BTC_TASK_H__ |
||||||
|
#define __BTC_TASK_H__ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/thread.h" |
||||||
|
|
||||||
|
#if CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#include "common/bt_target.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef struct btc_msg { |
||||||
|
uint8_t sig; //event signal
|
||||||
|
uint8_t aid; //application id
|
||||||
|
uint8_t pid; //profile id
|
||||||
|
uint8_t act; //profile action, defined in seprerate header files
|
||||||
|
UINT8 arg[0]; //param for btc function or function param
|
||||||
|
} btc_msg_t; |
||||||
|
|
||||||
|
typedef struct btc_adv_packet { |
||||||
|
uint8_t addr[6]; |
||||||
|
uint8_t addr_type; |
||||||
|
} btc_adv_packet_t; |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
BTC_SIG_API_CALL = 0, // APP TO STACK
|
||||||
|
BTC_SIG_API_CB, // STACK TO APP
|
||||||
|
BTC_SIG_NUM, |
||||||
|
} btc_sig_t; //btc message type
|
||||||
|
|
||||||
|
typedef enum { |
||||||
|
BTC_PID_MAIN_INIT = 0, |
||||||
|
BTC_PID_DEV, |
||||||
|
BTC_PID_GATTS, |
||||||
|
#if (GATTC_INCLUDED == TRUE) |
||||||
|
BTC_PID_GATTC, |
||||||
|
#endif ///GATTC_INCLUDED == TRUE
|
||||||
|
BTC_PID_GATT_COMMON, |
||||||
|
BTC_PID_GAP_BLE, |
||||||
|
BTC_PID_BLE_HID, |
||||||
|
BTC_PID_SPPLIKE, |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
BTC_PID_BLUFI, |
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
||||||
|
BTC_PID_DM_SEC, |
||||||
|
BTC_PID_ALARM, |
||||||
|
#if (CLASSIC_BT_INCLUDED == TRUE) |
||||||
|
BTC_PID_GAP_BT, |
||||||
|
BTC_PID_PRF_QUE, |
||||||
|
BTC_PID_A2DP, |
||||||
|
BTC_PID_AVRC_CT, |
||||||
|
BTC_PID_AVRC_TG, |
||||||
|
BTC_PID_SPP, |
||||||
|
BTC_PID_HD, |
||||||
|
BTC_PID_HH, |
||||||
|
BTC_PID_L2CAP, |
||||||
|
BTC_PID_SDP, |
||||||
|
#if (BTC_HF_INCLUDED == TRUE) |
||||||
|
BTC_PID_HF, |
||||||
|
#endif /* BTC_HF_INCLUDED */ |
||||||
|
#if (BTC_HF_CLIENT_INCLUDED == TRUE) |
||||||
|
BTC_PID_HF_CLIENT, |
||||||
|
#endif /* BTC_HF_CLIENT_INCLUDED */ |
||||||
|
#endif /* CLASSIC_BT_INCLUDED */ |
||||||
|
#if CONFIG_BLE_MESH |
||||||
|
BTC_PID_PROV, |
||||||
|
BTC_PID_MODEL, |
||||||
|
BTC_PID_HEALTH_CLIENT, |
||||||
|
BTC_PID_HEALTH_SERVER, |
||||||
|
BTC_PID_CONFIG_CLIENT, |
||||||
|
BTC_PID_CONFIG_SERVER, |
||||||
|
BTC_PID_AGG_CLIENT, |
||||||
|
BTC_PID_AGG_SERVER, |
||||||
|
BTC_PID_BRC_CLIENT, |
||||||
|
BTC_PID_BRC_SERVER, |
||||||
|
BTC_PID_DF_CLIENT, |
||||||
|
BTC_PID_DF_SERVER, |
||||||
|
BTC_PID_LCD_CLIENT, |
||||||
|
BTC_PID_LCD_SERVER, |
||||||
|
BTC_PID_ODP_CLIENT, |
||||||
|
BTC_PID_ODP_SERVER, |
||||||
|
BTC_PID_PRB_CLIENT, |
||||||
|
BTC_PID_PRB_SERVER, |
||||||
|
BTC_PID_RPR_CLIENT, |
||||||
|
BTC_PID_RPR_SERVER, |
||||||
|
BTC_PID_SAR_CLIENT, |
||||||
|
BTC_PID_SAR_SERVER, |
||||||
|
BTC_PID_SRPL_CLIENT, |
||||||
|
BTC_PID_SRPL_SERVER, |
||||||
|
BTC_PID_GENERIC_CLIENT, |
||||||
|
BTC_PID_LIGHTING_CLIENT, |
||||||
|
BTC_PID_SENSOR_CLIENT, |
||||||
|
BTC_PID_TIME_SCENE_CLIENT, |
||||||
|
BTC_PID_GENERIC_SERVER, |
||||||
|
BTC_PID_LIGHTING_SERVER, |
||||||
|
BTC_PID_SENSOR_SERVER, |
||||||
|
BTC_PID_TIME_SCENE_SERVER, |
||||||
|
BTC_PID_MBT_CLIENT, |
||||||
|
BTC_PID_MBT_SERVER, |
||||||
|
BTC_PID_BLE_MESH_BLE_COEX, |
||||||
|
#endif /* CONFIG_BLE_MESH */ |
||||||
|
BTC_PID_NUM, |
||||||
|
} btc_pid_t; //btc profile id
|
||||||
|
|
||||||
|
typedef struct { |
||||||
|
void (* btc_call)(btc_msg_t *msg); |
||||||
|
void (* btc_cb)(btc_msg_t *msg); |
||||||
|
} btc_func_t; |
||||||
|
|
||||||
|
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src); |
||||||
|
typedef void (* btc_arg_deep_free_t)(btc_msg_t *msg); |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* transfer an message to another module in the different task. |
||||||
|
* @param msg message |
||||||
|
* @param arg paramter |
||||||
|
* @param arg_len length of paramter |
||||||
|
* @param copy_func deep copy function |
||||||
|
* @param free_func deep free function |
||||||
|
* @return BT_STATUS_SUCCESS: success |
||||||
|
* others: fail |
||||||
|
*/ |
||||||
|
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func, |
||||||
|
btc_arg_deep_free_t free_func); |
||||||
|
|
||||||
|
/**
|
||||||
|
* transfer an message to another module in tha same task. |
||||||
|
* @param msg message |
||||||
|
* @return BT_STATUS_SUCCESS: success |
||||||
|
* others: fail |
||||||
|
*/ |
||||||
|
bt_status_t btc_inter_profile_call(btc_msg_t *msg); |
||||||
|
|
||||||
|
bt_status_t btc_init(void); |
||||||
|
void btc_deinit(void); |
||||||
|
bool btc_check_queue_is_congest(void); |
||||||
|
int get_btc_work_queue_size(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* get the BTC thread handle |
||||||
|
* @return NULL: fail |
||||||
|
* others: pointer of osi_thread structure of BTC |
||||||
|
*/ |
||||||
|
osi_thread_t *btc_get_current_thread(void); |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* __BTC_TASK_H__ */ |
@ -0,0 +1,422 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc/btc_manage.h" |
||||||
|
#include "blufi_int.h" |
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "esp_log.h" |
||||||
|
#include "esp_blufi_api.h" |
||||||
|
|
||||||
|
#include "common/bt_target.h" |
||||||
|
#include "common/bt_trace.h" |
||||||
|
#include "stack/bt_types.h" |
||||||
|
#include "stack/gatt_api.h" |
||||||
|
#include "bta/bta_api.h" |
||||||
|
#include "bta/bta_gatt_api.h" |
||||||
|
#include "bta_gatts_int.h" |
||||||
|
#include "btc_gatt_util.h" |
||||||
|
#include "btc_gatts.h" |
||||||
|
|
||||||
|
#include "esp_bt_defs.h" |
||||||
|
#include "esp_gap_ble_api.h" |
||||||
|
#include "esp_gatt_common_api.h" |
||||||
|
#include "esp_bt_main.h" |
||||||
|
#include "esp_bt_device.h" |
||||||
|
#include "esp_err.h" |
||||||
|
#include "esp_blufi.h" |
||||||
|
|
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
|
||||||
|
static uint8_t server_if; |
||||||
|
static uint16_t conn_id; |
||||||
|
static uint8_t blufi_service_uuid128[32] = { |
||||||
|
/* LSB <--------------------------------------------------------------------------------> MSB */ |
||||||
|
//first uuid, 16bit, [12],[13] is the value
|
||||||
|
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, |
||||||
|
}; |
||||||
|
|
||||||
|
static esp_ble_adv_data_t blufi_adv_data = { |
||||||
|
.set_scan_rsp = false, |
||||||
|
.include_name = true, |
||||||
|
.include_txpower = true, |
||||||
|
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
|
||||||
|
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
|
||||||
|
.appearance = 0x00, |
||||||
|
.manufacturer_len = 0, |
||||||
|
.p_manufacturer_data = NULL, |
||||||
|
.service_data_len = 0, |
||||||
|
.p_service_data = NULL, |
||||||
|
.service_uuid_len = 16, |
||||||
|
.p_service_uuid = blufi_service_uuid128, |
||||||
|
.flag = 0x6, |
||||||
|
}; |
||||||
|
|
||||||
|
static esp_ble_adv_params_t blufi_adv_params = { |
||||||
|
.adv_int_min = 0x100, |
||||||
|
.adv_int_max = 0x100, |
||||||
|
.adv_type = ADV_TYPE_IND, |
||||||
|
.own_addr_type = BLE_ADDR_TYPE_PUBLIC, |
||||||
|
//.peer_addr =
|
||||||
|
//.peer_addr_type =
|
||||||
|
.channel_map = ADV_CHNL_ALL, |
||||||
|
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, |
||||||
|
}; |
||||||
|
|
||||||
|
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) |
||||||
|
{ |
||||||
|
switch (event) { |
||||||
|
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: |
||||||
|
esp_ble_gap_start_advertising(&blufi_adv_params); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// static functions declare
|
||||||
|
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data); |
||||||
|
|
||||||
|
void blufi_create_service(void) |
||||||
|
{ |
||||||
|
if (!blufi_env.enabled) { |
||||||
|
BTC_TRACE_ERROR("blufi service added error."); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
blufi_env.srvc_inst = 0x00; |
||||||
|
BTA_GATTS_CreateService(blufi_env.gatt_if, &blufi_srvc_uuid, blufi_env.srvc_inst, BLUFI_HDL_NUM, true); |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t esp_blufi_init(void) |
||||||
|
{ |
||||||
|
|
||||||
|
/* register the BLUFI profile to the BTA_GATTS module*/ |
||||||
|
BTA_GATTS_AppRegister(&blufi_app_uuid, blufi_profile_cb); |
||||||
|
return GATT_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) |
||||||
|
{ |
||||||
|
tBTA_GATTS_RSP rsp; |
||||||
|
BLUFI_TRACE_DEBUG("blufi profile cb event = %x\n", event); |
||||||
|
|
||||||
|
switch (event) { |
||||||
|
case BTA_GATTS_REG_EVT: |
||||||
|
BLUFI_TRACE_DEBUG("REG: status %d, app_uuid %04x, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.uuid.uu.uuid16, p_data->reg_oper.server_if); |
||||||
|
|
||||||
|
if (p_data->reg_oper.status != BTA_GATT_OK) { |
||||||
|
BLUFI_TRACE_ERROR("BLUFI profile register failed\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
blufi_env.gatt_if = p_data->reg_oper.server_if; |
||||||
|
blufi_env.enabled = true; |
||||||
|
|
||||||
|
//create the blufi service to the service data base.
|
||||||
|
if (p_data->reg_oper.uuid.uu.uuid16 == BLUFI_APP_UUID) { |
||||||
|
BLUFI_TRACE_DEBUG("%s %d\n", __func__, __LINE__); |
||||||
|
blufi_create_service(); |
||||||
|
} |
||||||
|
break; |
||||||
|
case BTA_GATTS_DEREG_EVT: { |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
btc_msg_t msg; |
||||||
|
|
||||||
|
BLUFI_TRACE_DEBUG("DEREG: status %d, gatt_if %d\n", p_data->reg_oper.status, p_data->reg_oper.server_if); |
||||||
|
|
||||||
|
if (p_data->reg_oper.status != BTA_GATT_OK) { |
||||||
|
BLUFI_TRACE_ERROR("BLUFI profile unregister failed\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
blufi_env.enabled = false; |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_DEINIT_FINISH; |
||||||
|
param.deinit_finish.state = ESP_BLUFI_DEINIT_OK; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
|
||||||
|
break; |
||||||
|
} |
||||||
|
case BTA_GATTS_READ_EVT: |
||||||
|
memset(&rsp, 0, sizeof(tBTA_GATTS_API_RSP)); |
||||||
|
rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle; |
||||||
|
rsp.attr_value.len = 1; |
||||||
|
rsp.attr_value.value[0] = 0x00; |
||||||
|
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, |
||||||
|
p_data->req_data.status, &rsp); |
||||||
|
break; |
||||||
|
case BTA_GATTS_WRITE_EVT: { |
||||||
|
if (p_data->req_data.p_data->write_req.is_prep) { |
||||||
|
tBTA_GATT_STATUS status = GATT_SUCCESS; |
||||||
|
|
||||||
|
if (blufi_env.prepare_buf == NULL) { |
||||||
|
blufi_env.prepare_buf = osi_malloc(BLUFI_PREPAIR_BUF_MAX_SIZE); |
||||||
|
blufi_env.prepare_len = 0; |
||||||
|
if (blufi_env.prepare_buf == NULL) { |
||||||
|
BLUFI_TRACE_ERROR("Blufi prep no mem\n"); |
||||||
|
status = GATT_NO_RESOURCES; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (p_data->req_data.p_data->write_req.offset > BLUFI_PREPAIR_BUF_MAX_SIZE) { |
||||||
|
status = GATT_INVALID_OFFSET; |
||||||
|
} else if ((p_data->req_data.p_data->write_req.offset + p_data->req_data.p_data->write_req.len) > BLUFI_PREPAIR_BUF_MAX_SIZE) { |
||||||
|
status = GATT_INVALID_ATTR_LEN; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
memset(&rsp, 0, sizeof(tGATTS_RSP)); |
||||||
|
rsp.attr_value.handle = p_data->req_data.p_data->write_req.handle; |
||||||
|
rsp.attr_value.len = p_data->req_data.p_data->write_req.len; |
||||||
|
rsp.attr_value.offset = p_data->req_data.p_data->write_req.offset; |
||||||
|
memcpy(rsp.attr_value.value, p_data->req_data.p_data->write_req.value, p_data->req_data.p_data->write_req.len); |
||||||
|
|
||||||
|
BLUFI_TRACE_DEBUG("prep write, len=%d, offset=%d\n", p_data->req_data.p_data->write_req.len, p_data->req_data.p_data->write_req.offset); |
||||||
|
|
||||||
|
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, |
||||||
|
status, &rsp); |
||||||
|
|
||||||
|
if (status != GATT_SUCCESS) { |
||||||
|
if (blufi_env.prepare_buf) { |
||||||
|
osi_free(blufi_env.prepare_buf); |
||||||
|
blufi_env.prepare_buf = NULL; |
||||||
|
blufi_env.prepare_len = 0; |
||||||
|
} |
||||||
|
BLUFI_TRACE_ERROR("write data error , error code 0x%x\n", status); |
||||||
|
return; |
||||||
|
} |
||||||
|
memcpy(blufi_env.prepare_buf + p_data->req_data.p_data->write_req.offset, |
||||||
|
p_data->req_data.p_data->write_req.value, |
||||||
|
p_data->req_data.p_data->write_req.len); |
||||||
|
blufi_env.prepare_len += p_data->req_data.p_data->write_req.len; |
||||||
|
|
||||||
|
return; |
||||||
|
} else { |
||||||
|
BLUFI_TRACE_DEBUG("norm write, len=%d, offset=%d\n", p_data->req_data.p_data->write_req.len, p_data->req_data.p_data->write_req.offset); |
||||||
|
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, |
||||||
|
p_data->req_data.status, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
if (p_data->req_data.p_data->write_req.handle == blufi_env.handle_char_p2e) { |
||||||
|
btc_blufi_recv_handler(&p_data->req_data.p_data->write_req.value[0], |
||||||
|
p_data->req_data.p_data->write_req.len); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTA_GATTS_EXEC_WRITE_EVT: |
||||||
|
BLUFI_TRACE_DEBUG("exec write exec %d\n", p_data->req_data.p_data->exec_write); |
||||||
|
|
||||||
|
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, |
||||||
|
GATT_SUCCESS, NULL); |
||||||
|
|
||||||
|
if (blufi_env.prepare_buf && p_data->req_data.p_data->exec_write == GATT_PREP_WRITE_EXEC) { |
||||||
|
btc_blufi_recv_handler(blufi_env.prepare_buf, blufi_env.prepare_len); |
||||||
|
} |
||||||
|
|
||||||
|
if (blufi_env.prepare_buf) { |
||||||
|
osi_free(blufi_env.prepare_buf); |
||||||
|
blufi_env.prepare_buf = NULL; |
||||||
|
blufi_env.prepare_len = 0; |
||||||
|
} |
||||||
|
|
||||||
|
break; |
||||||
|
case BTA_GATTS_MTU_EVT: |
||||||
|
BLUFI_TRACE_DEBUG("MTU size %d\n", p_data->req_data.p_data->mtu); |
||||||
|
blufi_env.frag_size = (p_data->req_data.p_data->mtu < BLUFI_MAX_DATA_LEN ? p_data->req_data.p_data->mtu : BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE; |
||||||
|
break; |
||||||
|
case BTA_GATTS_CONF_EVT: |
||||||
|
BLUFI_TRACE_DEBUG("CONFIRM EVT\n"); |
||||||
|
/* Nothing */ |
||||||
|
break; |
||||||
|
case BTA_GATTS_CREATE_EVT: |
||||||
|
blufi_env.handle_srvc = p_data->create.service_id; |
||||||
|
|
||||||
|
//add the frist blufi characteristic --> write characteristic
|
||||||
|
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_p2e, |
||||||
|
(GATT_PERM_WRITE), |
||||||
|
(GATT_CHAR_PROP_BIT_WRITE), |
||||||
|
NULL, NULL); |
||||||
|
break; |
||||||
|
case BTA_GATTS_ADD_CHAR_EVT: |
||||||
|
switch (p_data->add_result.char_uuid.uu.uuid16) { |
||||||
|
case BLUFI_CHAR_P2E_UUID: /* Phone to ESP32 */ |
||||||
|
blufi_env.handle_char_p2e = p_data->add_result.attr_id; |
||||||
|
|
||||||
|
BTA_GATTS_AddCharacteristic(blufi_env.handle_srvc, &blufi_char_uuid_e2p, |
||||||
|
(GATT_PERM_READ), |
||||||
|
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY), |
||||||
|
NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_CHAR_E2P_UUID: /* ESP32 to Phone */ |
||||||
|
blufi_env.handle_char_e2p = p_data->add_result.attr_id; |
||||||
|
|
||||||
|
BTA_GATTS_AddCharDescriptor (blufi_env.handle_srvc, |
||||||
|
(GATT_PERM_READ | GATT_PERM_WRITE), |
||||||
|
&blufi_descr_uuid_e2p, |
||||||
|
NULL, NULL); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
case BTA_GATTS_ADD_CHAR_DESCR_EVT: { |
||||||
|
/* call init finish */ |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
btc_msg_t msg; |
||||||
|
|
||||||
|
blufi_env.handle_descr_e2p = p_data->add_result.attr_id; |
||||||
|
//start the blufi service after created
|
||||||
|
BTA_GATTS_StartService(blufi_env.handle_srvc, BTA_GATT_TRANSPORT_LE); |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_INIT_FINISH; |
||||||
|
param.init_finish.state = ESP_BLUFI_INIT_OK; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTA_GATTS_CONNECT_EVT: { |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
|
||||||
|
//set the connection flag to true
|
||||||
|
BLUFI_TRACE_API("\ndevice is connected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n", |
||||||
|
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if, |
||||||
|
p_data->conn.reason, p_data->conn.conn_id); |
||||||
|
|
||||||
|
memcpy(blufi_env.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
blufi_env.conn_id = p_data->conn.conn_id; |
||||||
|
blufi_env.is_connected = true; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT; |
||||||
|
memcpy(param.connect.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id); |
||||||
|
conn_id = param.connect.conn_id; |
||||||
|
server_if = p_data->conn.server_if; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTA_GATTS_DISCONNECT_EVT: { |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
|
||||||
|
blufi_env.is_connected = false; |
||||||
|
//set the connection flag to true
|
||||||
|
BLUFI_TRACE_API("\ndevice is disconnected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n", |
||||||
|
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if, |
||||||
|
p_data->conn.reason, p_data->conn.conn_id); |
||||||
|
|
||||||
|
memcpy(blufi_env.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
blufi_env.conn_id = p_data->conn.conn_id; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
blufi_env.sec_mode = 0x0; |
||||||
|
blufi_env.offset = 0; |
||||||
|
|
||||||
|
if (blufi_env.aggr_buf != NULL) { |
||||||
|
osi_free(blufi_env.aggr_buf); |
||||||
|
blufi_env.aggr_buf = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT; |
||||||
|
memcpy(param.disconnect.remote_bda, p_data->conn.remote_bda, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTA_GATTS_OPEN_EVT: |
||||||
|
break; |
||||||
|
case BTA_GATTS_CLOSE_EVT: |
||||||
|
break; |
||||||
|
case BTA_GATTS_CONGEST_EVT: |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_send_notify(void *arg) |
||||||
|
{ |
||||||
|
struct pkt_info *pkts = (struct pkt_info *) arg; |
||||||
|
uint16_t conn_id = blufi_env.conn_id; |
||||||
|
uint16_t attr_id = blufi_env.handle_char_e2p; |
||||||
|
bool rsp = false; |
||||||
|
BTA_GATTS_HandleValueIndication(conn_id, attr_id, pkts->pkt_len, |
||||||
|
pkts->pkt, rsp); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_deinit(void) |
||||||
|
{ |
||||||
|
BTA_GATTS_StopService(blufi_env.handle_srvc); |
||||||
|
BTA_GATTS_DeleteService(blufi_env.handle_srvc); |
||||||
|
/* register the BLUFI profile to the BTA_GATTS module*/ |
||||||
|
BTA_GATTS_AppDeregister(blufi_env.gatt_if); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_adv_start(void) |
||||||
|
{ |
||||||
|
esp_ble_gap_set_device_name(BLUFI_DEVICE_NAME); |
||||||
|
esp_ble_gap_config_adv_data(&blufi_adv_data); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_adv_stop(void) |
||||||
|
{ |
||||||
|
esp_ble_gap_stop_advertising(); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_send_encap(void *arg) |
||||||
|
{ |
||||||
|
struct blufi_hdr *hdr = (struct blufi_hdr *)arg; |
||||||
|
retry: |
||||||
|
if (blufi_env.is_connected == false) { |
||||||
|
BTC_TRACE_WARNING("%s ble connection is broken\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (esp_ble_get_cur_sendable_packets_num(BTC_GATT_GET_CONN_ID(blufi_env.conn_id)) > 0) { |
||||||
|
btc_blufi_send_notify((uint8_t *)hdr, |
||||||
|
((hdr->fc & BLUFI_FC_CHECK) ? |
||||||
|
hdr->data_len + sizeof(struct blufi_hdr) + 2 : |
||||||
|
hdr->data_len + sizeof(struct blufi_hdr))); |
||||||
|
} else { |
||||||
|
BTC_TRACE_WARNING("%s wait to send blufi custom data\n", __func__); |
||||||
|
vTaskDelay(pdMS_TO_TICKS(10)); |
||||||
|
goto retry; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id) |
||||||
|
{ |
||||||
|
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); |
||||||
|
btc_msg_t msg; |
||||||
|
btc_ble_gatts_args_t arg; |
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_GATTS; |
||||||
|
msg.act = BTC_GATTS_ACT_CLOSE; |
||||||
|
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id); |
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL, NULL) |
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_disconnect() |
||||||
|
{ |
||||||
|
int rc; |
||||||
|
rc = esp_blufi_close(server_if, conn_id); |
||||||
|
assert (rc == 0); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,901 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <stdio.h> |
||||||
|
|
||||||
|
|
||||||
|
#include "osi/allocator.h" |
||||||
|
|
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc/btc_manage.h" |
||||||
|
|
||||||
|
#include "blufi_int.h" |
||||||
|
|
||||||
|
#include "esp_log.h" |
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#include "esp_blufi.h" |
||||||
|
|
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
|
||||||
|
#if GATT_DYNAMIC_MEMORY == FALSE |
||||||
|
tBLUFI_ENV blufi_env; |
||||||
|
#else |
||||||
|
tBLUFI_ENV *blufi_env_ptr; |
||||||
|
#endif |
||||||
|
|
||||||
|
// static functions declare
|
||||||
|
static void btc_blufi_send_ack(uint8_t seq); |
||||||
|
|
||||||
|
inline void btc_blufi_cb_to_app(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param) |
||||||
|
{ |
||||||
|
esp_blufi_event_cb_t btc_blufi_cb = (esp_blufi_event_cb_t)btc_profile_cb_get(BTC_PID_BLUFI); |
||||||
|
if (btc_blufi_cb) { |
||||||
|
btc_blufi_cb(event, param); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static uint8_t btc_blufi_profile_init(void) |
||||||
|
{ |
||||||
|
esp_blufi_callbacks_t *store_p = blufi_env.cbs; |
||||||
|
|
||||||
|
uint8_t rc; |
||||||
|
if (blufi_env.enabled) { |
||||||
|
BLUFI_TRACE_ERROR("BLUFI already initialized"); |
||||||
|
return ESP_BLUFI_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
memset(&blufi_env, 0x0, sizeof(blufi_env)); |
||||||
|
blufi_env.cbs = store_p; /* if set callback prior, restore the point */ |
||||||
|
blufi_env.frag_size = BLUFI_FRAG_DATA_DEFAULT_LEN; |
||||||
|
rc = esp_blufi_init(); |
||||||
|
if(rc != 0 ){ |
||||||
|
return rc; |
||||||
|
} |
||||||
|
|
||||||
|
return ESP_BLUFI_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
static uint8_t btc_blufi_profile_deinit(void) |
||||||
|
{ |
||||||
|
if (!blufi_env.enabled) { |
||||||
|
BTC_TRACE_ERROR("BLUFI already de-initialized"); |
||||||
|
return ESP_BLUFI_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
esp_blufi_deinit(); |
||||||
|
return ESP_BLUFI_SUCCESS; |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_send_notify(uint8_t *pkt, int pkt_len) |
||||||
|
{ |
||||||
|
struct pkt_info pkts; |
||||||
|
pkts.pkt = pkt; |
||||||
|
pkts.pkt_len = pkt_len; |
||||||
|
esp_blufi_send_notify(&pkts); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_report_error(esp_blufi_error_state_t state) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_REPORT_ERROR; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
param.report_error.state = state; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_recv_handler(uint8_t *data, int len) |
||||||
|
{ |
||||||
|
struct blufi_hdr *hdr = (struct blufi_hdr *)data; |
||||||
|
uint16_t checksum, checksum_pkt; |
||||||
|
int ret; |
||||||
|
|
||||||
|
if (hdr->seq != blufi_env.recv_seq) { |
||||||
|
BTC_TRACE_ERROR("%s seq %d is not expect %d\n", __func__, hdr->seq, blufi_env.recv_seq + 1); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_SEQUENCE_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
blufi_env.recv_seq++; |
||||||
|
|
||||||
|
// first step, decrypt
|
||||||
|
if (BLUFI_FC_IS_ENC(hdr->fc) |
||||||
|
&& (blufi_env.cbs && blufi_env.cbs->decrypt_func)) { |
||||||
|
ret = blufi_env.cbs->decrypt_func(hdr->seq, hdr->data, hdr->data_len); |
||||||
|
if (ret != hdr->data_len) { /* enc must be success and enc len must equal to plain len */ |
||||||
|
BTC_TRACE_ERROR("%s decrypt error %d\n", __func__, ret); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_DECRYPT_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// second step, check sum
|
||||||
|
if (BLUFI_FC_IS_CHECK(hdr->fc) |
||||||
|
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) { |
||||||
|
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2); |
||||||
|
checksum_pkt = hdr->data[hdr->data_len] | (((uint16_t) hdr->data[hdr->data_len + 1]) << 8); |
||||||
|
if (checksum != checksum_pkt) { |
||||||
|
BTC_TRACE_ERROR("%s checksum error %04x, pkt %04x\n", __func__, checksum, checksum_pkt); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_CHECKSUM_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (BLUFI_FC_IS_REQ_ACK(hdr->fc)) { |
||||||
|
btc_blufi_send_ack(hdr->seq); |
||||||
|
} |
||||||
|
|
||||||
|
if (BLUFI_FC_IS_FRAG(hdr->fc)) { |
||||||
|
if (blufi_env.offset == 0) { |
||||||
|
/*
|
||||||
|
blufi_env.aggr_buf should be NULL if blufi_env.offset is 0. |
||||||
|
It is possible that the process of sending fragment packet |
||||||
|
has not been completed |
||||||
|
*/ |
||||||
|
if (blufi_env.aggr_buf) { |
||||||
|
BTC_TRACE_ERROR("%s msg error, blufi_env.aggr_buf is not freed\n", __func__); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_MSG_STATE_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
blufi_env.total_len = hdr->data[0] | (((uint16_t) hdr->data[1]) << 8); |
||||||
|
blufi_env.aggr_buf = osi_malloc(blufi_env.total_len); |
||||||
|
if (blufi_env.aggr_buf == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem, len %d\n", __func__, blufi_env.total_len); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (blufi_env.offset + hdr->data_len - 2 <= blufi_env.total_len){ |
||||||
|
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data + 2, hdr->data_len - 2); |
||||||
|
blufi_env.offset += (hdr->data_len - 2); |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
if (blufi_env.offset > 0) { /* if previous pkt is frag */ |
||||||
|
/* blufi_env.aggr_buf should not be NULL */ |
||||||
|
if (blufi_env.aggr_buf == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s buffer is NULL\n", __func__); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
/* payload length should be equal to total_len */ |
||||||
|
if ((blufi_env.offset + hdr->data_len) != blufi_env.total_len) { |
||||||
|
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR); |
||||||
|
return; |
||||||
|
} |
||||||
|
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data, hdr->data_len); |
||||||
|
|
||||||
|
btc_blufi_protocol_handler(hdr->type, blufi_env.aggr_buf, blufi_env.total_len); |
||||||
|
blufi_env.offset = 0; |
||||||
|
osi_free(blufi_env.aggr_buf); |
||||||
|
blufi_env.aggr_buf = NULL; |
||||||
|
} else { |
||||||
|
btc_blufi_protocol_handler(hdr->type, hdr->data, hdr->data_len); |
||||||
|
blufi_env.offset = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len) |
||||||
|
{ |
||||||
|
struct blufi_hdr *hdr = NULL; |
||||||
|
int remain_len = total_data_len; |
||||||
|
uint16_t checksum; |
||||||
|
int ret; |
||||||
|
|
||||||
|
if (blufi_env.is_connected == false) { |
||||||
|
BTC_TRACE_ERROR("blufi connection has been disconnected \n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
while (remain_len > 0) { |
||||||
|
if (remain_len > blufi_env.frag_size) { |
||||||
|
hdr = osi_malloc(sizeof(struct blufi_hdr) + 2 + blufi_env.frag_size + 2); |
||||||
|
if (hdr == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
hdr->fc = 0x0; |
||||||
|
hdr->data_len = blufi_env.frag_size + 2; |
||||||
|
hdr->data[0] = remain_len & 0xff; |
||||||
|
hdr->data[1] = (remain_len >> 8) & 0xff; |
||||||
|
memcpy(hdr->data + 2, &data[total_data_len - remain_len], blufi_env.frag_size); //copy first, easy for check sum
|
||||||
|
hdr->fc |= BLUFI_FC_FRAG; |
||||||
|
} else { |
||||||
|
hdr = osi_malloc(sizeof(struct blufi_hdr) + remain_len + 2); |
||||||
|
if (hdr == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
hdr->fc = 0x0; |
||||||
|
hdr->data_len = remain_len; |
||||||
|
memcpy(hdr->data, &data[total_data_len - remain_len], hdr->data_len); //copy first, easy for check sum
|
||||||
|
} |
||||||
|
|
||||||
|
hdr->type = type; |
||||||
|
hdr->fc |= BLUFI_FC_DIR_E2P; |
||||||
|
hdr->seq = blufi_env.send_seq++; |
||||||
|
|
||||||
|
if (BLUFI_TYPE_IS_CTRL(hdr->type)) { |
||||||
|
if ((blufi_env.sec_mode & BLUFI_CTRL_SEC_MODE_CHECK_MASK) |
||||||
|
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) { |
||||||
|
hdr->fc |= BLUFI_FC_CHECK; |
||||||
|
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2); |
||||||
|
memcpy(&hdr->data[hdr->data_len], &checksum, 2); |
||||||
|
} |
||||||
|
} else if (!BLUFI_TYPE_IS_DATA_NEG(hdr->type) && !BLUFI_TYPE_IS_DATA_ERROR_INFO(hdr->type)) { |
||||||
|
if ((blufi_env.sec_mode & BLUFI_DATA_SEC_MODE_CHECK_MASK) |
||||||
|
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) { |
||||||
|
hdr->fc |= BLUFI_FC_CHECK; |
||||||
|
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2); |
||||||
|
memcpy(&hdr->data[hdr->data_len], &checksum, 2); |
||||||
|
} |
||||||
|
|
||||||
|
if ((blufi_env.sec_mode & BLUFI_DATA_SEC_MODE_ENC_MASK) |
||||||
|
&& (blufi_env.cbs && blufi_env.cbs->encrypt_func)) { |
||||||
|
ret = blufi_env.cbs->encrypt_func(hdr->seq, hdr->data, hdr->data_len); |
||||||
|
if (ret == hdr->data_len) { /* enc must be success and enc len must equal to plain len */ |
||||||
|
hdr->fc |= BLUFI_FC_ENC; |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s encrypt error %d\n", __func__, ret); |
||||||
|
btc_blufi_report_error(ESP_BLUFI_ENCRYPT_ERROR); |
||||||
|
osi_free(hdr); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (hdr->fc & BLUFI_FC_FRAG) { |
||||||
|
remain_len -= (hdr->data_len - 2); |
||||||
|
} else { |
||||||
|
remain_len -= hdr->data_len; |
||||||
|
} |
||||||
|
|
||||||
|
esp_blufi_send_encap(hdr); |
||||||
|
|
||||||
|
osi_free(hdr); |
||||||
|
hdr = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void btc_blufi_wifi_conn_report(uint8_t opmode, uint8_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *info, int info_len) |
||||||
|
{ |
||||||
|
uint8_t type; |
||||||
|
uint8_t *data; |
||||||
|
int data_len; |
||||||
|
uint8_t *p; |
||||||
|
|
||||||
|
data_len = info_len + 3; |
||||||
|
p = data = osi_malloc(data_len); |
||||||
|
if (data == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP); |
||||||
|
*p++ = opmode; |
||||||
|
*p++ = sta_conn_state; |
||||||
|
*p++ = softap_conn_num; |
||||||
|
|
||||||
|
if (info) { |
||||||
|
if (info->sta_bssid_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID; |
||||||
|
*p++ = 6; |
||||||
|
memcpy(p, info->sta_bssid, 6); |
||||||
|
p += 6; |
||||||
|
} |
||||||
|
if (info->sta_ssid) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_SSID; |
||||||
|
*p++ = info->sta_ssid_len; |
||||||
|
memcpy(p, info->sta_ssid, info->sta_ssid_len); |
||||||
|
p += info->sta_ssid_len; |
||||||
|
} |
||||||
|
if (info->sta_passwd) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD; |
||||||
|
*p++ = info->sta_passwd_len; |
||||||
|
memcpy(p, info->sta_passwd, info->sta_passwd_len); |
||||||
|
p += info->sta_passwd_len; |
||||||
|
} |
||||||
|
if (info->softap_ssid) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID; |
||||||
|
*p++ = info->softap_ssid_len; |
||||||
|
memcpy(p, info->softap_ssid, info->softap_ssid_len); |
||||||
|
p += info->softap_ssid_len; |
||||||
|
} |
||||||
|
if (info->softap_passwd) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD; |
||||||
|
*p++ = info->softap_passwd_len; |
||||||
|
memcpy(p, info->softap_passwd, info->softap_passwd_len); |
||||||
|
p += info->softap_passwd_len; |
||||||
|
} |
||||||
|
if (info->softap_authmode_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->softap_authmode; |
||||||
|
} |
||||||
|
if (info->softap_max_conn_num_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->softap_max_conn_num; |
||||||
|
} |
||||||
|
if (info->softap_channel_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->softap_channel; |
||||||
|
} |
||||||
|
if (info->sta_max_conn_retry_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->sta_max_conn_retry; |
||||||
|
} |
||||||
|
if (info->sta_conn_end_reason_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->sta_conn_end_reason; |
||||||
|
} |
||||||
|
if (info->sta_conn_rssi_set) { |
||||||
|
*p++ = BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI; |
||||||
|
*p++ = 1; |
||||||
|
*p++ = info->sta_conn_rssi; |
||||||
|
} |
||||||
|
} |
||||||
|
if (p - data > data_len) { |
||||||
|
BTC_TRACE_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len); |
||||||
|
} |
||||||
|
|
||||||
|
btc_blufi_send_encap(type, data, data_len); |
||||||
|
osi_free(data); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list) |
||||||
|
{ |
||||||
|
uint8_t type; |
||||||
|
uint8_t *data; |
||||||
|
int data_len; |
||||||
|
uint8_t *p; |
||||||
|
// malloc size: (len + RSSI + ssid buffer) * apCount;
|
||||||
|
uint32_t malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount; |
||||||
|
p = data = osi_malloc(malloc_size); |
||||||
|
if (data == NULL) { |
||||||
|
BTC_TRACE_ERROR("malloc error\n"); |
||||||
|
return; |
||||||
|
} |
||||||
|
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST); |
||||||
|
for (int i = 0; i < apCount; ++i) |
||||||
|
{ |
||||||
|
uint32_t len = strlen((const char *)list[i].ssid); |
||||||
|
data_len = (p - data); |
||||||
|
//current_len + ssid + rssi + total_len_value
|
||||||
|
if((data_len + len + 1 + 1) > malloc_size) { |
||||||
|
BTC_TRACE_ERROR("%s len error", __func__); |
||||||
|
osi_free(data); |
||||||
|
return; |
||||||
|
} |
||||||
|
*p++ = len + 1; // length of ssid + rssi
|
||||||
|
*p++ = list[i].rssi; |
||||||
|
memcpy(p, list[i].ssid, len); |
||||||
|
p = p + len; |
||||||
|
} |
||||||
|
data_len = (p - data); |
||||||
|
btc_blufi_send_encap(type, data, data_len); |
||||||
|
osi_free(data); |
||||||
|
} |
||||||
|
|
||||||
|
static void btc_blufi_send_ack(uint8_t seq) |
||||||
|
{ |
||||||
|
uint8_t type; |
||||||
|
uint8_t data; |
||||||
|
|
||||||
|
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_CTRL, BLUFI_TYPE_CTRL_SUBTYPE_ACK); |
||||||
|
data = seq; |
||||||
|
|
||||||
|
btc_blufi_send_encap(type, &data, 1); |
||||||
|
} |
||||||
|
static void btc_blufi_send_error_info(uint8_t state) |
||||||
|
{ |
||||||
|
uint8_t type; |
||||||
|
uint8_t *data; |
||||||
|
int data_len; |
||||||
|
uint8_t *p; |
||||||
|
|
||||||
|
data_len = 1; |
||||||
|
p = data = osi_malloc(data_len); |
||||||
|
if (data == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO); |
||||||
|
*p++ = state; |
||||||
|
if (p - data > data_len) { |
||||||
|
BTC_TRACE_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len); |
||||||
|
} |
||||||
|
|
||||||
|
btc_blufi_send_encap(type, data, data_len); |
||||||
|
osi_free(data); |
||||||
|
} |
||||||
|
|
||||||
|
static void btc_blufi_send_custom_data(uint8_t *value, uint32_t value_len) |
||||||
|
{ |
||||||
|
if(value == NULL || value_len == 0) { |
||||||
|
BTC_TRACE_ERROR("%s value or value len error", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
uint8_t *data = osi_malloc(value_len); |
||||||
|
if (data == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s mem malloc error", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
uint8_t type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA); |
||||||
|
memcpy(data, value, value_len); |
||||||
|
btc_blufi_send_encap(type, data, value_len); |
||||||
|
osi_free(data); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) |
||||||
|
{ |
||||||
|
esp_blufi_cb_param_t *dst = (esp_blufi_cb_param_t *) p_dest; |
||||||
|
esp_blufi_cb_param_t *src = (esp_blufi_cb_param_t *) p_src; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_SSID: |
||||||
|
dst->sta_ssid.ssid = osi_malloc(src->sta_ssid.ssid_len); |
||||||
|
if (dst->sta_ssid.ssid == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->sta_ssid.ssid, src->sta_ssid.ssid, src->sta_ssid.ssid_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_PASSWD: |
||||||
|
dst->sta_passwd.passwd = osi_malloc(src->sta_passwd.passwd_len); |
||||||
|
if (dst->sta_passwd.passwd == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->sta_passwd.passwd, src->sta_passwd.passwd, src->sta_passwd.passwd_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID: |
||||||
|
dst->softap_ssid.ssid = osi_malloc(src->softap_ssid.ssid_len); |
||||||
|
if (dst->softap_ssid.ssid == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->softap_ssid.ssid, src->softap_ssid.ssid, src->softap_ssid.ssid_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD: |
||||||
|
dst->softap_passwd.passwd = osi_malloc(src->softap_passwd.passwd_len); |
||||||
|
if (dst->softap_passwd.passwd == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->softap_passwd.passwd, src->softap_passwd.passwd, src->softap_passwd.passwd_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_USERNAME: |
||||||
|
dst->username.name = osi_malloc(src->username.name_len); |
||||||
|
if (dst->username.name == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->username.name, src->username.name, src->username.name_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CA_CERT: |
||||||
|
dst->ca.cert = osi_malloc(src->ca.cert_len); |
||||||
|
if (dst->ca.cert == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->ca.cert, src->ca.cert, src->ca.cert_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT: |
||||||
|
dst->client_cert.cert = osi_malloc(src->client_cert.cert_len); |
||||||
|
if (dst->client_cert.cert == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->client_cert.cert, src->client_cert.cert, src->client_cert.cert_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_CERT: |
||||||
|
dst->server_cert.cert = osi_malloc(src->server_cert.cert_len); |
||||||
|
if (dst->server_cert.cert == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->server_cert.cert, src->server_cert.cert, src->server_cert.cert_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY: |
||||||
|
dst->client_pkey.pkey = osi_malloc(src->client_pkey.pkey_len); |
||||||
|
if (dst->client_pkey.pkey == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->client_pkey.pkey, src->client_pkey.pkey, src->client_pkey.pkey_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY: |
||||||
|
dst->server_pkey.pkey = osi_malloc(src->server_pkey.pkey_len); |
||||||
|
if (dst->server_pkey.pkey == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
} |
||||||
|
memcpy(dst->server_pkey.pkey, src->server_pkey.pkey, src->server_pkey.pkey_len); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA: |
||||||
|
dst->custom_data.data = osi_malloc(src->custom_data.data_len); |
||||||
|
if (dst->custom_data.data == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); |
||||||
|
break; |
||||||
|
} |
||||||
|
memcpy(dst->custom_data.data, src->custom_data.data, src->custom_data.data_len); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_cb_deep_free(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
esp_blufi_cb_param_t *param = (esp_blufi_cb_param_t *)msg->arg; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_SSID: |
||||||
|
osi_free(param->sta_ssid.ssid); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_PASSWD: |
||||||
|
osi_free(param->sta_passwd.passwd); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID: |
||||||
|
osi_free(param->softap_ssid.ssid); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD: |
||||||
|
osi_free(param->softap_passwd.passwd); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_USERNAME: |
||||||
|
osi_free(param->username.name); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CA_CERT: |
||||||
|
osi_free(param->ca.cert); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT: |
||||||
|
osi_free(param->client_cert.cert); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_CERT: |
||||||
|
osi_free(param->server_cert.cert); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY: |
||||||
|
osi_free(param->client_pkey.pkey); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY: |
||||||
|
osi_free(param->server_pkey.pkey); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA: |
||||||
|
osi_free(param->custom_data.data); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_cb_handler(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
esp_blufi_cb_param_t *param = (esp_blufi_cb_param_t *)msg->arg; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case ESP_BLUFI_EVENT_INIT_FINISH: { |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_INIT_FINISH, param); |
||||||
|
break; |
||||||
|
} |
||||||
|
case ESP_BLUFI_EVENT_DEINIT_FINISH: { |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_DEINIT_FINISH, param); |
||||||
|
break; |
||||||
|
} |
||||||
|
case ESP_BLUFI_EVENT_BLE_CONNECT: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_BLE_CONNECT, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_BLE_DISCONNECT: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_BLE_DISCONNECT, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_SET_WIFI_OPMODE: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_SET_WIFI_OPMODE, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, NULL); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, NULL); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_GET_WIFI_STATUS: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_STATUS, NULL); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_GET_WIFI_LIST: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_LIST, NULL); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, NULL); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_BSSID: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_BSSID, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_SSID: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_SSID, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_STA_PASSWD: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_STA_PASSWD, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_USERNAME: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_USERNAME, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CA_CERT: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CA_CERT, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CLIENT_CERT, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_CERT: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SERVER_CERT, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_REPORT_ERROR: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REPORT_ERROR, param); |
||||||
|
break; |
||||||
|
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA: |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_CUSTOM_DATA, param); |
||||||
|
break; |
||||||
|
default: |
||||||
|
BTC_TRACE_ERROR("%s UNKNOWN %d\n", __func__, msg->act); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
btc_blufi_cb_deep_free(msg); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) |
||||||
|
{ |
||||||
|
btc_blufi_args_t *dst = (btc_blufi_args_t *) p_dest; |
||||||
|
btc_blufi_args_t *src = (btc_blufi_args_t *) p_src; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case BTC_BLUFI_ACT_SEND_CFG_REPORT: { |
||||||
|
esp_blufi_extra_info_t *src_info = src->wifi_conn_report.extra_info; |
||||||
|
dst->wifi_conn_report.extra_info_len = 0; |
||||||
|
dst->wifi_conn_report.extra_info = NULL; |
||||||
|
|
||||||
|
if (src_info == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
dst->wifi_conn_report.extra_info = osi_calloc(sizeof(esp_blufi_extra_info_t)); |
||||||
|
if (dst->wifi_conn_report.extra_info == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (src_info->sta_bssid_set) { |
||||||
|
memcpy(dst->wifi_conn_report.extra_info->sta_bssid, src_info->sta_bssid, 6); |
||||||
|
dst->wifi_conn_report.extra_info->sta_bssid_set = src_info->sta_bssid_set; |
||||||
|
dst->wifi_conn_report.extra_info_len += (6 + 2); |
||||||
|
} |
||||||
|
if (src_info->sta_ssid) { |
||||||
|
dst->wifi_conn_report.extra_info->sta_ssid = osi_malloc(src_info->sta_ssid_len); |
||||||
|
if (dst->wifi_conn_report.extra_info->sta_ssid) { |
||||||
|
memcpy(dst->wifi_conn_report.extra_info->sta_ssid, src_info->sta_ssid, src_info->sta_ssid_len); |
||||||
|
dst->wifi_conn_report.extra_info->sta_ssid_len = src_info->sta_ssid_len; |
||||||
|
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->sta_ssid_len + 2); |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (src_info->sta_passwd) { |
||||||
|
dst->wifi_conn_report.extra_info->sta_passwd = osi_malloc(src_info->sta_passwd_len); |
||||||
|
if (dst->wifi_conn_report.extra_info->sta_passwd) { |
||||||
|
memcpy(dst->wifi_conn_report.extra_info->sta_passwd, src_info->sta_passwd, src_info->sta_passwd_len); |
||||||
|
dst->wifi_conn_report.extra_info->sta_passwd_len = src_info->sta_passwd_len; |
||||||
|
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->sta_passwd_len + 2); |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (src_info->softap_ssid) { |
||||||
|
dst->wifi_conn_report.extra_info->softap_ssid = osi_malloc(src_info->softap_ssid_len); |
||||||
|
if (dst->wifi_conn_report.extra_info->softap_ssid) { |
||||||
|
memcpy(dst->wifi_conn_report.extra_info->softap_ssid, src_info->softap_ssid, src_info->softap_ssid_len); |
||||||
|
dst->wifi_conn_report.extra_info->softap_ssid_len = src_info->softap_ssid_len; |
||||||
|
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->softap_ssid_len + 2); |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (src_info->softap_passwd) { |
||||||
|
dst->wifi_conn_report.extra_info->softap_passwd = osi_malloc(src_info->softap_passwd_len); |
||||||
|
if (dst->wifi_conn_report.extra_info->softap_passwd) { |
||||||
|
memcpy(dst->wifi_conn_report.extra_info->softap_passwd, src_info->softap_passwd, src_info->softap_passwd_len); |
||||||
|
dst->wifi_conn_report.extra_info->softap_passwd_len = src_info->softap_passwd_len; |
||||||
|
dst->wifi_conn_report.extra_info_len += (dst->wifi_conn_report.extra_info->softap_passwd_len + 2); |
||||||
|
} else { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (src_info->softap_authmode_set) { |
||||||
|
dst->wifi_conn_report.extra_info->softap_authmode_set = src_info->softap_authmode_set; |
||||||
|
dst->wifi_conn_report.extra_info->softap_authmode = src_info->softap_authmode; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
if (src_info->softap_max_conn_num_set) { |
||||||
|
dst->wifi_conn_report.extra_info->softap_max_conn_num_set = src_info->softap_max_conn_num_set; |
||||||
|
dst->wifi_conn_report.extra_info->softap_max_conn_num = src_info->softap_max_conn_num; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
if (src_info->softap_channel_set) { |
||||||
|
dst->wifi_conn_report.extra_info->softap_channel_set = src_info->softap_channel_set; |
||||||
|
dst->wifi_conn_report.extra_info->softap_channel = src_info->softap_channel; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
if (src_info->sta_max_conn_retry_set) { |
||||||
|
dst->wifi_conn_report.extra_info->sta_max_conn_retry_set = src_info->sta_max_conn_retry_set; |
||||||
|
dst->wifi_conn_report.extra_info->sta_max_conn_retry = src_info->sta_max_conn_retry; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
if (src_info->sta_conn_end_reason_set) { |
||||||
|
dst->wifi_conn_report.extra_info->sta_conn_end_reason_set = src_info->sta_conn_end_reason_set; |
||||||
|
dst->wifi_conn_report.extra_info->sta_conn_end_reason = src_info->sta_conn_end_reason; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
if (src_info->sta_conn_rssi_set) { |
||||||
|
dst->wifi_conn_report.extra_info->sta_conn_rssi_set = src_info->sta_conn_rssi_set; |
||||||
|
dst->wifi_conn_report.extra_info->sta_conn_rssi = src_info->sta_conn_rssi; |
||||||
|
dst->wifi_conn_report.extra_info_len += (1 + 2); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{ |
||||||
|
esp_blufi_ap_record_t *list = src->wifi_list.list; |
||||||
|
src->wifi_list.list = NULL; |
||||||
|
if (list == NULL || src->wifi_list.apCount <= 0) { |
||||||
|
break; |
||||||
|
} |
||||||
|
dst->wifi_list.list = (esp_blufi_ap_record_t *)osi_malloc(sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount); |
||||||
|
if (dst->wifi_list.list == NULL) { |
||||||
|
BTC_TRACE_ERROR("%s no mem line %d\n", __func__, __LINE__); |
||||||
|
break; |
||||||
|
} |
||||||
|
memcpy(dst->wifi_list.list, list, sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA:{ |
||||||
|
uint8_t *data = src->custom_data.data; |
||||||
|
if(data == NULL) { |
||||||
|
BTC_TRACE_ERROR("custom data is NULL\n"); |
||||||
|
break; |
||||||
|
} |
||||||
|
dst->custom_data.data = osi_malloc(src->custom_data.data_len); |
||||||
|
if(dst->custom_data.data == NULL) { |
||||||
|
BTC_TRACE_ERROR("custom data malloc error\n"); |
||||||
|
break; |
||||||
|
} |
||||||
|
memcpy(dst->custom_data.data, src->custom_data.data, src->custom_data.data_len); |
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_call_deep_free(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
btc_blufi_args_t *arg = (btc_blufi_args_t *)msg->arg; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case BTC_BLUFI_ACT_SEND_CFG_REPORT: { |
||||||
|
esp_blufi_extra_info_t *info = (esp_blufi_extra_info_t *)arg->wifi_conn_report.extra_info; |
||||||
|
|
||||||
|
if (info == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (info->sta_ssid) { |
||||||
|
osi_free(info->sta_ssid); |
||||||
|
} |
||||||
|
if (info->sta_passwd) { |
||||||
|
osi_free(info->sta_passwd); |
||||||
|
} |
||||||
|
if (info->softap_ssid) { |
||||||
|
osi_free(info->softap_ssid); |
||||||
|
} |
||||||
|
if (info->softap_passwd) { |
||||||
|
osi_free(info->softap_passwd); |
||||||
|
} |
||||||
|
osi_free(info); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{ |
||||||
|
esp_blufi_ap_record_t *list = (esp_blufi_ap_record_t *)arg->wifi_list.list; |
||||||
|
if (list){ |
||||||
|
osi_free(list); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA:{ |
||||||
|
uint8_t *data = arg->custom_data.data; |
||||||
|
if(data) { |
||||||
|
osi_free(data); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_call_handler(btc_msg_t *msg) |
||||||
|
{ |
||||||
|
btc_blufi_args_t *arg = (btc_blufi_args_t *)msg->arg; |
||||||
|
|
||||||
|
switch (msg->act) { |
||||||
|
case BTC_BLUFI_ACT_INIT: |
||||||
|
btc_blufi_profile_init(); |
||||||
|
break; |
||||||
|
case BTC_BLUFI_ACT_DEINIT: |
||||||
|
btc_blufi_profile_deinit(); |
||||||
|
break; |
||||||
|
case BTC_BLUFI_ACT_SEND_CFG_REPORT: |
||||||
|
btc_blufi_wifi_conn_report(arg->wifi_conn_report.opmode, |
||||||
|
arg->wifi_conn_report.sta_conn_state, |
||||||
|
arg->wifi_conn_report.softap_conn_num, |
||||||
|
arg->wifi_conn_report.extra_info, |
||||||
|
arg->wifi_conn_report.extra_info_len); |
||||||
|
break; |
||||||
|
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{ |
||||||
|
btc_blufi_send_wifi_list(arg->wifi_list.apCount, arg->wifi_list.list); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BTC_BLUFI_ACT_SEND_ERR_INFO: |
||||||
|
btc_blufi_send_error_info(arg->blufi_err_infor.state); |
||||||
|
break; |
||||||
|
case BTC_BLUFI_ACT_SEND_CUSTOM_DATA: |
||||||
|
btc_blufi_send_custom_data(arg->custom_data.data, arg->custom_data.data_len); |
||||||
|
break; |
||||||
|
default: |
||||||
|
BTC_TRACE_ERROR("%s UNKNOWN %d\n", __func__, msg->act); |
||||||
|
break; |
||||||
|
} |
||||||
|
btc_blufi_call_deep_free(msg); |
||||||
|
} |
||||||
|
|
||||||
|
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks) |
||||||
|
{ |
||||||
|
blufi_env.cbs = callbacks; |
||||||
|
} |
||||||
|
|
||||||
|
uint16_t btc_blufi_get_version(void) |
||||||
|
{ |
||||||
|
return BTC_BLUFI_VERSION; |
||||||
|
} |
||||||
|
|
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
@ -0,0 +1,253 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <stdio.h> |
||||||
|
|
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc/btc_manage.h" |
||||||
|
|
||||||
|
#include "blufi_int.h" |
||||||
|
|
||||||
|
//#include "esp_wifi.h"
|
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
|
||||||
|
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len) |
||||||
|
{ |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
uint8_t *output_data = NULL; |
||||||
|
int output_len = 0; |
||||||
|
bool need_free = false; |
||||||
|
|
||||||
|
switch (BLUFI_GET_TYPE(type)) { |
||||||
|
case BLUFI_TYPE_CTRL: |
||||||
|
switch (BLUFI_GET_SUBTYPE(type)) { |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_ACK: |
||||||
|
/* TODO: check sequence */ |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE: |
||||||
|
blufi_env.sec_mode = data[0]; |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_SET_WIFI_OPMODE; |
||||||
|
param.wifi_mode.op_mode = data[0]; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_GET_WIFI_STATUS; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_DEAUTHENTICATE_STA; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL,NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION: { |
||||||
|
uint8_t type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION); |
||||||
|
uint8_t data[2]; |
||||||
|
|
||||||
|
data[0] = BTC_BLUFI_GREAT_VER; |
||||||
|
data[1] = BTC_BLUFI_SUB_VER; |
||||||
|
btc_blufi_send_encap(type, &data[0], sizeof(data)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE; |
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_GET_WIFI_LIST; |
||||||
|
btc_transfer_context(&msg, NULL, 0, NULL, NULL); |
||||||
|
break; |
||||||
|
default: |
||||||
|
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type); |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA: |
||||||
|
switch (BLUFI_GET_SUBTYPE(type)) { |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_NEG: |
||||||
|
if (blufi_env.cbs && blufi_env.cbs->negotiate_data_handler) { |
||||||
|
blufi_env.cbs->negotiate_data_handler(data, len, &output_data, &output_len, &need_free); |
||||||
|
} |
||||||
|
|
||||||
|
if (output_data && output_len > 0) { |
||||||
|
btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_NEG), |
||||||
|
output_data, output_len); |
||||||
|
} |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_STA_BSSID; |
||||||
|
memcpy(param.sta_bssid.bssid, &data[0], 6); |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_STA_SSID: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_STA_SSID; |
||||||
|
param.sta_ssid.ssid = &data[0]; |
||||||
|
param.sta_ssid.ssid_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_STA_PASSWD; |
||||||
|
param.sta_passwd.passwd = &data[0]; |
||||||
|
param.sta_passwd.passwd_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_SSID; |
||||||
|
param.softap_ssid.ssid = &data[0]; |
||||||
|
param.softap_ssid.ssid_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD; |
||||||
|
param.softap_passwd.passwd = &data[0]; |
||||||
|
param.softap_passwd.passwd_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM; |
||||||
|
param.softap_max_conn_num.max_conn_num = data[0]; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE; |
||||||
|
param.softap_auth_mode.auth_mode = data[0]; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL; |
||||||
|
param.softap_channel.channel = data[0]; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_USERNAME: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_USERNAME; |
||||||
|
param.username.name = &data[0]; |
||||||
|
param.username.name_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_CA: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_CA_CERT; |
||||||
|
param.ca.cert = &data[0]; |
||||||
|
param.ca.cert_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_CLIENT_CERT; |
||||||
|
param.client_cert.cert = &data[0]; |
||||||
|
param.client_cert.cert_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SERVER_CERT; |
||||||
|
param.client_cert.cert = &data[0]; |
||||||
|
param.client_cert.cert_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY; |
||||||
|
param.client_pkey.pkey = &data[0]; |
||||||
|
param.client_pkey.pkey_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY; |
||||||
|
param.client_pkey.pkey = &data[0]; |
||||||
|
param.client_pkey.pkey_len = len; |
||||||
|
|
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
case BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA: |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_RECV_CUSTOM_DATA; |
||||||
|
param.custom_data.data = &data[0]; |
||||||
|
param.custom_data.data_len = len; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), btc_blufi_cb_deep_copy, btc_blufi_cb_deep_free); |
||||||
|
break; |
||||||
|
default: |
||||||
|
BTC_TRACE_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type); |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
@ -0,0 +1,197 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __BLUFI_INT_H__ |
||||||
|
#define __BLUFI_INT_H__ |
||||||
|
|
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
|
||||||
|
#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion
|
||||||
|
#define BTC_BLUFI_SUB_VER 0x03 //Version + Subversion
|
||||||
|
#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion
|
||||||
|
|
||||||
|
typedef UINT8 tGATT_IF; |
||||||
|
/* service engine control block */ |
||||||
|
typedef struct { |
||||||
|
/* Protocol reference */ |
||||||
|
tGATT_IF gatt_if; |
||||||
|
UINT8 srvc_inst; |
||||||
|
UINT16 handle_srvc; |
||||||
|
UINT16 handle_char_p2e; |
||||||
|
UINT16 handle_char_e2p; |
||||||
|
UINT16 handle_descr_e2p; |
||||||
|
UINT16 conn_id; |
||||||
|
BOOLEAN is_connected; |
||||||
|
BD_ADDR remote_bda; |
||||||
|
UINT32 trans_id; |
||||||
|
UINT8 congest; |
||||||
|
UINT16 frag_size; |
||||||
|
#define BLUFI_PREPAIR_BUF_MAX_SIZE 1024 |
||||||
|
uint8_t *prepare_buf; |
||||||
|
int prepare_len; |
||||||
|
/* Control reference */ |
||||||
|
esp_blufi_callbacks_t *cbs; |
||||||
|
BOOLEAN enabled; |
||||||
|
uint8_t send_seq; |
||||||
|
uint8_t recv_seq; |
||||||
|
uint8_t sec_mode; |
||||||
|
uint8_t *aggr_buf; |
||||||
|
uint16_t total_len; |
||||||
|
uint16_t offset; |
||||||
|
} tBLUFI_ENV; |
||||||
|
|
||||||
|
/* BLUFI protocol */ |
||||||
|
struct blufi_hdr{ |
||||||
|
uint8_t type; |
||||||
|
uint8_t fc; |
||||||
|
uint8_t seq; |
||||||
|
uint8_t data_len; |
||||||
|
uint8_t data[0]; |
||||||
|
}; |
||||||
|
typedef struct blufi_hdr blufi_hd_t; |
||||||
|
|
||||||
|
struct blufi_frag_hdr { |
||||||
|
uint8_t type; |
||||||
|
uint8_t fc; |
||||||
|
uint8_t seq; |
||||||
|
uint8_t data_len; |
||||||
|
uint16_t total_len; |
||||||
|
uint8_t content[0]; |
||||||
|
}; |
||||||
|
typedef struct blufi_frag_hdr blufi_frag_hdr_t; |
||||||
|
|
||||||
|
#if GATT_DYNAMIC_MEMORY == FALSE |
||||||
|
extern tBLUFI_ENV blufi_env; |
||||||
|
#else |
||||||
|
extern tBLUFI_ENV *blufi_env_ptr; |
||||||
|
#define blufi_env (*blufi_env_ptr) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define BLUFI_DATA_SEC_MODE_CHECK_MASK 0x01 |
||||||
|
#define BLUFI_DATA_SEC_MODE_ENC_MASK 0x02 |
||||||
|
#define BLUFI_CTRL_SEC_MODE_CHECK_MASK 0x10 |
||||||
|
#define BLUFI_CTRL_SEC_MODE_ENC_MASK 0x20 |
||||||
|
#define BLUFI_MAX_DATA_LEN 255 |
||||||
|
|
||||||
|
// packet type
|
||||||
|
#define BLUFI_TYPE_MASK 0x03 |
||||||
|
#define BLUFI_TYPE_SHIFT 0 |
||||||
|
#define BLUFI_SUBTYPE_MASK 0xFC |
||||||
|
#define BLUFI_SUBTYPE_SHIFT 2 |
||||||
|
|
||||||
|
#define BLUFI_GET_TYPE(type) ((type) & BLUFI_TYPE_MASK) |
||||||
|
#define BLUFI_GET_SUBTYPE(type) (((type) & BLUFI_SUBTYPE_MASK) >>BLUFI_SUBTYPE_SHIFT) |
||||||
|
#define BLUFI_BUILD_TYPE(type, subtype) (((type) & BLUFI_TYPE_MASK) | ((subtype)<<BLUFI_SUBTYPE_SHIFT)) |
||||||
|
|
||||||
|
#define BLUFI_TYPE_CTRL 0x0 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_ACK 0x00 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE 0x01 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE 0x02 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP 0x03 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP 0x04 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS 0x05 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA 0x06 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION 0x07 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE 0x08 |
||||||
|
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST 0x09 |
||||||
|
|
||||||
|
#define BLUFI_TYPE_DATA 0x1 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_NEG 0x00 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID 0x01 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_SSID 0x02 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD 0x03 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID 0x04 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD 0x05 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM 0x06 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE 0x07 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL 0x08 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_USERNAME 0x09 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_CA 0x0a |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT 0x0b |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT 0x0c |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY 0x0d |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY 0x0e |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP 0x0f |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION 0x10 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST 0x11 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO 0x12 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA 0x13 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY 0x14 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON 0x15 |
||||||
|
#define BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI 0x16 |
||||||
|
#define BLUFI_TYPE_IS_CTRL(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_CTRL) |
||||||
|
#define BLUFI_TYPE_IS_DATA(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_DATA) |
||||||
|
|
||||||
|
#define BLUFI_TYPE_IS_CTRL_ACK(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_ACK) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_START_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_START_NEG) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_STOP_NEG(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_STOP_NEG) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_SET_WIFI_OPMODE(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_CONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_DISCONN_WIFI(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_GET_WIFI_STATUS(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_DEAUTHENTICATE_STA(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA) |
||||||
|
#define BLUFI_TYPE_IS_CTRL_GET_VERSION(type) (BLUFI_TYPE_IS_CTRL((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION) |
||||||
|
|
||||||
|
#define BLUFI_TYPE_IS_DATA_NEG(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_NEG) |
||||||
|
#define BLUFI_TYPE_IS_DATA_STA_BSSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID) |
||||||
|
#define BLUFI_TYPE_IS_DATA_STA_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_SSID) |
||||||
|
#define BLUFI_TYPE_IS_DATA_STA_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SOFTAP_SSID(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SOFTAP_PASSWD(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SOFTAP_MAX_CONN_NUM(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SOFTAP_AUTH_MODE(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SOFTAP_CHANNEL(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL) |
||||||
|
#define BLUFI_TYPE_IS_DATA_USERNAME(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_USERNAME) |
||||||
|
#define BLUFI_TYPE_IS_DATA_CA(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CA) |
||||||
|
#define BLUFI_TYPE_IS_DATA_CLEINT_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SERVER_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT) |
||||||
|
#define BLUFI_TYPE_IS_DATA_CLIENT_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY) |
||||||
|
#define BLUFI_TYPE_IS_DATA_SERVER_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY) |
||||||
|
#define BLUFI_TYPE_IS_DATA_ERROR_INFO(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO) |
||||||
|
|
||||||
|
// packet frame control
|
||||||
|
#define BLUFI_FC_ENC_MASK 0x01 |
||||||
|
#define BLUFI_FC_CHECK_MASK 0x02 |
||||||
|
#define BLUFI_FC_DIR_MASK 0x04 |
||||||
|
#define BLUFI_FC_REQ_ACK_MASK 0x08 |
||||||
|
#define BLUFI_FC_FRAG_MASK 0x10 |
||||||
|
|
||||||
|
#define BLUFI_FC_ENC 0x01 |
||||||
|
#define BLUFI_FC_CHECK 0x02 |
||||||
|
#define BLUFI_FC_DIR_P2E 0x00 |
||||||
|
#define BLUFI_FC_DIR_E2P 0x04 |
||||||
|
#define BLUFI_FC_REQ_ACK 0x08 |
||||||
|
#define BLUFI_FC_FRAG 0x10 |
||||||
|
|
||||||
|
#define BLUFI_FC_IS_ENC(fc) ((fc) & BLUFI_FC_ENC_MASK) |
||||||
|
#define BLUFI_FC_IS_CHECK(fc) ((fc) & BLUFI_FC_CHECK_MASK) |
||||||
|
#define BLUFI_FC_IS_DIR_P2E(fc) ((fc) & BLUFI_FC_DIR_P2E_MASK) |
||||||
|
#define BLUFI_FC_IS_DIR_E2P(fc) (!((fc) & BLUFI_DIR_P2E_MASK)) |
||||||
|
#define BLUFI_FC_IS_REQ_ACK(fc) ((fc) & BLUFI_FC_REQ_ACK_MASK) |
||||||
|
#define BLUFI_FC_IS_FRAG(fc) ((fc) & BLUFI_FC_FRAG_MASK) |
||||||
|
|
||||||
|
/* default GATT MTU size over LE link
|
||||||
|
*/ |
||||||
|
#define GATT_DEF_BLE_MTU_SIZE 23 |
||||||
|
/* BLUFI HEADER + TOTAL(REMAIN) LENGTH + CRC + L2CAP RESERVED */ |
||||||
|
#define BLUFI_MTU_RESERVED_SIZE (sizeof(struct blufi_hdr) + 2 + 2 + 3) |
||||||
|
#define BLUFI_FRAG_DATA_DEFAULT_LEN (GATT_DEF_BLE_MTU_SIZE - BLUFI_MTU_RESERVED_SIZE) |
||||||
|
|
||||||
|
//function declare
|
||||||
|
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len); |
||||||
|
|
||||||
|
void btc_blufi_send_encap(uint8_t type, uint8_t *data, int data_len); |
||||||
|
|
||||||
|
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks); |
||||||
|
|
||||||
|
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); |
||||||
|
|
||||||
|
void btc_blufi_cb_deep_free(btc_msg_t *msg); |
||||||
|
|
||||||
|
#endif /* __BLUFI_INT_H__ */ |
||||||
|
#endif ///BLUFI_INCLUDED == TRUE
|
@ -0,0 +1,99 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ESP_BLUFI_H__ |
||||||
|
#define __ESP_BLUFI_H__ |
||||||
|
|
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#include "esp_err.h" |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_NIMBLE_ENABLED |
||||||
|
#include "nimble/ble.h" |
||||||
|
#include "host/ble_gap.h" |
||||||
|
#include "modlog/modlog.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#include "esp_gap_ble_api.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#define BLUFI_APP_UUID 0xFFFF |
||||||
|
#define BLUFI_DEVICE_NAME "BLUFI_DEVICE" |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_NIMBLE_ENABLED |
||||||
|
struct ble_hs_cfg; |
||||||
|
struct ble_gatt_register_ctxt; |
||||||
|
struct gatt_value { |
||||||
|
struct os_mbuf *buf; |
||||||
|
uint16_t val_handle; |
||||||
|
uint8_t type; |
||||||
|
void *ptr; |
||||||
|
}; |
||||||
|
#define SERVER_MAX_VALUES 3 |
||||||
|
#define MAX_VAL_SIZE 512 |
||||||
|
extern struct gatt_value gatt_values[SERVER_MAX_VALUES]; |
||||||
|
/* GATT server callback */ |
||||||
|
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); |
||||||
|
|
||||||
|
/* Initialise gatt server */ |
||||||
|
int esp_blufi_gatt_svr_init(void); |
||||||
|
void esp_blufi_btc_init(void); |
||||||
|
void esp_blufi_btc_deinit(void); |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
/**
|
||||||
|
* @brief Close a connection a remote device. |
||||||
|
* |
||||||
|
* @param[in] gatts_if: GATT server access interface |
||||||
|
* @param[in] conn_id: connection ID to be closed. |
||||||
|
* |
||||||
|
* @return |
||||||
|
* - ESP_OK : success |
||||||
|
* - other : failed |
||||||
|
* |
||||||
|
*/ |
||||||
|
esp_err_t esp_blufi_close(uint8_t gatts_if, uint16_t conn_id); |
||||||
|
void esp_blufi_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Initialise blufi profile */ |
||||||
|
uint8_t esp_blufi_init(void); |
||||||
|
|
||||||
|
/* start advertising */ |
||||||
|
void bleprph_advertise(void); |
||||||
|
|
||||||
|
/* send notifications */ |
||||||
|
void esp_blufi_send_notify(void *arg); |
||||||
|
|
||||||
|
/* Deinitialise blufi */ |
||||||
|
void esp_blufi_deinit(void); |
||||||
|
/* disconnect */ |
||||||
|
void esp_blufi_disconnect(void); |
||||||
|
|
||||||
|
/* Stop advertisement */ |
||||||
|
void esp_blufi_adv_stop(void); |
||||||
|
|
||||||
|
/* Start advertisement */ |
||||||
|
void esp_blufi_adv_start(void); |
||||||
|
|
||||||
|
void esp_blufi_send_encap(void *arg); |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_NIMBLE_ENABLED |
||||||
|
/**
|
||||||
|
* @brief Handle gap event for BluFi. |
||||||
|
* This function can be called inside custom use gap event handler. |
||||||
|
* It provide minimal event management for BluFi purpose. |
||||||
|
* |
||||||
|
* @param[in] event The type of event being signalled. |
||||||
|
* @param[in] arg Application-specified argument. Currently unused |
||||||
|
* @return int 0 in case of success. |
||||||
|
* Other in case of failure. |
||||||
|
*/ |
||||||
|
int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg); |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif/* _ESP_BLUFI_ */ |
@ -0,0 +1,543 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <assert.h> |
||||||
|
|
||||||
|
#include "btc_blufi_prf.h" |
||||||
|
#include "blufi_int.h" |
||||||
|
#include "esp_log.h" |
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#include "esp_err.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "esp_blufi.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "console/console.h" |
||||||
|
|
||||||
|
/*nimBLE Host*/ |
||||||
|
#include "nimble/nimble_port.h" |
||||||
|
#include "nimble/nimble_port_freertos.h" |
||||||
|
#include "host/ble_hs.h" |
||||||
|
#include "host/util/util.h" |
||||||
|
#include "host/ble_uuid.h" |
||||||
|
#include "host/ble_gatt.h" |
||||||
|
|
||||||
|
#include "services/gap/ble_svc_gap.h" |
||||||
|
#include "services/gatt/ble_svc_gatt.h" |
||||||
|
|
||||||
|
#if (BLUFI_INCLUDED == TRUE) |
||||||
|
|
||||||
|
static uint8_t own_addr_type; |
||||||
|
|
||||||
|
struct gatt_value gatt_values[SERVER_MAX_VALUES]; |
||||||
|
const static char *TAG = "BLUFI_EXAMPLE"; |
||||||
|
|
||||||
|
enum { |
||||||
|
GATT_VALUE_TYPE_CHR, |
||||||
|
GATT_VALUE_TYPE_DSC, |
||||||
|
}; |
||||||
|
|
||||||
|
static int gatt_svr_access_cb(uint16_t conn_handle, uint16_t attr_handle, |
||||||
|
struct ble_gatt_access_ctxt *ctxt, |
||||||
|
void *arg); |
||||||
|
|
||||||
|
static const struct ble_gatt_svc_def gatt_svr_svcs[] = { |
||||||
|
{ |
||||||
|
/*** Service: Blufi */ |
||||||
|
.type = BLE_GATT_SVC_TYPE_PRIMARY, |
||||||
|
.uuid = BLE_UUID16_DECLARE(BLUFI_SERVICE_UUID), |
||||||
|
.characteristics = (struct ble_gatt_chr_def[]) |
||||||
|
{ { |
||||||
|
/*** Characteristic: P2E */ |
||||||
|
.uuid = BLE_UUID16_DECLARE(BLUFI_CHAR_P2E_UUID), |
||||||
|
.access_cb = gatt_svr_access_cb, |
||||||
|
.flags = BLE_GATT_CHR_F_WRITE, |
||||||
|
.arg = &gatt_values[0], |
||||||
|
.val_handle = &gatt_values[0].val_handle, |
||||||
|
}, { |
||||||
|
/*** Characteristic: E2P */ |
||||||
|
.uuid = BLE_UUID16_DECLARE(BLUFI_CHAR_E2P_UUID), |
||||||
|
.access_cb = gatt_svr_access_cb, |
||||||
|
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, |
||||||
|
.arg = &gatt_values[1], |
||||||
|
.val_handle = &gatt_values[1].val_handle, |
||||||
|
}, { |
||||||
|
0, /* No more characteristics in this service. */ |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
{ |
||||||
|
0, /* No more services. */ |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
void esp_blufi_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) |
||||||
|
{ |
||||||
|
char buf[BLE_UUID_STR_LEN]; |
||||||
|
switch (ctxt->op) { |
||||||
|
case BLE_GATT_REGISTER_OP_SVC: |
||||||
|
ESP_LOGI(TAG, "registered service %s with handle=%d", |
||||||
|
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), |
||||||
|
ctxt->svc.handle); |
||||||
|
break; |
||||||
|
|
||||||
|
case BLE_GATT_REGISTER_OP_CHR: |
||||||
|
ESP_LOGI(TAG, "registering characteristic %s with " |
||||||
|
"def_handle=%d val_handle=%d\n", |
||||||
|
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), |
||||||
|
ctxt->chr.def_handle, |
||||||
|
ctxt->chr.val_handle); |
||||||
|
break; |
||||||
|
|
||||||
|
case BLE_GATT_REGISTER_OP_DSC: |
||||||
|
ESP_LOGI(TAG, "registering descriptor %s with handle=%d", |
||||||
|
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), |
||||||
|
ctxt->dsc.handle); |
||||||
|
break; |
||||||
|
|
||||||
|
default: |
||||||
|
assert(0); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static size_t write_value(uint16_t conn_handle, uint16_t attr_handle, |
||||||
|
struct ble_gatt_access_ctxt *ctxt, |
||||||
|
void *arg) |
||||||
|
{ |
||||||
|
struct gatt_value *value = (struct gatt_value *)arg; |
||||||
|
uint16_t len; |
||||||
|
int rc; |
||||||
|
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { |
||||||
|
if (ctxt->chr->flags & BLE_GATT_CHR_F_WRITE_AUTHOR) { |
||||||
|
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (ctxt->dsc->att_flags & BLE_ATT_F_WRITE_AUTHOR) { |
||||||
|
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len); |
||||||
|
rc = ble_hs_mbuf_to_flat(ctxt->om, value->buf->om_data, |
||||||
|
value->buf->om_len, &len); |
||||||
|
if (rc != 0) { |
||||||
|
return BLE_ATT_ERR_UNLIKELY; |
||||||
|
} |
||||||
|
/* Maximum attribute value size is 512 bytes */ |
||||||
|
assert(value->buf->om_len < MAX_VAL_SIZE); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static size_t read_value(uint16_t conn_handle, uint16_t attr_handle, |
||||||
|
struct ble_gatt_access_ctxt *ctxt, |
||||||
|
void *arg) |
||||||
|
{ |
||||||
|
const struct gatt_value *value = (const struct gatt_value *) arg; |
||||||
|
char str[BLE_UUID_STR_LEN]; |
||||||
|
int rc; |
||||||
|
|
||||||
|
memset(str, '\0', sizeof(str)); |
||||||
|
|
||||||
|
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { |
||||||
|
if (ctxt->chr->flags & BLE_GATT_CHR_F_READ_AUTHOR) { |
||||||
|
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; |
||||||
|
} |
||||||
|
|
||||||
|
ble_uuid_to_str(ctxt->chr->uuid, str); |
||||||
|
} else { |
||||||
|
if (ctxt->dsc->att_flags & BLE_ATT_F_READ_AUTHOR) { |
||||||
|
return BLE_ATT_ERR_INSUFFICIENT_AUTHOR; |
||||||
|
} |
||||||
|
|
||||||
|
ble_uuid_to_str(ctxt->dsc->uuid, str); |
||||||
|
} |
||||||
|
|
||||||
|
rc = os_mbuf_append(ctxt->om, value->buf->om_data, value->buf->om_len); |
||||||
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; |
||||||
|
} |
||||||
|
|
||||||
|
static int gatt_svr_access_cb(uint16_t conn_handle, uint16_t attr_handle, |
||||||
|
struct ble_gatt_access_ctxt *ctxt, |
||||||
|
void *arg) |
||||||
|
{ |
||||||
|
switch (ctxt->op) { |
||||||
|
case BLE_GATT_ACCESS_OP_READ_CHR: |
||||||
|
return read_value(conn_handle, attr_handle, |
||||||
|
ctxt, arg); |
||||||
|
case BLE_GATT_ACCESS_OP_WRITE_CHR: |
||||||
|
return write_value(conn_handle, attr_handle, |
||||||
|
ctxt, arg); |
||||||
|
default: |
||||||
|
assert(0); |
||||||
|
return BLE_ATT_ERR_UNLIKELY; |
||||||
|
} |
||||||
|
|
||||||
|
/* Unknown characteristic; the nimble stack should not have called this
|
||||||
|
* function. |
||||||
|
*/ |
||||||
|
assert(0); |
||||||
|
return BLE_ATT_ERR_UNLIKELY; |
||||||
|
} |
||||||
|
|
||||||
|
static void init_gatt_values(void) |
||||||
|
{ |
||||||
|
int i = 0; |
||||||
|
const struct ble_gatt_svc_def *svc; |
||||||
|
const struct ble_gatt_chr_def *chr; |
||||||
|
const struct ble_gatt_dsc_def *dsc; |
||||||
|
|
||||||
|
for (svc = gatt_svr_svcs; svc && svc->uuid; svc++) { |
||||||
|
for (chr = svc->characteristics; chr && chr->uuid; chr++) { |
||||||
|
assert(i < SERVER_MAX_VALUES); |
||||||
|
gatt_values[i].type = GATT_VALUE_TYPE_CHR; |
||||||
|
gatt_values[i].ptr = (void *)chr; |
||||||
|
gatt_values[i].buf = os_msys_get(0, 0); |
||||||
|
os_mbuf_extend(gatt_values[i].buf, 1); |
||||||
|
++i; |
||||||
|
|
||||||
|
for (dsc = chr->descriptors; dsc && dsc->uuid; dsc++) { |
||||||
|
assert(i < SERVER_MAX_VALUES); |
||||||
|
gatt_values[i].type = GATT_VALUE_TYPE_DSC; |
||||||
|
gatt_values[i].ptr = (void *)dsc; |
||||||
|
gatt_values[i].buf = os_msys_get(0, 0); |
||||||
|
os_mbuf_extend(gatt_values[i].buf, 1); |
||||||
|
++i; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
int esp_blufi_gatt_svr_init(void) |
||||||
|
{ |
||||||
|
int rc; |
||||||
|
ble_svc_gap_init(); |
||||||
|
ble_svc_gatt_init(); |
||||||
|
|
||||||
|
rc = ble_gatts_count_cfg(gatt_svr_svcs); |
||||||
|
if (rc != 0) { |
||||||
|
return rc; |
||||||
|
} |
||||||
|
|
||||||
|
rc = ble_gatts_add_svcs(gatt_svr_svcs); |
||||||
|
if (rc != 0) { |
||||||
|
return rc; |
||||||
|
} |
||||||
|
|
||||||
|
init_gatt_values(); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int |
||||||
|
esp_blufi_gap_event(struct ble_gap_event *event, void *arg) |
||||||
|
{ |
||||||
|
struct ble_gap_conn_desc desc; |
||||||
|
int rc; |
||||||
|
|
||||||
|
switch (event->type) { |
||||||
|
case BLE_GAP_EVENT_CONNECT: |
||||||
|
/* A new connection was established or a connection attempt failed. */ |
||||||
|
ESP_LOGI(TAG, "connection %s; status=%d", |
||||||
|
event->connect.status == 0 ? "established" : "failed", |
||||||
|
event->connect.status); |
||||||
|
if (event->connect.status == 0) { |
||||||
|
|
||||||
|
blufi_env.is_connected = true; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT; |
||||||
|
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc); |
||||||
|
assert(rc == 0); |
||||||
|
memcpy(param.connect.remote_bda, desc.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
|
||||||
|
param.connect.conn_id = event->connect.conn_handle; |
||||||
|
/* save connection handle */ |
||||||
|
blufi_env.conn_id = event->connect.conn_handle; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
} |
||||||
|
if (event->connect.status != 0) { |
||||||
|
/* Connection failed; resume advertising. */ |
||||||
|
esp_blufi_adv_start(); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
case BLE_GAP_EVENT_DISCONNECT: |
||||||
|
ESP_LOGI(TAG, "disconnect; reason=%d", event->disconnect.reason); |
||||||
|
memcpy(blufi_env.remote_bda, event->disconnect.conn.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
blufi_env.is_connected = false; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
blufi_env.sec_mode = 0x0; |
||||||
|
blufi_env.offset = 0; |
||||||
|
|
||||||
|
if (blufi_env.aggr_buf != NULL) { |
||||||
|
osi_free(blufi_env.aggr_buf); |
||||||
|
blufi_env.aggr_buf = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT; |
||||||
|
memcpy(param.disconnect.remote_bda, event->disconnect.conn.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
|
||||||
|
return 0; |
||||||
|
case BLE_GAP_EVENT_CONN_UPDATE: |
||||||
|
/* The central has updated the connection parameters. */ |
||||||
|
ESP_LOGI(TAG, "connection updated; status=%d", |
||||||
|
event->conn_update.status); |
||||||
|
return 0; |
||||||
|
|
||||||
|
case BLE_GAP_EVENT_ADV_COMPLETE: |
||||||
|
ESP_LOGI(TAG, "advertise complete; reason=%d", |
||||||
|
event->adv_complete.reason); |
||||||
|
esp_blufi_adv_start(); |
||||||
|
return 0; |
||||||
|
|
||||||
|
case BLE_GAP_EVENT_SUBSCRIBE: |
||||||
|
ESP_LOGI(TAG, "subscribe event; conn_handle=%d attr_handle=%d " |
||||||
|
"reason=%d prevn=%d curn=%d previ=%d curi=%d\n", |
||||||
|
event->subscribe.conn_handle, |
||||||
|
event->subscribe.attr_handle, |
||||||
|
event->subscribe.reason, |
||||||
|
event->subscribe.prev_notify, |
||||||
|
event->subscribe.cur_notify, |
||||||
|
event->subscribe.prev_indicate, |
||||||
|
event->subscribe.cur_indicate); |
||||||
|
return 0; |
||||||
|
|
||||||
|
case BLE_GAP_EVENT_MTU: |
||||||
|
ESP_LOGI(TAG, "mtu update event; conn_handle=%d cid=%d mtu=%d", |
||||||
|
event->mtu.conn_handle, |
||||||
|
event->mtu.channel_id, |
||||||
|
event->mtu.value); |
||||||
|
blufi_env.frag_size = (event->mtu.value < BLUFI_MAX_DATA_LEN ? event->mtu.value : BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE; |
||||||
|
return 0; |
||||||
|
|
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_adv_start(void) |
||||||
|
{ |
||||||
|
int rc; |
||||||
|
|
||||||
|
rc = ble_hs_util_ensure_addr(0); |
||||||
|
assert(rc == 0); |
||||||
|
|
||||||
|
/* Figure out address to use while advertising (no privacy for now) */ |
||||||
|
rc = ble_hs_id_infer_auto(0, &own_addr_type); |
||||||
|
if (rc != 0) { |
||||||
|
ESP_LOGI(TAG, "error determining address type; rc=%d ", rc); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Printing ADDR */ |
||||||
|
uint8_t addr_val[6] = {0}; |
||||||
|
rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); |
||||||
|
|
||||||
|
/* Begin advertising. */ |
||||||
|
struct ble_gap_adv_params adv_params; |
||||||
|
struct ble_hs_adv_fields fields; |
||||||
|
const char *name; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the advertisement data included in our advertisements: |
||||||
|
* o Flags (indicates advertisement type and other general info). |
||||||
|
* o Advertising tx power. |
||||||
|
* o Device name. |
||||||
|
* o 16-bit service UUIDs (alert notifications). |
||||||
|
*/ |
||||||
|
|
||||||
|
memset(&fields, 0, sizeof fields); |
||||||
|
|
||||||
|
/* Advertise two flags:
|
||||||
|
* o Discoverability in forthcoming advertisement (general) |
||||||
|
* o BLE-only (BR/EDR unsupported). |
||||||
|
*/ |
||||||
|
fields.flags = BLE_HS_ADV_F_DISC_GEN | |
||||||
|
BLE_HS_ADV_F_BREDR_UNSUP; |
||||||
|
|
||||||
|
/* Indicate that the TX power level field should be included; have the
|
||||||
|
* stack fill this value automatically. This is done by assigning the |
||||||
|
* special value BLE_HS_ADV_TX_PWR_LVL_AUTO. |
||||||
|
*/ |
||||||
|
fields.tx_pwr_lvl_is_present = 1; |
||||||
|
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; |
||||||
|
|
||||||
|
name = ble_svc_gap_device_name(); |
||||||
|
fields.name = (uint8_t *)name; |
||||||
|
fields.name_len = strlen(name); |
||||||
|
fields.name_is_complete = 1; |
||||||
|
|
||||||
|
fields.uuids16 = (ble_uuid16_t[]) { |
||||||
|
BLE_UUID16_INIT(BLUFI_APP_UUID) |
||||||
|
}; |
||||||
|
fields.num_uuids16 = 1; |
||||||
|
fields.uuids16_is_complete = 1; |
||||||
|
rc = ble_gap_adv_set_fields(&fields); |
||||||
|
if (rc != 0) { |
||||||
|
ESP_LOGE(TAG, "error setting advertisement data; rc=%d", rc); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Begin advertising. */ |
||||||
|
memset(&adv_params, 0, sizeof adv_params); |
||||||
|
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; |
||||||
|
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; |
||||||
|
rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, |
||||||
|
&adv_params, esp_blufi_gap_event, NULL); |
||||||
|
if (rc != 0) { |
||||||
|
ESP_LOGE(TAG, "error enabling advertisement; rc=%d", rc); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t esp_blufi_init(void) |
||||||
|
{ |
||||||
|
blufi_env.enabled = true; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
param.init_finish.state = ESP_BLUFI_INIT_OK; |
||||||
|
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_INIT_FINISH, ¶m); |
||||||
|
return ESP_BLUFI_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_deinit(void) |
||||||
|
{ |
||||||
|
blufi_env.enabled = false; |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_DEINIT_FINISH; |
||||||
|
param.deinit_finish.state = ESP_BLUFI_DEINIT_OK; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_send_notify(void *arg) |
||||||
|
{ |
||||||
|
struct pkt_info *pkts = (struct pkt_info *) arg; |
||||||
|
struct os_mbuf *om; |
||||||
|
om = ble_hs_mbuf_from_flat(pkts->pkt, pkts->pkt_len); |
||||||
|
if (om == NULL) { |
||||||
|
ESP_LOGE(TAG, "Error in allocating memory"); |
||||||
|
return; |
||||||
|
} |
||||||
|
int rc = 0; |
||||||
|
rc = ble_gatts_notify_custom(blufi_env.conn_id, gatt_values[1].val_handle, om); |
||||||
|
if (rc != 0) { |
||||||
|
ESP_LOGE(TAG, "Error in sending notification"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_disconnect(void) |
||||||
|
{ |
||||||
|
ble_gap_terminate(blufi_env.conn_id, BLE_ERR_REM_USER_CONN_TERM); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_adv_stop(void) {} |
||||||
|
|
||||||
|
void esp_blufi_send_encap(void *arg) |
||||||
|
{ |
||||||
|
struct blufi_hdr *hdr = (struct blufi_hdr *)arg; |
||||||
|
if (blufi_env.is_connected == false) { |
||||||
|
BTC_TRACE_WARNING("%s ble connection is broken\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
btc_blufi_send_notify((uint8_t *)hdr, |
||||||
|
((hdr->fc & BLUFI_FC_CHECK) ? |
||||||
|
hdr->data_len + sizeof(struct blufi_hdr) + 2 : |
||||||
|
hdr->data_len + sizeof(struct blufi_hdr))); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_btc_init(void) |
||||||
|
{ |
||||||
|
int rc; |
||||||
|
rc = btc_init(); |
||||||
|
assert(rc == 0); |
||||||
|
} |
||||||
|
|
||||||
|
void esp_blufi_btc_deinit(void) |
||||||
|
{ |
||||||
|
btc_deinit(); |
||||||
|
} |
||||||
|
|
||||||
|
int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg) |
||||||
|
{ |
||||||
|
struct ble_gap_conn_desc desc; |
||||||
|
int rc; |
||||||
|
|
||||||
|
if (event != NULL) { |
||||||
|
switch (event->type) { |
||||||
|
case BLE_GAP_EVENT_CONNECT: |
||||||
|
if (event->connect.status == 0) { |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
|
||||||
|
blufi_env.is_connected = true; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
blufi_env.conn_id = event->connect.conn_handle; |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT; |
||||||
|
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc); |
||||||
|
assert(rc == 0); |
||||||
|
memcpy(param.connect.remote_bda, desc.peer_id_addr.val, ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
|
||||||
|
param.connect.conn_id = event->connect.conn_handle; |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
case BLE_GAP_EVENT_DISCONNECT: { |
||||||
|
btc_msg_t msg; |
||||||
|
esp_blufi_cb_param_t param; |
||||||
|
|
||||||
|
blufi_env.is_connected = false; |
||||||
|
blufi_env.recv_seq = blufi_env.send_seq = 0; |
||||||
|
blufi_env.sec_mode = 0x0; |
||||||
|
blufi_env.offset = 0; |
||||||
|
|
||||||
|
memcpy(blufi_env.remote_bda, |
||||||
|
event->disconnect.conn.peer_id_addr.val, |
||||||
|
ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
|
||||||
|
if (blufi_env.aggr_buf != NULL) { |
||||||
|
osi_free(blufi_env.aggr_buf); |
||||||
|
blufi_env.aggr_buf = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
msg.sig = BTC_SIG_API_CB; |
||||||
|
msg.pid = BTC_PID_BLUFI; |
||||||
|
msg.act = ESP_BLUFI_EVENT_BLE_DISCONNECT; |
||||||
|
memcpy(param.disconnect.remote_bda, |
||||||
|
event->disconnect.conn.peer_id_addr.val, |
||||||
|
ESP_BLUFI_BD_ADDR_LEN); |
||||||
|
btc_transfer_context(&msg, ¶m, sizeof(esp_blufi_cb_param_t), NULL, NULL); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
case BLE_GAP_EVENT_MTU: |
||||||
|
blufi_env.frag_size = (event->mtu.value < BLUFI_MAX_DATA_LEN ? event->mtu.value : |
||||||
|
BLUFI_MAX_DATA_LEN) - BLUFI_MTU_RESERVED_SIZE; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,103 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __BTC_BLUFI_PRF_H__ |
||||||
|
#define __BTC_BLUFI_PRF_H__ |
||||||
|
|
||||||
|
#include "blufi_int.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "esp_blufi_api.h" |
||||||
|
#include "esp_err.h" |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#include "stack/gatt_api.h" |
||||||
|
#define ESP_BLUFI_ERROR GATT_ERROR |
||||||
|
#define ESP_BLUFI_SUCCESS GATT_SUCCESS |
||||||
|
#else |
||||||
|
#define ESP_BLUFI_ERROR 0x85 |
||||||
|
#define ESP_BLUFI_SUCCESS 0x00 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" |
||||||
|
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] |
||||||
|
|
||||||
|
#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */ |
||||||
|
//define the blufi serivce uuid
|
||||||
|
#define BLUFI_SERVICE_UUID 0xFFFF |
||||||
|
//define the blufi Char uuid (PHONE to ESP32)
|
||||||
|
#define BLUFI_CHAR_P2E_UUID 0xFF01 |
||||||
|
//define the blufi Char uuid (ESP32 to PHONE)
|
||||||
|
#define BLUFI_CHAR_E2P_UUID 0xFF02 |
||||||
|
//define the blufi Descriptor uuid (ESP32 to PHONE)
|
||||||
|
#define BLUFI_DESCR_E2P_UUID GATT_UUID_CHAR_CLIENT_CONFIG |
||||||
|
//define the blufi APP ID
|
||||||
|
#define BLUFI_APP_UUID 0xFFFF |
||||||
|
|
||||||
|
#define BLUFI_HDL_NUM 6 |
||||||
|
|
||||||
|
struct pkt_info{ |
||||||
|
uint8_t *pkt; |
||||||
|
int pkt_len; |
||||||
|
}; |
||||||
|
|
||||||
|
static const tBT_UUID blufi_srvc_uuid = {LEN_UUID_16, {BLUFI_SERVICE_UUID}}; |
||||||
|
static const tBT_UUID blufi_char_uuid_p2e = {LEN_UUID_16, {BLUFI_CHAR_P2E_UUID}}; |
||||||
|
static const tBT_UUID blufi_char_uuid_e2p = {LEN_UUID_16, {BLUFI_CHAR_E2P_UUID}}; |
||||||
|
static const tBT_UUID blufi_descr_uuid_e2p = {LEN_UUID_16, {BLUFI_DESCR_E2P_UUID}}; |
||||||
|
static const tBT_UUID blufi_app_uuid = {LEN_UUID_16, {BLUFI_APP_UUID}}; |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
BTC_BLUFI_ACT_INIT = 0, |
||||||
|
BTC_BLUFI_ACT_DEINIT, |
||||||
|
BTC_BLUFI_ACT_SEND_CFG_REPORT, |
||||||
|
BTC_BLUFI_ACT_SEND_WIFI_LIST, |
||||||
|
BTC_BLUFI_ACT_SEND_ERR_INFO, |
||||||
|
BTC_BLUFI_ACT_SEND_CUSTOM_DATA, |
||||||
|
} btc_blufi_act_t; |
||||||
|
|
||||||
|
typedef union { |
||||||
|
struct blufi_cfg_report { |
||||||
|
wifi_mode_t opmode; |
||||||
|
esp_blufi_sta_conn_state_t sta_conn_state; |
||||||
|
uint8_t softap_conn_num; |
||||||
|
esp_blufi_extra_info_t *extra_info; |
||||||
|
int extra_info_len; |
||||||
|
} wifi_conn_report; |
||||||
|
/*
|
||||||
|
BTC_BLUFI_ACT_SEND_WIFI_LIST |
||||||
|
*/ |
||||||
|
struct blufi_wifi_list { |
||||||
|
uint16_t apCount; |
||||||
|
esp_blufi_ap_record_t *list; |
||||||
|
} wifi_list; |
||||||
|
/*
|
||||||
|
BTC_BLUFI_ACT_SEND_ERR_INFO |
||||||
|
*/ |
||||||
|
struct blufi_error_infor { |
||||||
|
esp_blufi_error_state_t state; |
||||||
|
} blufi_err_infor; |
||||||
|
/*
|
||||||
|
BTC_BLUFI_ACT_SEND_CUSTOM_DATA |
||||||
|
*/ |
||||||
|
struct blufi_custom_data { |
||||||
|
uint8_t *data; |
||||||
|
uint32_t data_len; |
||||||
|
} custom_data; |
||||||
|
} btc_blufi_args_t; |
||||||
|
|
||||||
|
void btc_blufi_cb_to_app(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param); |
||||||
|
void btc_blufi_cb_handler(btc_msg_t *msg); |
||||||
|
void btc_blufi_call_handler(btc_msg_t *msg); |
||||||
|
void btc_blufi_set_callbacks(esp_blufi_callbacks_t *callbacks); |
||||||
|
|
||||||
|
void btc_blufi_recv_handler(uint8_t *data, int len); |
||||||
|
void btc_blufi_send_notify(uint8_t *pkt, int pkt_len); |
||||||
|
void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); |
||||||
|
void btc_blufi_call_deep_free(btc_msg_t *msg); |
||||||
|
|
||||||
|
uint16_t btc_blufi_get_version(void); |
||||||
|
|
||||||
|
#endif /* __BTC_BLUFI_PRF_H__ */ |
@ -0,0 +1,215 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _BT_COMMON_H_ |
||||||
|
#define _BT_COMMON_H_ |
||||||
|
|
||||||
|
#include <assert.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include "bt_user_config.h" |
||||||
|
#include "esp_log.h" |
||||||
|
|
||||||
|
#ifndef FALSE |
||||||
|
#define FALSE false |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef TRUE |
||||||
|
#define TRUE true |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#if (UC_BT_BLUFI_ENABLE) |
||||||
|
#define BLUFI_INCLUDED TRUE |
||||||
|
#else |
||||||
|
#define BLUFI_INCLUDED FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_ENABLED |
||||||
|
#include "esp_bt_defs.h" |
||||||
|
#include "esp_bt_main.h" |
||||||
|
#include "esp_gatt_defs.h" |
||||||
|
#define ESP_BLE_HOST_STATUS_ENABLED ESP_BLUEDROID_STATUS_ENABLED |
||||||
|
#define ESP_BLE_HOST_STATUS_CHECK(status) ESP_BLUEDROID_STATUS_CHECK(status) |
||||||
|
#else |
||||||
|
#define ESP_BLE_HOST_STATUS_ENABLED 0 |
||||||
|
#define ESP_BLE_HOST_STATUS_CHECK(status) do {} while (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef BT_QUEUE_CONGEST_SIZE |
||||||
|
#define BT_QUEUE_CONGEST_SIZE 40 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define BTC_INITIAL_TRACE_LEVEL UC_BT_LOG_BTC_TRACE_LEVEL |
||||||
|
#define OSI_INITIAL_TRACE_LEVEL UC_BT_LOG_OSI_TRACE_LEVEL |
||||||
|
#define BLUFI_INITIAL_TRACE_LEVEL UC_BT_LOG_BLUFI_TRACE_LEVEL |
||||||
|
|
||||||
|
#if UC_BT_BLE_DYNAMIC_ENV_MEMORY |
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY TRUE |
||||||
|
#define BTC_DYNAMIC_MEMORY TRUE |
||||||
|
#else |
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE |
||||||
|
#define BTC_DYNAMIC_MEMORY FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#if UC_BT_BLUEDROID_MEM_DEBUG |
||||||
|
#define HEAP_MEMORY_DEBUG TRUE |
||||||
|
#else |
||||||
|
#define HEAP_MEMORY_DEBUG FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef BT_BLE_DYNAMIC_ENV_MEMORY |
||||||
|
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
/* OS Configuration from User config (eg: sdkconfig) */ |
||||||
|
#define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE |
||||||
|
#define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES |
||||||
|
#define BT_BTC_TASK_STACK_SIZE UC_BTC_TASK_STACK_SIZE |
||||||
|
|
||||||
|
/* Define trace levels */ |
||||||
|
#define BT_TRACE_LEVEL_NONE UC_TRACE_LEVEL_NONE /* No trace messages to be generated */ |
||||||
|
#define BT_TRACE_LEVEL_ERROR UC_TRACE_LEVEL_ERROR /* Error condition trace messages */ |
||||||
|
#define BT_TRACE_LEVEL_WARNING UC_TRACE_LEVEL_WARNING /* Warning condition trace messages */ |
||||||
|
#define BT_TRACE_LEVEL_API UC_TRACE_LEVEL_API /* API traces */ |
||||||
|
#define BT_TRACE_LEVEL_EVENT UC_TRACE_LEVEL_EVENT /* Debug messages for events */ |
||||||
|
#define BT_TRACE_LEVEL_DEBUG UC_TRACE_LEVEL_DEBUG /* Full debug messages */ |
||||||
|
#define BT_TRACE_LEVEL_VERBOSE UC_TRACE_LEVEL_VERBOSE /* Verbose debug messages */ |
||||||
|
|
||||||
|
#define MAX_TRACE_LEVEL UC_TRACE_LEVEL_VERBOSE |
||||||
|
|
||||||
|
#ifndef LOG_LOCAL_LEVEL |
||||||
|
#ifndef BOOTLOADER_BUILD |
||||||
|
#define LOG_LOCAL_LEVEL UC_LOG_DEFAULT_LEVEL |
||||||
|
#else |
||||||
|
#define LOG_LOCAL_LEVEL UC_BOOTLOADER_LOG_LEVEL |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
// Mapping between ESP_LOG_LEVEL and BT_TRACE_LEVEL
|
||||||
|
#if (LOG_LOCAL_LEVEL >= 4) |
||||||
|
#define LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL+1) |
||||||
|
#else |
||||||
|
#define LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL |
||||||
|
#endif |
||||||
|
|
||||||
|
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
||||||
|
|
||||||
|
#define BT_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_INITIAL_TRACE_LEVEL, LOG_LOCAL_LEVEL_MAPPING) >= BT_TRACE_LEVEL_##LEVEL) |
||||||
|
|
||||||
|
#define BT_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } |
||||||
|
#define BT_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } |
||||||
|
#define BT_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } |
||||||
|
#define BT_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } |
||||||
|
#define BT_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } |
||||||
|
|
||||||
|
|
||||||
|
#if !UC_BT_STACK_NO_LOG |
||||||
|
/* define traces for BTC */ |
||||||
|
#define BTC_TRACE_ERROR(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTC, ERROR)) BT_PRINT_E("BT_BTC", fmt, ## args);} |
||||||
|
#define BTC_TRACE_WARNING(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTC, WARNING)) BT_PRINT_W("BT_BTC", fmt, ## args);} |
||||||
|
#define BTC_TRACE_API(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTC,API)) BT_PRINT_I("BT_BTC", fmt, ## args);} |
||||||
|
#define BTC_TRACE_EVENT(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTC,EVENT)) BT_PRINT_D("BT_BTC", fmt, ## args);} |
||||||
|
#define BTC_TRACE_DEBUG(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTC,DEBUG)) BT_PRINT_D("BT_BTC", fmt, ## args);} |
||||||
|
#define BTC_TRACE_VERBOSE(fmt, args...) {if (BTC_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BTC,VERBOSE)) BT_PRINT_V("BT_BTC", fmt, ## args);} |
||||||
|
|
||||||
|
/* define traces for OSI */ |
||||||
|
#define OSI_TRACE_ERROR(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(OSI, ERROR)) BT_PRINT_E("BT_OSI", fmt, ## args);} |
||||||
|
#define OSI_TRACE_WARNING(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(OSI, WARNING)) BT_PRINT_W("BT_OSI", fmt, ## args);} |
||||||
|
#define OSI_TRACE_API(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(OSI,API)) BT_PRINT_I("BT_OSI", fmt, ## args);} |
||||||
|
#define OSI_TRACE_EVENT(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(OSI,EVENT)) BT_PRINT_D("BT_OSI", fmt, ## args);} |
||||||
|
#define OSI_TRACE_DEBUG(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(OSI,DEBUG)) BT_PRINT_D("BT_OSI", fmt, ## args);} |
||||||
|
#define OSI_TRACE_VERBOSE(fmt, args...) {if (OSI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(OSI,VERBOSE)) BT_PRINT_V("BT_OSI", fmt, ## args);} |
||||||
|
|
||||||
|
/* define traces for BLUFI */ |
||||||
|
#define BLUFI_TRACE_ERROR(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BLUFI, ERROR)) BT_PRINT_E("BT_BLUFI", fmt, ## args);} |
||||||
|
#define BLUFI_TRACE_WARNING(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BLUFI, WARNING)) BT_PRINT_W("BT_BLUFI", fmt, ## args);} |
||||||
|
#define BLUFI_TRACE_API(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BLUFI,API)) BT_PRINT_I("BT_BLUFI", fmt, ## args);} |
||||||
|
#define BLUFI_TRACE_EVENT(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BLUFI,EVENT)) BT_PRINT_D("BT_BLUFI", fmt, ## args);} |
||||||
|
#define BLUFI_TRACE_DEBUG(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BLUFI,DEBUG)) BT_PRINT_D("BT_BLUFI", fmt, ## args);} |
||||||
|
#define BLUFI_TRACE_VERBOSE(fmt, args...) {if (BLUFI_INITIAL_TRACE_LEVEL >= BT_TRACE_LEVEL_VERBOSE && BT_LOG_LEVEL_CHECK(BLUFI,VERBOSE)) BT_PRINT_V("BT_BLUFI", fmt, ## args);} |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
/* define traces for BTC */ |
||||||
|
#define BTC_TRACE_ERROR(fmt, args...) |
||||||
|
#define BTC_TRACE_WARNING(fmt, args...) |
||||||
|
#define BTC_TRACE_API(fmt, args...) |
||||||
|
#define BTC_TRACE_EVENT(fmt, args...) |
||||||
|
#define BTC_TRACE_DEBUG(fmt, args...) |
||||||
|
#define BTC_TRACE_VERBOSE(fmt, args...) |
||||||
|
|
||||||
|
/* define traces for OSI */ |
||||||
|
#define OSI_TRACE_ERROR(fmt, args...) |
||||||
|
#define OSI_TRACE_WARNING(fmt, args...) |
||||||
|
#define OSI_TRACE_API(fmt, args...) |
||||||
|
#define OSI_TRACE_EVENT(fmt, args...) |
||||||
|
#define OSI_TRACE_DEBUG(fmt, args...) |
||||||
|
#define OSI_TRACE_VERBOSE(fmt, args...) |
||||||
|
|
||||||
|
/* define traces for BLUFI */ |
||||||
|
#define BLUFI_TRACE_ERROR(fmt, args...) |
||||||
|
#define BLUFI_TRACE_WARNING(fmt, args...) |
||||||
|
#define BLUFI_TRACE_API(fmt, args...) |
||||||
|
#define BLUFI_TRACE_EVENT(fmt, args...) |
||||||
|
#define BLUFI_TRACE_DEBUG(fmt, args...) |
||||||
|
#define BLUFI_TRACE_VERBOSE(fmt, args...) |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
/** Bluetooth Error Status */ |
||||||
|
/** We need to build on this */ |
||||||
|
|
||||||
|
/* relate to ESP_BT_STATUS_xxx in esp_bt_defs.h */ |
||||||
|
typedef enum { |
||||||
|
BT_STATUS_SUCCESS = 0, |
||||||
|
BT_STATUS_FAIL, |
||||||
|
BT_STATUS_NOT_READY, |
||||||
|
BT_STATUS_NOMEM, |
||||||
|
BT_STATUS_BUSY, |
||||||
|
BT_STATUS_DONE, /* request already completed */ |
||||||
|
BT_STATUS_UNSUPPORTED, |
||||||
|
BT_STATUS_PARM_INVALID, |
||||||
|
BT_STATUS_UNHANDLED, |
||||||
|
BT_STATUS_AUTH_FAILURE, |
||||||
|
BT_STATUS_RMT_DEV_DOWN, |
||||||
|
BT_STATUS_AUTH_REJECTED, |
||||||
|
BT_STATUS_INVALID_STATIC_RAND_ADDR, |
||||||
|
BT_STATUS_PENDING, |
||||||
|
BT_STATUS_UNACCEPT_CONN_INTERVAL, |
||||||
|
BT_STATUS_PARAM_OUT_OF_RANGE, |
||||||
|
BT_STATUS_TIMEOUT, |
||||||
|
BT_STATUS_MEMORY_FULL, |
||||||
|
BT_STATUS_EIR_TOO_LARGE, |
||||||
|
} bt_status_t; |
||||||
|
|
||||||
|
typedef uint8_t UINT8; |
||||||
|
typedef uint16_t UINT16; |
||||||
|
typedef uint32_t UINT32; |
||||||
|
typedef uint64_t UINT64; |
||||||
|
typedef bool BOOLEAN; |
||||||
|
/* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ |
||||||
|
#define MAX_UUID_SIZE 16 |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
#define LEN_UUID_16 2 |
||||||
|
#define LEN_UUID_32 4 |
||||||
|
#define LEN_UUID_128 16 |
||||||
|
|
||||||
|
UINT16 len; |
||||||
|
|
||||||
|
union { |
||||||
|
UINT16 uuid16; |
||||||
|
UINT32 uuid32; |
||||||
|
UINT8 uuid128[MAX_UUID_SIZE]; |
||||||
|
} uu; |
||||||
|
|
||||||
|
} tBT_UUID; |
||||||
|
|
||||||
|
/* Common Bluetooth field definitions */ |
||||||
|
#define BD_ADDR_LEN 6 /* Device address length */ |
||||||
|
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */ |
||||||
|
|
||||||
|
#endif /* _BT_COMMON_H_ */ |
@ -0,0 +1,101 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __BT_USER_CONFIG_H__ |
||||||
|
#define __BT_USER_CONFIG_H__ |
||||||
|
#include "sdkconfig.h" |
||||||
|
|
||||||
|
#define UC_TRACE_LEVEL_NONE 0 /* No trace messages to be generated */ |
||||||
|
#define UC_TRACE_LEVEL_ERROR 1 /* Error condition trace messages */ |
||||||
|
#define UC_TRACE_LEVEL_WARNING 2 /* Warning condition trace messages */ |
||||||
|
#define UC_TRACE_LEVEL_API 3 /* API traces */ |
||||||
|
#define UC_TRACE_LEVEL_EVENT 4 /* Debug messages for events */ |
||||||
|
#define UC_TRACE_LEVEL_DEBUG 5 /* Full debug messages */ |
||||||
|
#define UC_TRACE_LEVEL_VERBOSE 6 /* Verbose debug messages */ |
||||||
|
|
||||||
|
//DYNAMIC ENV ALLOCATOR
|
||||||
|
#ifdef CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY |
||||||
|
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY |
||||||
|
#else |
||||||
|
#define UC_BT_BLE_DYNAMIC_ENV_MEMORY FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_STACK_NO_LOG |
||||||
|
#define UC_BT_STACK_NO_LOG CONFIG_BT_STACK_NO_LOG |
||||||
|
#else |
||||||
|
#define UC_BT_STACK_NO_LOG FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_CONTROLLER_ENABLED |
||||||
|
#define UC_BT_CONTROLLER_INCLUDED TRUE |
||||||
|
#else |
||||||
|
#define UC_BT_CONTROLLER_INCLUDED FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Thread/Task reference |
||||||
|
**********************************************************/ |
||||||
|
#ifdef CONFIG_BT_BLUEDROID_PINNED_TO_CORE |
||||||
|
#define UC_TASK_PINNED_TO_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY) |
||||||
|
#else |
||||||
|
#define UC_TASK_PINNED_TO_CORE (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_BTC_TASK_STACK_SIZE |
||||||
|
#define UC_BTC_TASK_STACK_SIZE CONFIG_BT_BTC_TASK_STACK_SIZE |
||||||
|
#else |
||||||
|
#define UC_BTC_TASK_STACK_SIZE 4096 |
||||||
|
#endif |
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Trace reference |
||||||
|
**********************************************************/ |
||||||
|
|
||||||
|
#ifdef CONFIG_LOG_DEFAULT_LEVEL |
||||||
|
#define UC_LOG_DEFAULT_LEVEL CONFIG_LOG_DEFAULT_LEVEL |
||||||
|
#else |
||||||
|
#define UC_LOG_DEFAULT_LEVEL 3 |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BOOTLOADER_LOG_LEVEL |
||||||
|
#define UC_BOOTLOADER_LOG_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL |
||||||
|
#else |
||||||
|
#define UC_BOOTLOADER_LOG_LEVEL 3 |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LOG_BTC_TRACE_LEVEL |
||||||
|
#define UC_BT_LOG_BTC_TRACE_LEVEL CONFIG_BT_LOG_BTC_TRACE_LEVEL |
||||||
|
#else |
||||||
|
#define UC_BT_LOG_BTC_TRACE_LEVEL UC_TRACE_LEVEL_WARNING |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LOG_OSI_TRACE_LEVEL |
||||||
|
#define UC_BT_LOG_OSI_TRACE_LEVEL CONFIG_BT_LOG_OSI_TRACE_LEVEL |
||||||
|
#else |
||||||
|
#define UC_BT_LOG_OSI_TRACE_LEVEL UC_TRACE_LEVEL_WARNING |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LOG_BLUFI_TRACE_LEVEL |
||||||
|
#define UC_BT_LOG_BLUFI_TRACE_LEVEL CONFIG_BT_LOG_BLUFI_TRACE_LEVEL |
||||||
|
#else |
||||||
|
#define UC_BT_LOG_BLUFI_TRACE_LEVEL UC_TRACE_LEVEL_WARNING |
||||||
|
#endif |
||||||
|
|
||||||
|
//BLUFI
|
||||||
|
#if defined(CONFIG_BT_BLE_BLUFI_ENABLE) || defined(CONFIG_BT_NIMBLE_BLUFI_ENABLE) |
||||||
|
#define UC_BT_BLUFI_ENABLE TRUE |
||||||
|
#else |
||||||
|
#define UC_BT_BLUFI_ENABLE FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
//MEMORY DEBUG
|
||||||
|
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG |
||||||
|
#define UC_BT_BLUEDROID_MEM_DEBUG TRUE |
||||||
|
#else |
||||||
|
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* __BT_USER_CONFIG_H__ */ |
@ -0,0 +1,331 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include "osi/alarm.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/list.h" |
||||||
|
#include "esp_timer.h" |
||||||
|
#include "btc/btc_task.h" |
||||||
|
#include "btc/btc_alarm.h" |
||||||
|
#include "osi/mutex.h" |
||||||
|
#include "bt_common.h" |
||||||
|
|
||||||
|
typedef struct alarm_t { |
||||||
|
/* timer id point to here */ |
||||||
|
esp_timer_handle_t alarm_hdl; |
||||||
|
osi_alarm_callback_t cb; |
||||||
|
void *cb_data; |
||||||
|
int64_t deadline_us; |
||||||
|
} osi_alarm_t; |
||||||
|
|
||||||
|
enum { |
||||||
|
ALARM_STATE_IDLE, |
||||||
|
ALARM_STATE_OPEN, |
||||||
|
}; |
||||||
|
|
||||||
|
static osi_mutex_t alarm_mutex; |
||||||
|
static int alarm_state; |
||||||
|
|
||||||
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == FALSE) |
||||||
|
static struct alarm_t alarm_cbs[ALARM_CBS_NUM]; |
||||||
|
#else |
||||||
|
static struct alarm_t *alarm_cbs; |
||||||
|
#endif |
||||||
|
|
||||||
|
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm); |
||||||
|
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic); |
||||||
|
|
||||||
|
int osi_alarm_create_mux(void) |
||||||
|
{ |
||||||
|
if (alarm_state != ALARM_STATE_IDLE) { |
||||||
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
osi_mutex_new(&alarm_mutex); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int osi_alarm_delete_mux(void) |
||||||
|
{ |
||||||
|
if (alarm_state != ALARM_STATE_IDLE) { |
||||||
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
osi_mutex_free(&alarm_mutex); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_alarm_init(void) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_IDLE) { |
||||||
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
goto end; |
||||||
|
} |
||||||
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) |
||||||
|
if ((alarm_cbs = (osi_alarm_t *)osi_malloc(sizeof(osi_alarm_t) * ALARM_CBS_NUM)) == NULL) { |
||||||
|
OSI_TRACE_ERROR("%s, malloc failed\n", __func__); |
||||||
|
goto end; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
memset(alarm_cbs, 0x00, sizeof(osi_alarm_t) * ALARM_CBS_NUM); |
||||||
|
alarm_state = ALARM_STATE_OPEN; |
||||||
|
|
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
} |
||||||
|
|
||||||
|
void osi_alarm_deinit(void) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < ALARM_CBS_NUM; i++) { |
||||||
|
if (alarm_cbs[i].alarm_hdl != NULL) { |
||||||
|
alarm_free(&alarm_cbs[i]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) |
||||||
|
osi_free(alarm_cbs); |
||||||
|
alarm_cbs = NULL; |
||||||
|
#endif |
||||||
|
|
||||||
|
alarm_state = ALARM_STATE_IDLE; |
||||||
|
|
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
} |
||||||
|
|
||||||
|
static struct alarm_t *alarm_cbs_lookfor_available(void) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i = 0; i < ALARM_CBS_NUM; i++) { |
||||||
|
if (alarm_cbs[i].alarm_hdl == NULL) { //available
|
||||||
|
OSI_TRACE_DEBUG("%s %d %p\n", __func__, i, &alarm_cbs[i]); |
||||||
|
return &alarm_cbs[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void alarm_cb_handler(struct alarm_t *alarm) |
||||||
|
{ |
||||||
|
OSI_TRACE_DEBUG("TimerID %p\n", alarm); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_WARNING("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
return; |
||||||
|
} |
||||||
|
btc_msg_t msg = {0}; |
||||||
|
btc_alarm_args_t arg; |
||||||
|
msg.sig = BTC_SIG_API_CALL; |
||||||
|
msg.pid = BTC_PID_ALARM; |
||||||
|
arg.cb = alarm->cb; |
||||||
|
arg.cb_data = alarm->cb_data; |
||||||
|
btc_transfer_context(&msg, &arg, sizeof(btc_alarm_args_t), NULL, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
|
||||||
|
struct alarm_t *timer_id = NULL; |
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
timer_id = NULL; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
timer_id = alarm_cbs_lookfor_available(); |
||||||
|
|
||||||
|
if (!timer_id) { |
||||||
|
OSI_TRACE_ERROR("%s alarm_cbs exhausted\n", __func__); |
||||||
|
timer_id = NULL; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
esp_timer_create_args_t tca = {0}; |
||||||
|
tca.callback = (esp_timer_cb_t)alarm_cb_handler; |
||||||
|
tca.arg = timer_id; |
||||||
|
tca.dispatch_method = ESP_TIMER_TASK; |
||||||
|
tca.name = alarm_name; |
||||||
|
|
||||||
|
timer_id->cb = callback; |
||||||
|
timer_id->cb_data = data; |
||||||
|
timer_id->deadline_us = 0; |
||||||
|
|
||||||
|
esp_err_t stat = esp_timer_create(&tca, &timer_id->alarm_hdl); |
||||||
|
if (stat != ESP_OK) { |
||||||
|
OSI_TRACE_ERROR("%s failed to create timer, err 0x%x\n", __func__, stat); |
||||||
|
timer_id = NULL; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
return timer_id; |
||||||
|
} |
||||||
|
|
||||||
|
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm) |
||||||
|
{ |
||||||
|
if (!alarm || alarm->alarm_hdl == NULL) { |
||||||
|
OSI_TRACE_ERROR("%s null\n", __func__); |
||||||
|
return OSI_ALARM_ERR_INVALID_ARG; |
||||||
|
} |
||||||
|
esp_timer_stop(alarm->alarm_hdl); |
||||||
|
esp_err_t stat = esp_timer_delete(alarm->alarm_hdl); |
||||||
|
if (stat != ESP_OK) { |
||||||
|
OSI_TRACE_ERROR("%s failed to delete timer, err 0x%x\n", __func__, stat); |
||||||
|
return OSI_ALARM_ERR_FAIL; |
||||||
|
} |
||||||
|
|
||||||
|
memset(alarm, 0, sizeof(osi_alarm_t)); |
||||||
|
return OSI_ALARM_ERR_PASS; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_alarm_free(osi_alarm_t *alarm) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
goto end; |
||||||
|
} |
||||||
|
alarm_free(alarm); |
||||||
|
|
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
|
||||||
|
osi_alarm_err_t ret = OSI_ALARM_ERR_PASS; |
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
ret = OSI_ALARM_ERR_INVALID_STATE; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
if (!alarm || alarm->alarm_hdl == NULL) { |
||||||
|
OSI_TRACE_ERROR("%s null\n", __func__); |
||||||
|
ret = OSI_ALARM_ERR_INVALID_ARG; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
int64_t timeout_us = 1000 * (int64_t)timeout; |
||||||
|
esp_err_t stat; |
||||||
|
if (is_periodic) { |
||||||
|
stat = esp_timer_start_periodic(alarm->alarm_hdl, (uint64_t)timeout_us); |
||||||
|
} else { |
||||||
|
stat = esp_timer_start_once(alarm->alarm_hdl, (uint64_t)timeout_us); |
||||||
|
} |
||||||
|
if (stat != ESP_OK) { |
||||||
|
OSI_TRACE_ERROR("%s failed to start timer, err 0x%x\n", __func__, stat); |
||||||
|
ret = OSI_ALARM_ERR_FAIL; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
alarm->deadline_us = is_periodic ? 0 : (timeout_us + esp_timer_get_time()); |
||||||
|
|
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout) |
||||||
|
{ |
||||||
|
return alarm_set(alarm, timeout, FALSE); |
||||||
|
} |
||||||
|
|
||||||
|
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period) |
||||||
|
{ |
||||||
|
return alarm_set(alarm, period, TRUE); |
||||||
|
} |
||||||
|
|
||||||
|
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm) |
||||||
|
{ |
||||||
|
int ret = OSI_ALARM_ERR_PASS; |
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (alarm_state != ALARM_STATE_OPEN) { |
||||||
|
OSI_TRACE_ERROR("%s, invalid state %d\n", __func__, alarm_state); |
||||||
|
ret = OSI_ALARM_ERR_INVALID_STATE; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
if (!alarm || alarm->alarm_hdl == NULL) { |
||||||
|
OSI_TRACE_ERROR("%s null\n", __func__); |
||||||
|
ret = OSI_ALARM_ERR_INVALID_ARG; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t stat = esp_timer_stop(alarm->alarm_hdl); |
||||||
|
if (stat != ESP_OK) { |
||||||
|
OSI_TRACE_DEBUG("%s failed to stop timer, err 0x%x\n", __func__, stat); |
||||||
|
ret = OSI_ALARM_ERR_FAIL; |
||||||
|
goto end; |
||||||
|
} |
||||||
|
end: |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm) |
||||||
|
{ |
||||||
|
assert(alarm_mutex != NULL); |
||||||
|
int64_t dt_us = 0; |
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
dt_us = alarm->deadline_us - esp_timer_get_time(); |
||||||
|
osi_mutex_unlock(&alarm_mutex); |
||||||
|
|
||||||
|
return (dt_us > 0) ? (period_ms_t)(dt_us / 1000) : 0; |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t osi_time_get_os_boottime_ms(void) |
||||||
|
{ |
||||||
|
return (uint32_t)(esp_timer_get_time() / 1000); |
||||||
|
} |
||||||
|
|
||||||
|
bool osi_alarm_is_active(osi_alarm_t *alarm) |
||||||
|
{ |
||||||
|
assert(alarm != NULL); |
||||||
|
|
||||||
|
if (alarm->alarm_hdl != NULL) { |
||||||
|
return esp_timer_is_active(alarm->alarm_hdl); |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
@ -0,0 +1,260 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
|
||||||
|
extern void *pvPortZalloc(size_t size); |
||||||
|
extern void vPortFree(void *pv); |
||||||
|
|
||||||
|
|
||||||
|
#if HEAP_MEMORY_DEBUG |
||||||
|
|
||||||
|
#define OSI_MEM_DBG_INFO_MAX 1024*3 |
||||||
|
typedef struct { |
||||||
|
void *p; |
||||||
|
int size; |
||||||
|
const char *func; |
||||||
|
int line; |
||||||
|
} osi_mem_dbg_info_t; |
||||||
|
|
||||||
|
static uint32_t mem_dbg_count = 0; |
||||||
|
static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX]; |
||||||
|
static uint32_t mem_dbg_current_size = 0; |
||||||
|
static uint32_t mem_dbg_max_size = 0; |
||||||
|
|
||||||
|
#define OSI_MEM_DBG_MAX_SECTION_NUM 5 |
||||||
|
typedef struct { |
||||||
|
bool used; |
||||||
|
uint32_t max_size; |
||||||
|
} osi_mem_dbg_max_size_section_t; |
||||||
|
static osi_mem_dbg_max_size_section_t mem_dbg_max_size_section[OSI_MEM_DBG_MAX_SECTION_NUM]; |
||||||
|
|
||||||
|
void osi_mem_dbg_init(void) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) { |
||||||
|
mem_dbg_info[i].p = NULL; |
||||||
|
mem_dbg_info[i].size = 0; |
||||||
|
mem_dbg_info[i].func = NULL; |
||||||
|
mem_dbg_info[i].line = 0; |
||||||
|
} |
||||||
|
mem_dbg_count = 0; |
||||||
|
mem_dbg_current_size = 0; |
||||||
|
mem_dbg_max_size = 0; |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){ |
||||||
|
mem_dbg_max_size_section[i].used = false; |
||||||
|
mem_dbg_max_size_section[i].max_size = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mem_dbg_record(void *p, int size, const char *func, int line) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
if (!p || size == 0) { |
||||||
|
OSI_TRACE_ERROR("%s invalid !!\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) { |
||||||
|
if (mem_dbg_info[i].p == NULL) { |
||||||
|
mem_dbg_info[i].p = p; |
||||||
|
mem_dbg_info[i].size = size; |
||||||
|
mem_dbg_info[i].func = func; |
||||||
|
mem_dbg_info[i].line = line; |
||||||
|
mem_dbg_count++; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (i >= OSI_MEM_DBG_INFO_MAX) { |
||||||
|
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line); |
||||||
|
} |
||||||
|
|
||||||
|
mem_dbg_current_size += size; |
||||||
|
if(mem_dbg_max_size < mem_dbg_current_size) { |
||||||
|
mem_dbg_max_size = mem_dbg_current_size; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_MAX_SECTION_NUM; i++){ |
||||||
|
if (mem_dbg_max_size_section[i].used) { |
||||||
|
if(mem_dbg_max_size_section[i].max_size < mem_dbg_current_size) { |
||||||
|
mem_dbg_max_size_section[i].max_size = mem_dbg_current_size; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mem_dbg_clean(void *p, const char *func, int line) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
if (!p) { |
||||||
|
OSI_TRACE_ERROR("%s invalid\n", __func__); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) { |
||||||
|
if (mem_dbg_info[i].p == p) { |
||||||
|
mem_dbg_current_size -= mem_dbg_info[i].size; |
||||||
|
mem_dbg_info[i].p = NULL; |
||||||
|
mem_dbg_info[i].size = 0; |
||||||
|
mem_dbg_info[i].func = NULL; |
||||||
|
mem_dbg_info[i].line = 0; |
||||||
|
mem_dbg_count--; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (i >= OSI_MEM_DBG_INFO_MAX) { |
||||||
|
OSI_TRACE_ERROR("%s full %s %d !!\n", __func__, func, line); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mem_dbg_show(void) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) { |
||||||
|
if (mem_dbg_info[i].p || mem_dbg_info[i].size != 0 ) { |
||||||
|
OSI_TRACE_ERROR("--> p %p, s %d, f %s, l %d\n", mem_dbg_info[i].p, mem_dbg_info[i].size, mem_dbg_info[i].func, mem_dbg_info[i].line); |
||||||
|
} |
||||||
|
} |
||||||
|
OSI_TRACE_ERROR("--> count %d\n", mem_dbg_count); |
||||||
|
OSI_TRACE_ERROR("--> size %dB\n--> max size %dB\n", mem_dbg_current_size, mem_dbg_max_size); |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_max_size(void) |
||||||
|
{ |
||||||
|
return mem_dbg_max_size; |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_current_size(void) |
||||||
|
{ |
||||||
|
return mem_dbg_current_size; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_men_dbg_set_section_start(uint8_t index) |
||||||
|
{ |
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) { |
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n", |
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (mem_dbg_max_size_section[index].used) { |
||||||
|
OSI_TRACE_WARNING("This index(%d) has been started, restart it.\n", index); |
||||||
|
} |
||||||
|
|
||||||
|
mem_dbg_max_size_section[index].used = true; |
||||||
|
mem_dbg_max_size_section[index].max_size = mem_dbg_current_size; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_men_dbg_set_section_end(uint8_t index) |
||||||
|
{ |
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM) { |
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n", |
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (!mem_dbg_max_size_section[index].used) { |
||||||
|
OSI_TRACE_ERROR("This index(%d) has not been started.\n", index); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
mem_dbg_max_size_section[index].used = false; |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index) |
||||||
|
{ |
||||||
|
if (index >= OSI_MEM_DBG_MAX_SECTION_NUM){ |
||||||
|
OSI_TRACE_ERROR("Then range of index should be between 0 and %d, current index is %d.\n", |
||||||
|
OSI_MEM_DBG_MAX_SECTION_NUM - 1, index); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return mem_dbg_max_size_section[index].max_size; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
char *osi_strdup(const char *str) |
||||||
|
{ |
||||||
|
size_t size = strlen(str) + 1; // + 1 for the null terminator
|
||||||
|
char *new_string = (char *)osi_calloc(size); |
||||||
|
|
||||||
|
if (!new_string) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
memcpy(new_string, str, size); |
||||||
|
return new_string; |
||||||
|
} |
||||||
|
|
||||||
|
void *osi_malloc_func(size_t size) |
||||||
|
{ |
||||||
|
#if HEAP_MEMORY_DEBUG |
||||||
|
void *p; |
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); |
||||||
|
#else |
||||||
|
p = malloc(size); |
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); |
||||||
|
return p; |
||||||
|
#else |
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); |
||||||
|
#else |
||||||
|
return malloc(size); |
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
#endif /* #if HEAP_MEMORY_DEBUG */ |
||||||
|
} |
||||||
|
|
||||||
|
void *osi_calloc_func(size_t size) |
||||||
|
{ |
||||||
|
#if HEAP_MEMORY_DEBUG |
||||||
|
void *p; |
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); |
||||||
|
#else |
||||||
|
p = calloc(1, size); |
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); |
||||||
|
return p; |
||||||
|
#else |
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); |
||||||
|
#else |
||||||
|
return calloc(1, size); |
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
#endif /* #if HEAP_MEMORY_DEBUG */ |
||||||
|
} |
||||||
|
|
||||||
|
void osi_free_func(void *ptr) |
||||||
|
{ |
||||||
|
#if HEAP_MEMORY_DEBUG |
||||||
|
osi_mem_dbg_clean(ptr, __func__, __LINE__); |
||||||
|
#endif |
||||||
|
free(ptr); |
||||||
|
} |
@ -0,0 +1,102 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
#include <stdint.h> |
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/buffer.h" |
||||||
|
|
||||||
|
struct buffer_t { |
||||||
|
buffer_t *root; |
||||||
|
size_t refcount; |
||||||
|
size_t length; |
||||||
|
uint8_t data[]; |
||||||
|
}; |
||||||
|
|
||||||
|
buffer_t *buffer_new(size_t size) |
||||||
|
{ |
||||||
|
assert(size > 0); |
||||||
|
|
||||||
|
buffer_t *buffer = osi_malloc(sizeof(buffer_t) + size); |
||||||
|
if (!buffer) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate buffer of %zu bytes.", __func__, size); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
buffer->root = buffer; |
||||||
|
buffer->refcount = 1; |
||||||
|
buffer->length = size; |
||||||
|
|
||||||
|
return buffer; |
||||||
|
} |
||||||
|
|
||||||
|
buffer_t *buffer_new_ref(const buffer_t *buf) |
||||||
|
{ |
||||||
|
assert(buf != NULL); |
||||||
|
return buffer_new_slice(buf, buf->length); |
||||||
|
} |
||||||
|
|
||||||
|
buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size) |
||||||
|
{ |
||||||
|
assert(buf != NULL); |
||||||
|
assert(slice_size > 0); |
||||||
|
assert(slice_size <= buf->length); |
||||||
|
|
||||||
|
buffer_t *ret = osi_calloc(sizeof(buffer_t)); |
||||||
|
if (!ret) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate new buffer for slice of length %zu.", __func__, slice_size); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
ret->root = buf->root; |
||||||
|
ret->refcount = SIZE_MAX; |
||||||
|
ret->length = slice_size; |
||||||
|
|
||||||
|
++buf->root->refcount; |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void buffer_free(buffer_t *buffer) |
||||||
|
{ |
||||||
|
if (!buffer) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (buffer->root != buffer) { |
||||||
|
// We're a leaf node. Delete the root node if we're the last referent.
|
||||||
|
if (--buffer->root->refcount == 0) { |
||||||
|
osi_free(buffer->root); |
||||||
|
} |
||||||
|
osi_free(buffer); |
||||||
|
} else if (--buffer->refcount == 0) { |
||||||
|
// We're a root node. Roots are only deleted when their refcount goes to 0.
|
||||||
|
osi_free(buffer); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void *buffer_ptr(const buffer_t *buf) |
||||||
|
{ |
||||||
|
assert(buf != NULL); |
||||||
|
return buf->root->data + buf->root->length - buf->length; |
||||||
|
} |
||||||
|
|
||||||
|
size_t buffer_length(const buffer_t *buf) |
||||||
|
{ |
||||||
|
assert(buf != NULL); |
||||||
|
return buf->length; |
||||||
|
} |
@ -0,0 +1,740 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#define LOG_TAG "bt_osi_config" |
||||||
|
#include "esp_system.h" |
||||||
|
#include "nvs_flash.h" |
||||||
|
#include "nvs.h" |
||||||
|
|
||||||
|
#include <ctype.h> |
||||||
|
#include <errno.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/config.h" |
||||||
|
#include "osi/list.h" |
||||||
|
|
||||||
|
#define CONFIG_FILE_MAX_SIZE (1536)//1.5k
|
||||||
|
#define CONFIG_FILE_DEFAULE_LENGTH (2048) |
||||||
|
#define CONFIG_KEY "bt_cfg_key" |
||||||
|
typedef struct { |
||||||
|
char *key; |
||||||
|
char *value; |
||||||
|
} entry_t; |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
char *name; |
||||||
|
list_t *entries; |
||||||
|
} section_t; |
||||||
|
|
||||||
|
struct config_t { |
||||||
|
list_t *sections; |
||||||
|
}; |
||||||
|
|
||||||
|
// Empty definition; this type is aliased to list_node_t.
|
||||||
|
struct config_section_iter_t {}; |
||||||
|
|
||||||
|
static void config_parse(nvs_handle_t fp, config_t *config); |
||||||
|
|
||||||
|
static section_t *section_new(const char *name); |
||||||
|
static void section_free(void *ptr); |
||||||
|
static section_t *section_find(const config_t *config, const char *section); |
||||||
|
|
||||||
|
static entry_t *entry_new(const char *key, const char *value); |
||||||
|
static void entry_free(void *ptr); |
||||||
|
static entry_t *entry_find(const config_t *config, const char *section, const char *key); |
||||||
|
|
||||||
|
config_t *config_new_empty(void) |
||||||
|
{ |
||||||
|
config_t *config = osi_calloc(sizeof(config_t)); |
||||||
|
if (!config) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate memory for config_t.\n", __func__); |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
config->sections = list_new(section_free); |
||||||
|
if (!config->sections) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate list for sections.\n", __func__); |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
return config; |
||||||
|
|
||||||
|
error:; |
||||||
|
config_free(config); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
config_t *config_new(const char *filename) |
||||||
|
{ |
||||||
|
assert(filename != NULL); |
||||||
|
|
||||||
|
config_t *config = config_new_empty(); |
||||||
|
if (!config) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
esp_err_t err; |
||||||
|
nvs_handle_t fp; |
||||||
|
err = nvs_open(filename, NVS_READWRITE, &fp); |
||||||
|
if (err != ESP_OK) { |
||||||
|
if (err == ESP_ERR_NVS_NOT_INITIALIZED) { |
||||||
|
OSI_TRACE_ERROR("%s: NVS not initialized. " |
||||||
|
"Call nvs_flash_init before initializing bluetooth.", __func__); |
||||||
|
} else { |
||||||
|
OSI_TRACE_ERROR("%s unable to open NVS namespace '%s'\n", __func__, filename); |
||||||
|
} |
||||||
|
config_free(config); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
config_parse(fp, config); |
||||||
|
nvs_close(fp); |
||||||
|
return config; |
||||||
|
} |
||||||
|
|
||||||
|
void config_free(config_t *config) |
||||||
|
{ |
||||||
|
if (!config) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
list_free(config->sections); |
||||||
|
osi_free(config); |
||||||
|
} |
||||||
|
|
||||||
|
bool config_has_section(const config_t *config, const char *section) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
|
||||||
|
return (section_find(config, section) != NULL); |
||||||
|
} |
||||||
|
|
||||||
|
bool config_has_key(const config_t *config, const char *section, const char *key) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
return (entry_find(config, section, key) != NULL); |
||||||
|
} |
||||||
|
|
||||||
|
bool config_has_key_in_section(config_t *config, const char *key, char *key_value) |
||||||
|
{ |
||||||
|
OSI_TRACE_DEBUG("key = %s, value = %s", key, key_value); |
||||||
|
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { |
||||||
|
const section_t *section = (const section_t *)list_node(node); |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(section->entries); node != list_end(section->entries); node = list_next(node)) { |
||||||
|
entry_t *entry = list_node(node); |
||||||
|
OSI_TRACE_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value); |
||||||
|
if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) { |
||||||
|
OSI_TRACE_DEBUG("%s, the irk aready in the flash.", __func__); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
int config_get_int(const config_t *config, const char *section, const char *key, int def_value) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
entry_t *entry = entry_find(config, section, key); |
||||||
|
if (!entry) { |
||||||
|
return def_value; |
||||||
|
} |
||||||
|
|
||||||
|
char *endptr; |
||||||
|
int ret = strtol(entry->value, &endptr, 0); |
||||||
|
return (*endptr == '\0') ? ret : def_value; |
||||||
|
} |
||||||
|
|
||||||
|
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
entry_t *entry = entry_find(config, section, key); |
||||||
|
if (!entry) { |
||||||
|
return def_value; |
||||||
|
} |
||||||
|
|
||||||
|
if (!strcmp(entry->value, "true")) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (!strcmp(entry->value, "false")) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return def_value; |
||||||
|
} |
||||||
|
|
||||||
|
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
entry_t *entry = entry_find(config, section, key); |
||||||
|
if (!entry) { |
||||||
|
return def_value; |
||||||
|
} |
||||||
|
|
||||||
|
return entry->value; |
||||||
|
} |
||||||
|
|
||||||
|
void config_set_int(config_t *config, const char *section, const char *key, int value) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
char value_str[32] = { 0 }; |
||||||
|
sprintf(value_str, "%d", value); |
||||||
|
config_set_string(config, section, key, value_str, false); |
||||||
|
} |
||||||
|
|
||||||
|
void config_set_bool(config_t *config, const char *section, const char *key, bool value) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
|
||||||
|
config_set_string(config, section, key, value ? "true" : "false", false); |
||||||
|
} |
||||||
|
|
||||||
|
void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back) |
||||||
|
{ |
||||||
|
section_t *sec = section_find(config, section); |
||||||
|
if (!sec) { |
||||||
|
sec = section_new(section); |
||||||
|
if (insert_back) { |
||||||
|
list_append(config->sections, sec); |
||||||
|
} else { |
||||||
|
list_prepend(config->sections, sec); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) { |
||||||
|
entry_t *entry = list_node(node); |
||||||
|
if (!strcmp(entry->key, key)) { |
||||||
|
osi_free(entry->value); |
||||||
|
entry->value = osi_strdup(value); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
entry_t *entry = entry_new(key, value); |
||||||
|
list_append(sec->entries, entry); |
||||||
|
} |
||||||
|
|
||||||
|
bool config_remove_section(config_t *config, const char *section) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
|
||||||
|
section_t *sec = section_find(config, section); |
||||||
|
if (!sec) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return list_remove(config->sections, sec); |
||||||
|
} |
||||||
|
|
||||||
|
bool config_update_newest_section(config_t *config, const char *section) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
|
||||||
|
list_node_t *first_node = list_begin(config->sections); |
||||||
|
if (first_node == NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
section_t *first_sec = list_node(first_node); |
||||||
|
if (strcmp(first_sec->name, section) == 0) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { |
||||||
|
section_t *sec = list_node(node); |
||||||
|
if (strcmp(sec->name, section) == 0) { |
||||||
|
list_delete(config->sections, sec); |
||||||
|
list_prepend(config->sections, sec); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
bool config_remove_key(config_t *config, const char *section, const char *key) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(section != NULL); |
||||||
|
assert(key != NULL); |
||||||
|
bool ret; |
||||||
|
|
||||||
|
section_t *sec = section_find(config, section); |
||||||
|
entry_t *entry = entry_find(config, section, key); |
||||||
|
if (!sec || !entry) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
ret = list_remove(sec->entries, entry); |
||||||
|
if (list_length(sec->entries) == 0) { |
||||||
|
OSI_TRACE_DEBUG("%s remove section name:%s",__func__, section); |
||||||
|
ret &= config_remove_section(config, section); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
const config_section_node_t *config_section_begin(const config_t *config) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
return (const config_section_node_t *)list_begin(config->sections); |
||||||
|
} |
||||||
|
|
||||||
|
const config_section_node_t *config_section_end(const config_t *config) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
return (const config_section_node_t *)list_end(config->sections); |
||||||
|
} |
||||||
|
|
||||||
|
const config_section_node_t *config_section_next(const config_section_node_t *node) |
||||||
|
{ |
||||||
|
assert(node != NULL); |
||||||
|
return (const config_section_node_t *)list_next((const list_node_t *)node); |
||||||
|
} |
||||||
|
|
||||||
|
const char *config_section_name(const config_section_node_t *node) |
||||||
|
{ |
||||||
|
assert(node != NULL); |
||||||
|
const list_node_t *lnode = (const list_node_t *)node; |
||||||
|
const section_t *section = (const section_t *)list_node(lnode); |
||||||
|
return section->name; |
||||||
|
} |
||||||
|
|
||||||
|
static int get_config_size(const config_t *config) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
|
||||||
|
int w_len = 0, total_size = 0; |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { |
||||||
|
const section_t *section = (const section_t *)list_node(node); |
||||||
|
w_len = strlen(section->name) + strlen("[]\n");// format "[section->name]\n"
|
||||||
|
total_size += w_len; |
||||||
|
|
||||||
|
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { |
||||||
|
const entry_t *entry = (const entry_t *)list_node(enode); |
||||||
|
w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n");// format "entry->key = entry->value\n"
|
||||||
|
total_size += w_len; |
||||||
|
} |
||||||
|
|
||||||
|
// Only add a separating newline if there are more sections.
|
||||||
|
if (list_next(node) != list_end(config->sections)) { |
||||||
|
total_size ++; //'\n'
|
||||||
|
} else { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
total_size ++; //'\0'
|
||||||
|
return total_size; |
||||||
|
} |
||||||
|
|
||||||
|
static int get_config_size_from_flash(nvs_handle_t fp) |
||||||
|
{ |
||||||
|
assert(fp != 0); |
||||||
|
|
||||||
|
esp_err_t err; |
||||||
|
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||||
|
char *keyname = osi_calloc(keyname_bufsz); |
||||||
|
if (!keyname){ |
||||||
|
OSI_TRACE_ERROR("%s, malloc error\n", __func__); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
size_t length = CONFIG_FILE_DEFAULE_LENGTH; |
||||||
|
size_t total_length = 0; |
||||||
|
uint16_t i = 0; |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0); |
||||||
|
err = nvs_get_blob(fp, keyname, NULL, &length); |
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) { |
||||||
|
osi_free(keyname); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
if (err != ESP_OK) { |
||||||
|
OSI_TRACE_ERROR("%s, error %d\n", __func__, err); |
||||||
|
osi_free(keyname); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
total_length += length; |
||||||
|
while (length == CONFIG_FILE_MAX_SIZE) { |
||||||
|
length = CONFIG_FILE_DEFAULE_LENGTH; |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, ++i); |
||||||
|
err = nvs_get_blob(fp, keyname, NULL, &length); |
||||||
|
|
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (err != ESP_OK) { |
||||||
|
OSI_TRACE_ERROR("%s, error %d\n", __func__, err); |
||||||
|
osi_free(keyname); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
total_length += length; |
||||||
|
} |
||||||
|
osi_free(keyname); |
||||||
|
return total_length; |
||||||
|
} |
||||||
|
|
||||||
|
bool config_save(const config_t *config, const char *filename) |
||||||
|
{ |
||||||
|
assert(config != NULL); |
||||||
|
assert(filename != NULL); |
||||||
|
assert(*filename != '\0'); |
||||||
|
|
||||||
|
esp_err_t err; |
||||||
|
int err_code = 0; |
||||||
|
nvs_handle_t fp; |
||||||
|
char *line = osi_calloc(1024); |
||||||
|
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||||
|
char *keyname = osi_calloc(keyname_bufsz); |
||||||
|
int config_size = get_config_size(config); |
||||||
|
char *buf = osi_calloc(config_size); |
||||||
|
if (!line || !buf || !keyname) { |
||||||
|
err_code |= 0x01; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
err = nvs_open(filename, NVS_READWRITE, &fp); |
||||||
|
if (err != ESP_OK) { |
||||||
|
if (err == ESP_ERR_NVS_NOT_INITIALIZED) { |
||||||
|
OSI_TRACE_ERROR("%s: NVS not initialized. " |
||||||
|
"Call nvs_flash_init before initializing bluetooth.", __func__); |
||||||
|
} |
||||||
|
err_code |= 0x02; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
int w_cnt, w_cnt_total = 0; |
||||||
|
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { |
||||||
|
const section_t *section = (const section_t *)list_node(node); |
||||||
|
w_cnt = snprintf(line, 1024, "[%s]\n", section->name); |
||||||
|
if(w_cnt < 0) { |
||||||
|
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt); |
||||||
|
err_code |= 0x10; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
if(w_cnt_total + w_cnt > config_size) { |
||||||
|
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size (config_size = %d).", __func__, (w_cnt + w_cnt_total), config_size); |
||||||
|
err_code |= 0x20; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
OSI_TRACE_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total); |
||||||
|
memcpy(buf + w_cnt_total, line, w_cnt); |
||||||
|
w_cnt_total += w_cnt; |
||||||
|
|
||||||
|
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) { |
||||||
|
const entry_t *entry = (const entry_t *)list_node(enode); |
||||||
|
OSI_TRACE_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value); |
||||||
|
w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value); |
||||||
|
if(w_cnt < 0) { |
||||||
|
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt); |
||||||
|
err_code |= 0x10; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
if(w_cnt_total + w_cnt > config_size) { |
||||||
|
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size.(config_size = %d)", __func__, (w_cnt + w_cnt_total), config_size); |
||||||
|
err_code |= 0x20; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
OSI_TRACE_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total); |
||||||
|
memcpy(buf + w_cnt_total, line, w_cnt); |
||||||
|
w_cnt_total += w_cnt; |
||||||
|
} |
||||||
|
|
||||||
|
// Only add a separating newline if there are more sections.
|
||||||
|
if (list_next(node) != list_end(config->sections)) { |
||||||
|
buf[w_cnt_total] = '\n'; |
||||||
|
w_cnt_total += 1; |
||||||
|
} else { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
buf[w_cnt_total] = '\0'; |
||||||
|
if (w_cnt_total < CONFIG_FILE_MAX_SIZE) { |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0); |
||||||
|
err = nvs_set_blob(fp, keyname, buf, w_cnt_total); |
||||||
|
if (err != ESP_OK) { |
||||||
|
nvs_close(fp); |
||||||
|
err_code |= 0x04; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
}else { |
||||||
|
int count = (w_cnt_total / CONFIG_FILE_MAX_SIZE); |
||||||
|
assert(count <= 0xFF); |
||||||
|
for (uint8_t i = 0; i <= count; i++) |
||||||
|
{ |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, i); |
||||||
|
if (i == count) { |
||||||
|
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); |
||||||
|
OSI_TRACE_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, w_cnt_total - i*CONFIG_FILE_MAX_SIZE); |
||||||
|
}else { |
||||||
|
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, CONFIG_FILE_MAX_SIZE); |
||||||
|
OSI_TRACE_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE); |
||||||
|
} |
||||||
|
if (err != ESP_OK) { |
||||||
|
nvs_close(fp); |
||||||
|
err_code |= 0x04; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
err = nvs_commit(fp); |
||||||
|
if (err != ESP_OK) { |
||||||
|
nvs_close(fp); |
||||||
|
err_code |= 0x08; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
nvs_close(fp); |
||||||
|
osi_free(line); |
||||||
|
osi_free(buf); |
||||||
|
osi_free(keyname); |
||||||
|
return true; |
||||||
|
|
||||||
|
error: |
||||||
|
if (buf) { |
||||||
|
osi_free(buf); |
||||||
|
} |
||||||
|
if (line) { |
||||||
|
osi_free(line); |
||||||
|
} |
||||||
|
if (keyname) { |
||||||
|
osi_free(keyname); |
||||||
|
} |
||||||
|
if (err_code) { |
||||||
|
OSI_TRACE_ERROR("%s, err_code: 0x%x\n", __func__, err_code); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
static char *trim(char *str) |
||||||
|
{ |
||||||
|
while (isspace((unsigned char)(*str))) { |
||||||
|
++str; |
||||||
|
} |
||||||
|
|
||||||
|
if (!*str) { |
||||||
|
return str; |
||||||
|
} |
||||||
|
|
||||||
|
char *end_str = str + strlen(str) - 1; |
||||||
|
while (end_str > str && isspace((unsigned char)(*end_str))) { |
||||||
|
--end_str; |
||||||
|
} |
||||||
|
|
||||||
|
end_str[1] = '\0'; |
||||||
|
return str; |
||||||
|
} |
||||||
|
|
||||||
|
static void config_parse(nvs_handle_t fp, config_t *config) |
||||||
|
{ |
||||||
|
assert(fp != 0); |
||||||
|
assert(config != NULL); |
||||||
|
|
||||||
|
esp_err_t err; |
||||||
|
int line_num = 0; |
||||||
|
int err_code = 0; |
||||||
|
uint16_t i = 0; |
||||||
|
size_t length = CONFIG_FILE_DEFAULE_LENGTH; |
||||||
|
size_t total_length = 0; |
||||||
|
char *line = osi_calloc(1024); |
||||||
|
char *section = osi_calloc(1024); |
||||||
|
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||||
|
char *keyname = osi_calloc(keyname_bufsz); |
||||||
|
int buf_size = get_config_size_from_flash(fp); |
||||||
|
char *buf = NULL; |
||||||
|
|
||||||
|
if(buf_size == 0) { //First use nvs
|
||||||
|
goto error; |
||||||
|
} |
||||||
|
buf = osi_calloc(buf_size); |
||||||
|
if (!line || !section || !buf || !keyname) { |
||||||
|
err_code |= 0x01; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0); |
||||||
|
err = nvs_get_blob(fp, keyname, buf, &length); |
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
if (err != ESP_OK) { |
||||||
|
err_code |= 0x02; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
total_length += length; |
||||||
|
while (length == CONFIG_FILE_MAX_SIZE) { |
||||||
|
length = CONFIG_FILE_DEFAULE_LENGTH; |
||||||
|
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, ++i); |
||||||
|
err = nvs_get_blob(fp, keyname, buf + CONFIG_FILE_MAX_SIZE * i, &length); |
||||||
|
|
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) { |
||||||
|
break; |
||||||
|
} |
||||||
|
if (err != ESP_OK) { |
||||||
|
err_code |= 0x02; |
||||||
|
goto error; |
||||||
|
} |
||||||
|
total_length += length; |
||||||
|
} |
||||||
|
char *p_line_end; |
||||||
|
char *p_line_bgn = buf; |
||||||
|
strcpy(section, CONFIG_DEFAULT_SECTION); |
||||||
|
|
||||||
|
while ( (p_line_bgn < buf + total_length - 1) && (p_line_end = strchr(p_line_bgn, '\n'))) { |
||||||
|
|
||||||
|
// get one line
|
||||||
|
int line_len = p_line_end - p_line_bgn; |
||||||
|
if (line_len > 1023) { |
||||||
|
OSI_TRACE_WARNING("%s exceed max line length on line %d.\n", __func__, line_num); |
||||||
|
break; |
||||||
|
} |
||||||
|
memcpy(line, p_line_bgn, line_len); |
||||||
|
line[line_len] = '\0'; |
||||||
|
p_line_bgn = p_line_end + 1; |
||||||
|
char *line_ptr = trim(line); |
||||||
|
++line_num; |
||||||
|
|
||||||
|
// Skip blank and comment lines.
|
||||||
|
if (*line_ptr == '\0' || *line_ptr == '#') { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (*line_ptr == '[') { |
||||||
|
size_t len = strlen(line_ptr); |
||||||
|
if (line_ptr[len - 1] != ']') { |
||||||
|
OSI_TRACE_WARNING("%s unterminated section name on line %d.\n", __func__, line_num); |
||||||
|
continue; |
||||||
|
} |
||||||
|
strncpy(section, line_ptr + 1, len - 2); |
||||||
|
section[len - 2] = '\0'; |
||||||
|
} else { |
||||||
|
char *split = strchr(line_ptr, '='); |
||||||
|
if (!split) { |
||||||
|
OSI_TRACE_DEBUG("%s no key/value separator found on line %d.\n", __func__, line_num); |
||||||
|
continue; |
||||||
|
} |
||||||
|
*split = '\0'; |
||||||
|
config_set_string(config, section, trim(line_ptr), trim(split + 1), true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
error: |
||||||
|
if (buf) { |
||||||
|
osi_free(buf); |
||||||
|
} |
||||||
|
if (line) { |
||||||
|
osi_free(line); |
||||||
|
} |
||||||
|
if (section) { |
||||||
|
osi_free(section); |
||||||
|
} |
||||||
|
if (keyname) { |
||||||
|
osi_free(keyname); |
||||||
|
} |
||||||
|
if (err_code) { |
||||||
|
OSI_TRACE_ERROR("%s returned with err code: %d\n", __func__, err_code); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static section_t *section_new(const char *name) |
||||||
|
{ |
||||||
|
section_t *section = osi_calloc(sizeof(section_t)); |
||||||
|
if (!section) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
section->name = osi_strdup(name); |
||||||
|
section->entries = list_new(entry_free); |
||||||
|
return section; |
||||||
|
} |
||||||
|
|
||||||
|
static void section_free(void *ptr) |
||||||
|
{ |
||||||
|
if (!ptr) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
section_t *section = ptr; |
||||||
|
osi_free(section->name); |
||||||
|
list_free(section->entries); |
||||||
|
osi_free(section); |
||||||
|
} |
||||||
|
|
||||||
|
static section_t *section_find(const config_t *config, const char *section) |
||||||
|
{ |
||||||
|
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { |
||||||
|
section_t *sec = list_node(node); |
||||||
|
if (!strcmp(sec->name, section)) { |
||||||
|
return sec; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static entry_t *entry_new(const char *key, const char *value) |
||||||
|
{ |
||||||
|
entry_t *entry = osi_calloc(sizeof(entry_t)); |
||||||
|
if (!entry) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
entry->key = osi_strdup(key); |
||||||
|
entry->value = osi_strdup(value); |
||||||
|
return entry; |
||||||
|
} |
||||||
|
|
||||||
|
static void entry_free(void *ptr) |
||||||
|
{ |
||||||
|
if (!ptr) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
entry_t *entry = ptr; |
||||||
|
osi_free(entry->key); |
||||||
|
osi_free(entry->value); |
||||||
|
osi_free(entry); |
||||||
|
} |
||||||
|
|
||||||
|
static entry_t *entry_find(const config_t *config, const char *section, const char *key) |
||||||
|
{ |
||||||
|
section_t *sec = section_find(config, section); |
||||||
|
if (!sec) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) { |
||||||
|
entry_t *entry = list_node(node); |
||||||
|
if (!strcmp(entry->key, key)) { |
||||||
|
return entry; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/pkt_queue.h" |
||||||
|
#include "osi/fixed_pkt_queue.h" |
||||||
|
#include "osi/osi.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
typedef struct fixed_pkt_queue_t { |
||||||
|
struct pkt_queue *pkt_list; |
||||||
|
osi_sem_t enqueue_sem; |
||||||
|
osi_sem_t dequeue_sem; |
||||||
|
size_t capacity; |
||||||
|
fixed_pkt_queue_cb dequeue_ready; |
||||||
|
} fixed_pkt_queue_t; |
||||||
|
|
||||||
|
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity) |
||||||
|
{ |
||||||
|
fixed_pkt_queue_t *ret = osi_calloc(sizeof(fixed_pkt_queue_t)); |
||||||
|
if (!ret) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
ret->capacity = capacity; |
||||||
|
ret->pkt_list = pkt_queue_create(); |
||||||
|
if (!ret->pkt_list) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
osi_sem_new(&ret->enqueue_sem, capacity, capacity); |
||||||
|
if (!ret->enqueue_sem) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
osi_sem_new(&ret->dequeue_sem, capacity, 0); |
||||||
|
if (!ret->dequeue_sem) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
|
||||||
|
error: |
||||||
|
fixed_pkt_queue_free(ret, NULL); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
fixed_pkt_queue_unregister_dequeue(queue); |
||||||
|
|
||||||
|
pkt_queue_destroy(queue->pkt_list, (pkt_queue_free_cb)free_cb); |
||||||
|
queue->pkt_list = NULL; |
||||||
|
|
||||||
|
if (queue->enqueue_sem) { |
||||||
|
osi_sem_free(&queue->enqueue_sem); |
||||||
|
} |
||||||
|
if (queue->dequeue_sem) { |
||||||
|
osi_sem_free(&queue->dequeue_sem); |
||||||
|
} |
||||||
|
osi_free(queue); |
||||||
|
} |
||||||
|
|
||||||
|
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return pkt_queue_is_empty(queue->pkt_list); |
||||||
|
} |
||||||
|
|
||||||
|
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return pkt_queue_length(queue->pkt_list); |
||||||
|
} |
||||||
|
|
||||||
|
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
return queue->capacity; |
||||||
|
} |
||||||
|
|
||||||
|
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout) |
||||||
|
{ |
||||||
|
bool ret = false; |
||||||
|
|
||||||
|
assert(queue != NULL); |
||||||
|
assert(linked_pkt != NULL); |
||||||
|
|
||||||
|
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
ret = pkt_queue_enqueue(queue->pkt_list, linked_pkt); |
||||||
|
|
||||||
|
assert(ret == true); |
||||||
|
osi_sem_give(&queue->dequeue_sem); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout) |
||||||
|
{ |
||||||
|
pkt_linked_item_t *ret = NULL; |
||||||
|
|
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
ret = pkt_queue_dequeue(queue->pkt_list); |
||||||
|
|
||||||
|
osi_sem_give(&queue->enqueue_sem); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
return pkt_queue_try_peek_first(queue->pkt_list); |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
assert(ready_cb != NULL); |
||||||
|
|
||||||
|
queue->dequeue_ready = ready_cb; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
queue->dequeue_ready = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
if (queue->dequeue_ready) { |
||||||
|
queue->dequeue_ready(queue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,256 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/fixed_queue.h" |
||||||
|
#include "osi/list.h" |
||||||
|
#include "osi/osi.h" |
||||||
|
#include "osi/mutex.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
typedef struct fixed_queue_t { |
||||||
|
|
||||||
|
list_t *list; |
||||||
|
osi_sem_t enqueue_sem; |
||||||
|
osi_sem_t dequeue_sem; |
||||||
|
osi_mutex_t lock; |
||||||
|
size_t capacity; |
||||||
|
|
||||||
|
fixed_queue_cb dequeue_ready; |
||||||
|
} fixed_queue_t; |
||||||
|
|
||||||
|
|
||||||
|
fixed_queue_t *fixed_queue_new(size_t capacity) |
||||||
|
{ |
||||||
|
fixed_queue_t *ret = osi_calloc(sizeof(fixed_queue_t)); |
||||||
|
if (!ret) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_new(&ret->lock); |
||||||
|
ret->capacity = capacity; |
||||||
|
|
||||||
|
ret->list = list_new(NULL); |
||||||
|
if (!ret->list) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
osi_sem_new(&ret->enqueue_sem, capacity, capacity); |
||||||
|
if (!ret->enqueue_sem) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
osi_sem_new(&ret->dequeue_sem, capacity, 0); |
||||||
|
if (!ret->dequeue_sem) { |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
|
||||||
|
error:; |
||||||
|
fixed_queue_free(ret, NULL); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb) |
||||||
|
{ |
||||||
|
const list_node_t *node; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
fixed_queue_unregister_dequeue(queue); |
||||||
|
|
||||||
|
if (free_cb) { |
||||||
|
for (node = list_begin(queue->list); node != list_end(queue->list); node = list_next(node)) { |
||||||
|
free_cb(list_node(node)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
list_free(queue->list); |
||||||
|
osi_sem_free(&queue->enqueue_sem); |
||||||
|
osi_sem_free(&queue->dequeue_sem); |
||||||
|
osi_mutex_free(&queue->lock); |
||||||
|
osi_free(queue); |
||||||
|
} |
||||||
|
|
||||||
|
bool fixed_queue_is_empty(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
bool is_empty = false; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
is_empty = list_is_empty(queue->list); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return is_empty; |
||||||
|
} |
||||||
|
|
||||||
|
size_t fixed_queue_length(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
size_t length; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
length = list_length(queue->list); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return length; |
||||||
|
} |
||||||
|
size_t fixed_queue_capacity(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
return queue->capacity; |
||||||
|
} |
||||||
|
|
||||||
|
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout) |
||||||
|
{ |
||||||
|
bool status=false; //Flag whether enqueued success
|
||||||
|
|
||||||
|
assert(queue != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
|
||||||
|
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
status = list_append(queue->list, data); //Check whether enqueued success
|
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
if(status == true ) |
||||||
|
osi_sem_give(&queue->dequeue_sem); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout) |
||||||
|
{ |
||||||
|
void *ret = NULL; |
||||||
|
|
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
ret = list_front(queue->list); |
||||||
|
list_remove(queue->list, ret); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
osi_sem_give(&queue->enqueue_sem); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void *fixed_queue_try_peek_first(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
void *ret = NULL; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
ret = list_is_empty(queue->list) ? NULL : list_front(queue->list); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void *fixed_queue_try_peek_last(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
void *ret = NULL; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
ret = list_is_empty(queue->list) ? NULL : list_back(queue->list); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data) |
||||||
|
{ |
||||||
|
bool removed = false; |
||||||
|
|
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
if (list_contains(queue->list, data) && |
||||||
|
osi_sem_take(&queue->dequeue_sem, 0) == 0) { |
||||||
|
removed = list_remove(queue->list, data); |
||||||
|
assert(removed); |
||||||
|
} |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
if (removed) { |
||||||
|
osi_sem_give(&queue->enqueue_sem); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
list_t *fixed_queue_get_list(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
// NOTE: This function is not thread safe, and there is no point for
|
||||||
|
// calling osi_mutex_lock() / osi_mutex_unlock()
|
||||||
|
return queue->list; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
assert(ready_cb != NULL); |
||||||
|
|
||||||
|
queue->dequeue_ready = ready_cb; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_queue_unregister_dequeue(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
queue->dequeue_ready = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void fixed_queue_process(fixed_queue_t *queue) |
||||||
|
{ |
||||||
|
assert(queue != NULL); |
||||||
|
|
||||||
|
if (queue->dequeue_ready) { |
||||||
|
queue->dequeue_ready(queue); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,97 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/future.h" |
||||||
|
#include "osi/osi.h" |
||||||
|
|
||||||
|
void future_free(future_t *future); |
||||||
|
|
||||||
|
future_t *future_new(void) |
||||||
|
{ |
||||||
|
future_t *ret = osi_calloc(sizeof(future_t)); |
||||||
|
if (!ret) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__); |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
if (osi_sem_new(&ret->semaphore, 1, 0) != 0) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate memory for the semaphore.", __func__); |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
ret->ready_can_be_called = true; |
||||||
|
return ret; |
||||||
|
error:; |
||||||
|
future_free(ret); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
future_t *future_new_immediate(void *value) |
||||||
|
{ |
||||||
|
future_t *ret = osi_calloc(sizeof(future_t)); |
||||||
|
if (!ret) { |
||||||
|
OSI_TRACE_ERROR("%s unable to allocate memory for return value.", __func__); |
||||||
|
goto error; |
||||||
|
} |
||||||
|
|
||||||
|
ret->result = value; |
||||||
|
ret->ready_can_be_called = false; |
||||||
|
return ret; |
||||||
|
error:; |
||||||
|
future_free(ret); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void future_ready(future_t *future, void *value) |
||||||
|
{ |
||||||
|
assert(future != NULL); |
||||||
|
assert(future->ready_can_be_called); |
||||||
|
|
||||||
|
future->ready_can_be_called = false; |
||||||
|
future->result = value; |
||||||
|
osi_sem_give(&future->semaphore); |
||||||
|
} |
||||||
|
|
||||||
|
void *future_await(future_t *future) |
||||||
|
{ |
||||||
|
assert(future != NULL); |
||||||
|
|
||||||
|
// If the future is immediate, it will not have a semaphore
|
||||||
|
if (future->semaphore) { |
||||||
|
osi_sem_take(&future->semaphore, OSI_SEM_MAX_TIMEOUT); |
||||||
|
} |
||||||
|
|
||||||
|
void *result = future->result; |
||||||
|
future_free(future); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
void future_free(future_t *future) |
||||||
|
{ |
||||||
|
if (!future) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (future->semaphore) { |
||||||
|
osi_sem_free(&future->semaphore); |
||||||
|
} |
||||||
|
|
||||||
|
osi_free(future); |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "osi/hash_functions.h" |
||||||
|
|
||||||
|
hash_index_t hash_function_naive(const void *key) |
||||||
|
{ |
||||||
|
return (hash_index_t)key; |
||||||
|
} |
||||||
|
|
||||||
|
hash_index_t hash_function_integer(const void *key) |
||||||
|
{ |
||||||
|
return ((hash_index_t)key) * 2654435761; |
||||||
|
} |
||||||
|
|
||||||
|
hash_index_t hash_function_pointer(const void *key) |
||||||
|
{ |
||||||
|
return ((hash_index_t)key) * 2654435761; |
||||||
|
} |
||||||
|
|
||||||
|
hash_index_t hash_function_string(const void *key) |
||||||
|
{ |
||||||
|
hash_index_t hash = 5381; |
||||||
|
const char *name = (const char *)key; |
||||||
|
size_t string_len = strlen(name); |
||||||
|
for (size_t i = 0; i < string_len; ++i) { |
||||||
|
hash = ((hash << 5) + hash ) + name[i]; |
||||||
|
} |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h) |
||||||
|
{ |
||||||
|
size_t j; |
||||||
|
|
||||||
|
while (len--) { |
||||||
|
j = sizeof(hash_key_t)-1; |
||||||
|
|
||||||
|
while (j) { |
||||||
|
h[j] = ((h[j] << 7) | (h[j-1] >> 1)) + h[j]; |
||||||
|
--j; |
||||||
|
} |
||||||
|
|
||||||
|
h[0] = (h[0] << 7) + h[0] + *s++; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,270 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/list.h" |
||||||
|
#include "osi/hash_map.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
|
||||||
|
struct hash_map_t; |
||||||
|
|
||||||
|
typedef struct hash_map_bucket_t { |
||||||
|
list_t *list; |
||||||
|
} hash_map_bucket_t; |
||||||
|
|
||||||
|
typedef struct hash_map_t { |
||||||
|
hash_map_bucket_t *bucket; |
||||||
|
size_t num_bucket; |
||||||
|
size_t hash_size; |
||||||
|
hash_index_fn hash_fn; |
||||||
|
key_free_fn key_fn; |
||||||
|
data_free_fn data_fn; |
||||||
|
key_equality_fn keys_are_equal; |
||||||
|
} hash_map_t; |
||||||
|
|
||||||
|
// Hidden constructor for list, only to be used by us.
|
||||||
|
list_t *list_new_internal(list_free_cb callback); |
||||||
|
|
||||||
|
static void bucket_free_(void *data); |
||||||
|
static bool default_key_equality(const void *x, const void *y); |
||||||
|
static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list, |
||||||
|
const void *key); |
||||||
|
|
||||||
|
// Hidden constructor, only to be used by the allocation tracker. Behaves the same as
|
||||||
|
// |hash_map_new|, except you get to specify the allocator.
|
||||||
|
hash_map_t *hash_map_new_internal( |
||||||
|
size_t num_bucket, |
||||||
|
hash_index_fn hash_fn, |
||||||
|
key_free_fn key_fn, |
||||||
|
data_free_fn data_fn, |
||||||
|
key_equality_fn equality_fn) |
||||||
|
{ |
||||||
|
assert(hash_fn != NULL); |
||||||
|
assert(num_bucket > 0); |
||||||
|
hash_map_t *hash_map = osi_calloc(sizeof(hash_map_t)); |
||||||
|
if (hash_map == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
hash_map->hash_fn = hash_fn; |
||||||
|
hash_map->key_fn = key_fn; |
||||||
|
hash_map->data_fn = data_fn; |
||||||
|
hash_map->keys_are_equal = equality_fn ? equality_fn : default_key_equality; |
||||||
|
|
||||||
|
hash_map->num_bucket = num_bucket; |
||||||
|
hash_map->bucket = osi_calloc(sizeof(hash_map_bucket_t) * num_bucket); |
||||||
|
if (hash_map->bucket == NULL) { |
||||||
|
osi_free(hash_map); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
return hash_map; |
||||||
|
} |
||||||
|
|
||||||
|
hash_map_t *hash_map_new( |
||||||
|
size_t num_bucket, |
||||||
|
hash_index_fn hash_fn, |
||||||
|
key_free_fn key_fn, |
||||||
|
data_free_fn data_fn, |
||||||
|
key_equality_fn equality_fn) |
||||||
|
{ |
||||||
|
return hash_map_new_internal(num_bucket, hash_fn, key_fn, data_fn, equality_fn); |
||||||
|
} |
||||||
|
|
||||||
|
void hash_map_free(hash_map_t *hash_map) |
||||||
|
{ |
||||||
|
if (hash_map == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
hash_map_clear(hash_map); |
||||||
|
osi_free(hash_map->bucket); |
||||||
|
osi_free(hash_map); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
bool hash_map_is_empty(const hash_map_t *hash_map) { |
||||||
|
assert(hash_map != NULL); |
||||||
|
return (hash_map->hash_size == 0); |
||||||
|
} |
||||||
|
|
||||||
|
size_t hash_map_size(const hash_map_t *hash_map) { |
||||||
|
assert(hash_map != NULL); |
||||||
|
return hash_map->hash_size; |
||||||
|
} |
||||||
|
|
||||||
|
size_t hash_map_num_buckets(const hash_map_t *hash_map) { |
||||||
|
assert(hash_map != NULL); |
||||||
|
return hash_map->num_bucket; |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
bool hash_map_has_key(const hash_map_t *hash_map, const void *key) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
|
||||||
|
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; |
||||||
|
list_t *hash_bucket_list = hash_map->bucket[hash_key].list; |
||||||
|
|
||||||
|
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); |
||||||
|
return (hash_map_entry != NULL); |
||||||
|
} |
||||||
|
|
||||||
|
bool hash_map_set(hash_map_t *hash_map, const void *key, void *data) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
|
||||||
|
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; |
||||||
|
|
||||||
|
if (hash_map->bucket[hash_key].list == NULL) { |
||||||
|
hash_map->bucket[hash_key].list = list_new_internal(bucket_free_); |
||||||
|
if (hash_map->bucket[hash_key].list == NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
list_t *hash_bucket_list = hash_map->bucket[hash_key].list; |
||||||
|
|
||||||
|
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); |
||||||
|
|
||||||
|
if (hash_map_entry) { |
||||||
|
// Calls hash_map callback to delete the hash_map_entry.
|
||||||
|
bool rc = list_remove(hash_bucket_list, hash_map_entry); |
||||||
|
assert(rc == true); |
||||||
|
(void)rc; |
||||||
|
} else { |
||||||
|
hash_map->hash_size++; |
||||||
|
} |
||||||
|
hash_map_entry = osi_calloc(sizeof(hash_map_entry_t)); |
||||||
|
if (hash_map_entry == NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
hash_map_entry->key = key; |
||||||
|
hash_map_entry->data = data; |
||||||
|
hash_map_entry->hash_map = hash_map; |
||||||
|
|
||||||
|
return list_append(hash_bucket_list, hash_map_entry); |
||||||
|
} |
||||||
|
|
||||||
|
bool hash_map_erase(hash_map_t *hash_map, const void *key) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
|
||||||
|
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; |
||||||
|
list_t *hash_bucket_list = hash_map->bucket[hash_key].list; |
||||||
|
|
||||||
|
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); |
||||||
|
if (hash_map_entry == NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
hash_map->hash_size--; |
||||||
|
bool remove = list_remove(hash_bucket_list, hash_map_entry); |
||||||
|
if(list_is_empty(hash_map->bucket[hash_key].list)) { |
||||||
|
list_free(hash_map->bucket[hash_key].list); |
||||||
|
hash_map->bucket[hash_key].list = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
return remove; |
||||||
|
} |
||||||
|
|
||||||
|
void *hash_map_get(const hash_map_t *hash_map, const void *key) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
|
||||||
|
hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; |
||||||
|
list_t *hash_bucket_list = hash_map->bucket[hash_key].list; |
||||||
|
|
||||||
|
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); |
||||||
|
if (hash_map_entry != NULL) { |
||||||
|
return hash_map_entry->data; |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void hash_map_clear(hash_map_t *hash_map) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
|
||||||
|
for (hash_index_t i = 0; i < hash_map->num_bucket; i++) { |
||||||
|
if (hash_map->bucket[i].list == NULL) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
list_free(hash_map->bucket[i].list); |
||||||
|
hash_map->bucket[i].list = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context) |
||||||
|
{ |
||||||
|
assert(hash_map != NULL); |
||||||
|
assert(callback != NULL); |
||||||
|
|
||||||
|
for (hash_index_t i = 0; i < hash_map->num_bucket; ++i) { |
||||||
|
if (hash_map->bucket[i].list == NULL) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
for (const list_node_t *iter = list_begin(hash_map->bucket[i].list); |
||||||
|
iter != list_end(hash_map->bucket[i].list); |
||||||
|
iter = list_next(iter)) { |
||||||
|
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter); |
||||||
|
if (!callback(hash_map_entry, context)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void bucket_free_(void *data) |
||||||
|
{ |
||||||
|
assert(data != NULL); |
||||||
|
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)data; |
||||||
|
const hash_map_t *hash_map = hash_map_entry->hash_map; |
||||||
|
|
||||||
|
if (hash_map->key_fn) { |
||||||
|
hash_map->key_fn((void *)hash_map_entry->key); |
||||||
|
} |
||||||
|
if (hash_map->data_fn) { |
||||||
|
hash_map->data_fn(hash_map_entry->data); |
||||||
|
} |
||||||
|
osi_free(hash_map_entry); |
||||||
|
} |
||||||
|
|
||||||
|
static hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list, |
||||||
|
const void *key) |
||||||
|
{ |
||||||
|
|
||||||
|
if (hash_bucket_list == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
for (const list_node_t *iter = list_begin(hash_bucket_list); |
||||||
|
iter != list_end(hash_bucket_list); |
||||||
|
iter = list_next(iter)) { |
||||||
|
hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter); |
||||||
|
if (hash_map_entry->hash_map->keys_are_equal(hash_map_entry->key, key)) { |
||||||
|
return hash_map_entry; |
||||||
|
} |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static bool default_key_equality(const void *x, const void *y) |
||||||
|
{ |
||||||
|
return x == y; |
||||||
|
} |
@ -0,0 +1,84 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _ALARM_H_ |
||||||
|
#define _ALARM_H_ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include "esp_timer.h" |
||||||
|
|
||||||
|
typedef struct alarm_t osi_alarm_t; |
||||||
|
typedef uint64_t period_ms_t; |
||||||
|
typedef esp_timer_cb_t osi_alarm_callback_t; |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
OSI_ALARM_ERR_PASS = 0, |
||||||
|
OSI_ALARM_ERR_FAIL = -1, |
||||||
|
OSI_ALARM_ERR_INVALID_ARG = -2, |
||||||
|
OSI_ALARM_ERR_INVALID_STATE = -3, |
||||||
|
} osi_alarm_err_t; |
||||||
|
|
||||||
|
#define ALARM_CBS_NUM 50 |
||||||
|
#define ALARM_ID_BASE 1000 |
||||||
|
|
||||||
|
int osi_alarm_create_mux(void); |
||||||
|
int osi_alarm_delete_mux(void); |
||||||
|
void osi_alarm_init(void); |
||||||
|
void osi_alarm_deinit(void); |
||||||
|
|
||||||
|
// Creates a new alarm object. The returned object must be freed by calling
|
||||||
|
// |alarm_free|. Returns NULL on failure.
|
||||||
|
osi_alarm_t *osi_alarm_new(const char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire); |
||||||
|
|
||||||
|
// Frees an alarm object created by |alarm_new|. |alarm| may be NULL. If the
|
||||||
|
// alarm is pending, it will be cancelled. It is not safe to call |alarm_free|
|
||||||
|
// from inside the callback of |alarm|.
|
||||||
|
void osi_alarm_free(osi_alarm_t *alarm); |
||||||
|
|
||||||
|
// Sets an alarm to fire |cb| after the given |deadline|. Note that |deadline| is the
|
||||||
|
// number of milliseconds relative to the current time. |data| is a context variable
|
||||||
|
// for the callback and may be NULL. |cb| will be called back in the context of an
|
||||||
|
// unspecified thread (i.e. it will not be called back in the same thread as the caller).
|
||||||
|
// |alarm| and |cb| may not be NULL.
|
||||||
|
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout); |
||||||
|
|
||||||
|
// Sets an periodic alarm to fire |cb| each given |period|.
|
||||||
|
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period); |
||||||
|
|
||||||
|
// This function cancels the |alarm| if it was previously set. When this call
|
||||||
|
// returns, the caller has a guarantee that the callback is not in progress and
|
||||||
|
// will not be called if it hasn't already been called. This function is idempotent.
|
||||||
|
// |alarm| may not be NULL.
|
||||||
|
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm); |
||||||
|
|
||||||
|
// Figure out how much time until next expiration.
|
||||||
|
// Returns 0 if not armed. |alarm| may not be NULL.
|
||||||
|
// only for oneshot alarm, not for periodic alarm
|
||||||
|
// TODO: Remove this function once PM timers can be re-factored
|
||||||
|
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm); |
||||||
|
|
||||||
|
// Alarm-related state cleanup
|
||||||
|
//void alarm_cleanup(void);
|
||||||
|
|
||||||
|
uint32_t osi_time_get_os_boottime_ms(void); |
||||||
|
|
||||||
|
// This function returns whether the given |alarm| is active or not.
|
||||||
|
// Return true if active, false otherwise.
|
||||||
|
bool osi_alarm_is_active(osi_alarm_t *alarm); |
||||||
|
|
||||||
|
#endif /*_ALARM_H_*/ |
@ -0,0 +1,145 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _ALLOCATOR_H_ |
||||||
|
#define _ALLOCATOR_H_ |
||||||
|
|
||||||
|
#include <stddef.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include "esp_heap_caps.h" |
||||||
|
|
||||||
|
char *osi_strdup(const char *str); |
||||||
|
|
||||||
|
void *osi_malloc_func(size_t size); |
||||||
|
void *osi_calloc_func(size_t size); |
||||||
|
void osi_free_func(void *ptr); |
||||||
|
|
||||||
|
#if HEAP_MEMORY_DEBUG |
||||||
|
|
||||||
|
void osi_mem_dbg_init(void); |
||||||
|
void osi_mem_dbg_record(void *p, int size, const char *func, int line); |
||||||
|
void osi_mem_dbg_clean(void *p, const char *func, int line); |
||||||
|
void osi_mem_dbg_show(void); |
||||||
|
uint32_t osi_mem_dbg_get_max_size(void); |
||||||
|
uint32_t osi_mem_dbg_get_current_size(void); |
||||||
|
void osi_men_dbg_set_section_start(uint8_t index); |
||||||
|
void osi_men_dbg_set_section_end(uint8_t index); |
||||||
|
uint32_t osi_mem_dbg_get_max_size_section(uint8_t index); |
||||||
|
|
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
#define osi_malloc(size) \ |
||||||
|
({ \
|
||||||
|
void *p; \
|
||||||
|
p = heap_caps_malloc_prefer(size, 2, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#define osi_calloc(size) \ |
||||||
|
({ \
|
||||||
|
void *p; \
|
||||||
|
p = heap_caps_calloc_prefer(1, size, 2, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#define osi_malloc(size) \ |
||||||
|
({ \
|
||||||
|
void *p; \
|
||||||
|
p = malloc((size)); \
|
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#define osi_calloc(size) \ |
||||||
|
({ \
|
||||||
|
void *p; \
|
||||||
|
p = calloc(1, (size)); \
|
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
}) |
||||||
|
|
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
|
||||||
|
|
||||||
|
#if 0 |
||||||
|
#define osi_malloc(size) \ |
||||||
|
do { \
|
||||||
|
void *p; \
|
||||||
|
\
|
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \ |
||||||
|
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
|
#else \ |
||||||
|
p = malloc((size)); \
|
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \ |
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
}while(0) |
||||||
|
|
||||||
|
#define osi_calloc(size) \ |
||||||
|
do { \
|
||||||
|
void *p; \
|
||||||
|
\
|
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST \ |
||||||
|
p = heap_caps_calloc_prefer(1, size, 2, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
|
||||||
|
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
|
||||||
|
#else \ |
||||||
|
p = calloc(1, (size)); \
|
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ \ |
||||||
|
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||||
|
(void *)p; \
|
||||||
|
} while(0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define osi_free(ptr) \ |
||||||
|
do { \
|
||||||
|
void *tmp_point = (void *)(ptr); \
|
||||||
|
osi_mem_dbg_clean(tmp_point, __func__, __LINE__); \
|
||||||
|
free(tmp_point); \
|
||||||
|
} while (0) |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST |
||||||
|
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) |
||||||
|
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) |
||||||
|
#else |
||||||
|
#define osi_malloc(size) malloc((size)) |
||||||
|
#define osi_calloc(size) calloc(1, (size)) |
||||||
|
#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ |
||||||
|
#define osi_free(p) free((p)) |
||||||
|
|
||||||
|
#endif /* HEAP_MEMORY_DEBUG */ |
||||||
|
|
||||||
|
#define FREE_AND_RESET(a) \ |
||||||
|
do { \
|
||||||
|
if (a) { \
|
||||||
|
osi_free(a); \
|
||||||
|
a = NULL; \
|
||||||
|
} \
|
||||||
|
}while (0) |
||||||
|
|
||||||
|
|
||||||
|
#endif /* _ALLOCATOR_H_ */ |
@ -0,0 +1,59 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _BUFFER_H_ |
||||||
|
#define _BUFFER_H_ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include <stddef.h> |
||||||
|
|
||||||
|
typedef struct buffer_t buffer_t; |
||||||
|
|
||||||
|
// Returns a new buffer of |size| bytes. Returns NULL if a buffer could not be
|
||||||
|
// allocated. |size| must be non-zero. The caller must release this buffer with
|
||||||
|
// |buffer_free|.
|
||||||
|
buffer_t *buffer_new(size_t size); |
||||||
|
|
||||||
|
// Creates a new reference to the buffer |buf|. A reference is indistinguishable
|
||||||
|
// from the original: writes to the original will be reflected in the reference
|
||||||
|
// and vice versa. In other words, this function creates an alias to |buf|. The
|
||||||
|
// caller must release the returned buffer with |buffer_free|. Note that releasing
|
||||||
|
// the returned buffer does not release |buf|. |buf| must not be NULL.
|
||||||
|
buffer_t *buffer_new_ref(const buffer_t *buf); |
||||||
|
|
||||||
|
// Creates a new reference to the last |slice_size| bytes of |buf|. See
|
||||||
|
// |buffer_new_ref| for a description of references. |slice_size| must be
|
||||||
|
// greater than 0 and may be at most |buffer_length|
|
||||||
|
// (0 < slice_size <= buffer_length). |buf| must not be NULL.
|
||||||
|
buffer_t *buffer_new_slice(const buffer_t *buf, size_t slice_size); |
||||||
|
|
||||||
|
// Frees a buffer object. |buf| may be NULL.
|
||||||
|
void buffer_free(buffer_t *buf); |
||||||
|
|
||||||
|
// Returns a pointer to a writeable memory region for |buf|. All references
|
||||||
|
// and slices that share overlapping bytes will also be written to when
|
||||||
|
// writing to the returned pointer. The caller may safely write up to
|
||||||
|
// |buffer_length| consecutive bytes starting at the address returned by
|
||||||
|
// this function. |buf| must not be NULL.
|
||||||
|
void *buffer_ptr(const buffer_t *buf); |
||||||
|
|
||||||
|
// Returns the length of the writeable memory region referred to by |buf|.
|
||||||
|
// |buf| must not be NULL.
|
||||||
|
size_t buffer_length(const buffer_t *buf); |
||||||
|
|
||||||
|
#endif /*_BUFFER_H_*/ |
@ -0,0 +1,145 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __CONFIG_H__ |
||||||
|
#define __CONFIG_H__ |
||||||
|
|
||||||
|
// This module implements a configuration parser. Clients can query the
|
||||||
|
// contents of a configuration file through the interface provided here.
|
||||||
|
// The current implementation is read-only; mutations are only kept in
|
||||||
|
// memory. This parser supports the INI file format.
|
||||||
|
|
||||||
|
// Implementation notes:
|
||||||
|
// - Key/value pairs that are not within a section are assumed to be under
|
||||||
|
// the |CONFIG_DEFAULT_SECTION| section.
|
||||||
|
// - Multiple sections with the same name will be merged as if they were in
|
||||||
|
// a single section.
|
||||||
|
// - Empty sections with no key/value pairs will be treated as if they do
|
||||||
|
// not exist. In other words, |config_has_section| will return false for
|
||||||
|
// empty sections.
|
||||||
|
// - Duplicate keys in a section will overwrite previous values.
|
||||||
|
// - All strings are case sensitive.
|
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
// The default section name to use if a key/value pair is not defined within
|
||||||
|
// a section.
|
||||||
|
#define CONFIG_DEFAULT_SECTION "Global" |
||||||
|
|
||||||
|
typedef struct config_t config_t; |
||||||
|
typedef struct config_section_node_t config_section_node_t; |
||||||
|
|
||||||
|
// Creates a new config object with no entries (i.e. not backed by a file).
|
||||||
|
// This function returns a config object or NULL on error. Clients must call
|
||||||
|
// |config_free| on the returned handle when it is no longer required.
|
||||||
|
config_t *config_new_empty(void); |
||||||
|
|
||||||
|
// Loads the specified file and returns a handle to the config file. If there
|
||||||
|
// was a problem loading the file or allocating memory, this function returns
|
||||||
|
// NULL. Clients must call |config_free| on the returned handle when it is no
|
||||||
|
// longer required. |filename| must not be NULL and must point to a readable
|
||||||
|
// file on the filesystem.
|
||||||
|
config_t *config_new(const char *filename); |
||||||
|
|
||||||
|
// Frees resources associated with the config file. No further operations may
|
||||||
|
// be performed on the |config| object after calling this function. |config|
|
||||||
|
// may be NULL.
|
||||||
|
void config_free(config_t *config); |
||||||
|
|
||||||
|
// Returns true if the config file contains a section named |section|. If
|
||||||
|
// the section has no key/value pairs in it, this function will return false.
|
||||||
|
// |config| and |section| must not be NULL.
|
||||||
|
bool config_has_section(const config_t *config, const char *section); |
||||||
|
|
||||||
|
// Returns true if the config file has a key named |key| under |section|.
|
||||||
|
// Returns false otherwise. |config|, |section|, and |key| must not be NULL.
|
||||||
|
bool config_has_key(const config_t *config, const char *section, const char *key); |
||||||
|
|
||||||
|
// Returns true if the config file has a key named |key| and the key_value.
|
||||||
|
// Returns false otherwise. |config|, |key|, and |key_value| must not be NULL.
|
||||||
|
bool config_has_key_in_section(config_t *config, const char *key, char *key_value); |
||||||
|
|
||||||
|
// Returns the integral value for a given |key| in |section|. If |section|
|
||||||
|
// or |key| do not exist, or the value cannot be fully converted to an integer,
|
||||||
|
// this function returns |def_value|. |config|, |section|, and |key| must not
|
||||||
|
// be NULL.
|
||||||
|
int config_get_int(const config_t *config, const char *section, const char *key, int def_value); |
||||||
|
|
||||||
|
// Returns the boolean value for a given |key| in |section|. If |section|
|
||||||
|
// or |key| do not exist, or the value cannot be converted to a boolean, this
|
||||||
|
// function returns |def_value|. |config|, |section|, and |key| must not be NULL.
|
||||||
|
bool config_get_bool(const config_t *config, const char *section, const char *key, bool def_value); |
||||||
|
|
||||||
|
// Returns the string value for a given |key| in |section|. If |section| or
|
||||||
|
// |key| do not exist, this function returns |def_value|. The returned string
|
||||||
|
// is owned by the config module and must not be freed. |config|, |section|,
|
||||||
|
// and |key| must not be NULL. |def_value| may be NULL.
|
||||||
|
const char *config_get_string(const config_t *config, const char *section, const char *key, const char *def_value); |
||||||
|
|
||||||
|
// Sets an integral value for the |key| in |section|. If |key| or |section| do
|
||||||
|
// not already exist, this function creates them. |config|, |section|, and |key|
|
||||||
|
// must not be NULL.
|
||||||
|
void config_set_int(config_t *config, const char *section, const char *key, int value); |
||||||
|
|
||||||
|
// Sets a boolean value for the |key| in |section|. If |key| or |section| do
|
||||||
|
// not already exist, this function creates them. |config|, |section|, and |key|
|
||||||
|
// must not be NULL.
|
||||||
|
void config_set_bool(config_t *config, const char *section, const char *key, bool value); |
||||||
|
|
||||||
|
// Sets a string value for the |key| in |section|. If |key| or |section| do
|
||||||
|
// not already exist, this function creates them. |config|, |section|, |key|, and
|
||||||
|
// |value| must not be NULL.
|
||||||
|
void config_set_string(config_t *config, const char *section, const char *key, const char *value, bool insert_back); |
||||||
|
|
||||||
|
// Removes |section| from the |config| (and, as a result, all keys in the section).
|
||||||
|
// Returns true if |section| was found and removed from |config|, false otherwise.
|
||||||
|
// Neither |config| nor |section| may be NULL.
|
||||||
|
bool config_remove_section(config_t *config, const char *section); |
||||||
|
|
||||||
|
// Updates |section| to be the first section in |config|. Return true if |section| is in
|
||||||
|
// |config| and updated successfully, false otherwise.
|
||||||
|
// Neither |config| nor |section| may be NULL.
|
||||||
|
bool config_update_newest_section(config_t *config, const char *section); |
||||||
|
|
||||||
|
// Removes one specific |key| residing in |section| of the |config|. Returns true
|
||||||
|
// if the section and key were found and the key was removed, false otherwise.
|
||||||
|
// None of |config|, |section|, or |key| may be NULL.
|
||||||
|
bool config_remove_key(config_t *config, const char *section, const char *key); |
||||||
|
|
||||||
|
// Returns an iterator to the first section in the config file. If there are no
|
||||||
|
// sections, the iterator will equal the return value of |config_section_end|.
|
||||||
|
// The returned pointer must be treated as an opaque handle and must not be freed.
|
||||||
|
// The iterator is invalidated on any config mutating operation. |config| may not
|
||||||
|
// be NULL.
|
||||||
|
const config_section_node_t *config_section_begin(const config_t *config); |
||||||
|
|
||||||
|
// Returns an iterator to one past the last section in the config file. It does not
|
||||||
|
// represent a valid section, but can be used to determine if all sections have been
|
||||||
|
// iterated over. The returned pointer must be treated as an opaque handle and must
|
||||||
|
// not be freed and must not be iterated on (must not call |config_section_next| on
|
||||||
|
// it). |config| may not be NULL.
|
||||||
|
const config_section_node_t *config_section_end(const config_t *config); |
||||||
|
|
||||||
|
// Moves |iter| to the next section. If there are no more sections, |iter| will
|
||||||
|
// equal the value of |config_section_end|. |iter| may not be NULL and must be
|
||||||
|
// a pointer returned by either |config_section_begin| or |config_section_next|.
|
||||||
|
const config_section_node_t *config_section_next(const config_section_node_t *iter); |
||||||
|
|
||||||
|
// Returns the name of the section referred to by |iter|. The returned pointer is
|
||||||
|
// owned by the config module and must not be freed by the caller. The pointer will
|
||||||
|
// remain valid until |config_free| is called. |iter| may not be NULL and must not
|
||||||
|
// equal the value returned by |config_section_end|.
|
||||||
|
const char *config_section_name(const config_section_node_t *iter); |
||||||
|
|
||||||
|
// Saves |config| to a file given by |filename|. Note that this could be a destructive
|
||||||
|
// operation: if |filename| already exists, it will be overwritten. The config
|
||||||
|
// module does not preserve comments or formatting so if a config file was opened
|
||||||
|
// with |config_new| and subsequently overwritten with |config_save|, all comments
|
||||||
|
// and special formatting in the original file will be lost. Neither |config| nor
|
||||||
|
// |filename| may be NULL.
|
||||||
|
bool config_save(const config_t *config, const char *filename); |
||||||
|
|
||||||
|
#endif /* #ifndef __CONFIG_H__ */ |
@ -0,0 +1,79 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _FIXED_PKT_QUEUE_H_ |
||||||
|
#define _FIXED_PKT_QUEUE_H_ |
||||||
|
|
||||||
|
|
||||||
|
#include "osi/pkt_queue.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef FIXED_PKT_QUEUE_SIZE_MAX |
||||||
|
#define FIXED_PKT_QUEUE_SIZE_MAX 254 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define FIXED_PKT_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT |
||||||
|
|
||||||
|
struct fixed_pkt_queue_t; |
||||||
|
|
||||||
|
typedef struct fixed_pkt_queue_t fixed_pkt_queue_t; |
||||||
|
|
||||||
|
typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data); |
||||||
|
typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
// Creates a new fixed queue with the given |capacity|. If more elements than
|
||||||
|
// |capacity| are added to the queue, the caller is blocked until space is
|
||||||
|
// made available in the queue. Returns NULL on failure. The caller must free
|
||||||
|
// the returned queue with |fixed_pkt_queue_free|.
|
||||||
|
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity); |
||||||
|
|
||||||
|
// Freeing a queue that is currently in use (i.e. has waiters
|
||||||
|
// blocked on it) results in undefined behaviour.
|
||||||
|
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb); |
||||||
|
|
||||||
|
// Returns a value indicating whether the given |queue| is empty. If |queue|
|
||||||
|
// is NULL, the return value is true.
|
||||||
|
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
// Returns the length of the |queue|. If |queue| is NULL, the return value
|
||||||
|
// is 0.
|
||||||
|
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
// Returns the maximum number of elements this queue may hold. |queue| may
|
||||||
|
// not be NULL.
|
||||||
|
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
|
||||||
|
// If enqueue failed, it will return false, otherwise return true
|
||||||
|
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout); |
||||||
|
|
||||||
|
// Dequeues the next element from |queue|. If the queue is currently empty,
|
||||||
|
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
|
||||||
|
// If dequeue failed, it will return NULL, otherwise return a point.
|
||||||
|
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout); |
||||||
|
|
||||||
|
// Returns the first element from |queue|, if present, without dequeuing it.
|
||||||
|
// This function will never block the caller. Returns NULL if there are no
|
||||||
|
// elements in the queue or |queue| is NULL.
|
||||||
|
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
// Registers |queue| with |reactor| for dequeue operations. When there is an element
|
||||||
|
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
|
||||||
|
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
|
||||||
|
// |context| may be NULL.
|
||||||
|
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb); |
||||||
|
|
||||||
|
// Unregisters the dequeue ready callback for |queue| from whichever reactor
|
||||||
|
// it is registered with, if any. This function is idempotent.
|
||||||
|
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue); |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,125 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _FIXED_QUEUE_H_ |
||||||
|
#define _FIXED_QUEUE_H_ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include "osi/list.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
#ifndef QUEUE_SIZE_MAX |
||||||
|
#define QUEUE_SIZE_MAX 254 |
||||||
|
#endif |
||||||
|
|
||||||
|
#define FIXED_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT |
||||||
|
|
||||||
|
struct fixed_queue_t; |
||||||
|
|
||||||
|
typedef struct fixed_queue_t fixed_queue_t; |
||||||
|
//typedef struct reactor_t reactor_t;
|
||||||
|
|
||||||
|
typedef void (*fixed_queue_free_cb)(void *data); |
||||||
|
typedef void (*fixed_queue_cb)(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Creates a new fixed queue with the given |capacity|. If more elements than
|
||||||
|
// |capacity| are added to the queue, the caller is blocked until space is
|
||||||
|
// made available in the queue. Returns NULL on failure. The caller must free
|
||||||
|
// the returned queue with |fixed_queue_free|.
|
||||||
|
fixed_queue_t *fixed_queue_new(size_t capacity); |
||||||
|
|
||||||
|
// Freeing a queue that is currently in use (i.e. has waiters
|
||||||
|
// blocked on it) results in undefined behaviour.
|
||||||
|
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb); |
||||||
|
|
||||||
|
// Returns a value indicating whether the given |queue| is empty. If |queue|
|
||||||
|
// is NULL, the return value is true.
|
||||||
|
bool fixed_queue_is_empty(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Returns the length of the |queue|. If |queue| is NULL, the return value
|
||||||
|
// is 0.
|
||||||
|
size_t fixed_queue_length(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Returns the maximum number of elements this queue may hold. |queue| may
|
||||||
|
// not be NULL.
|
||||||
|
size_t fixed_queue_capacity(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
|
||||||
|
// If enqueue failed, it will return false, otherwise return true
|
||||||
|
bool fixed_queue_enqueue(fixed_queue_t *queue, void *data, uint32_t timeout); |
||||||
|
|
||||||
|
// Dequeues the next element from |queue|. If the queue is currently empty,
|
||||||
|
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
|
||||||
|
// If dequeue failed, it will return NULL, otherwise return a point.
|
||||||
|
void *fixed_queue_dequeue(fixed_queue_t *queue, uint32_t timeout); |
||||||
|
|
||||||
|
// Returns the first element from |queue|, if present, without dequeuing it.
|
||||||
|
// This function will never block the caller. Returns NULL if there are no
|
||||||
|
// elements in the queue or |queue| is NULL.
|
||||||
|
void *fixed_queue_try_peek_first(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Returns the last element from |queue|, if present, without dequeuing it.
|
||||||
|
// This function will never block the caller. Returns NULL if there are no
|
||||||
|
// elements in the queue or |queue| is NULL.
|
||||||
|
void *fixed_queue_try_peek_last(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// Tries to remove a |data| element from the middle of the |queue|. This
|
||||||
|
// function will never block the caller. If the queue is empty or NULL, this
|
||||||
|
// function returns NULL immediately. |data| may not be NULL. If the |data|
|
||||||
|
// element is found in the queue, a pointer to the removed data is returned,
|
||||||
|
// otherwise NULL.
|
||||||
|
void *fixed_queue_try_remove_from_queue(fixed_queue_t *queue, void *data); |
||||||
|
|
||||||
|
// Returns the iterateable list with all entries in the |queue|. This function
|
||||||
|
// will never block the caller. |queue| may not be NULL.
|
||||||
|
//
|
||||||
|
// NOTE: The return result of this function is not thread safe: the list could
|
||||||
|
// be modified by another thread, and the result would be unpredictable.
|
||||||
|
// TODO: The usage of this function should be refactored, and the function
|
||||||
|
// itself should be removed.
|
||||||
|
list_t *fixed_queue_get_list(fixed_queue_t *queue); |
||||||
|
|
||||||
|
// This function returns a valid file descriptor. Callers may perform one
|
||||||
|
// operation on the fd: select(2). If |select| indicates that the file
|
||||||
|
// descriptor is readable, the caller may call |fixed_queue_enqueue| without
|
||||||
|
// blocking. The caller must not close the returned file descriptor. |queue|
|
||||||
|
// may not be NULL.
|
||||||
|
//int fixed_queue_get_enqueue_fd(const fixed_queue_t *queue);
|
||||||
|
|
||||||
|
// This function returns a valid file descriptor. Callers may perform one
|
||||||
|
// operation on the fd: select(2). If |select| indicates that the file
|
||||||
|
// descriptor is readable, the caller may call |fixed_queue_dequeue| without
|
||||||
|
// blocking. The caller must not close the returned file descriptor. |queue|
|
||||||
|
// may not be NULL.
|
||||||
|
//int fixed_queue_get_dequeue_fd(const fixed_queue_t *queue);
|
||||||
|
|
||||||
|
// Registers |queue| with |reactor| for dequeue operations. When there is an element
|
||||||
|
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
|
||||||
|
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
|
||||||
|
// |context| may be NULL.
|
||||||
|
void fixed_queue_register_dequeue(fixed_queue_t *queue, fixed_queue_cb ready_cb); |
||||||
|
|
||||||
|
// Unregisters the dequeue ready callback for |queue| from whichever reactor
|
||||||
|
// it is registered with, if any. This function is idempotent.
|
||||||
|
void fixed_queue_unregister_dequeue(fixed_queue_t *queue); |
||||||
|
|
||||||
|
void fixed_queue_process(fixed_queue_t *queue); |
||||||
|
|
||||||
|
list_t *fixed_queue_get_list(fixed_queue_t *queue); |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,53 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef __FUTURE_H__ |
||||||
|
#define __FUTURE_H__ |
||||||
|
|
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
struct future { |
||||||
|
bool ready_can_be_called; |
||||||
|
osi_sem_t semaphore; // NULL semaphore means immediate future
|
||||||
|
void *result; |
||||||
|
}; |
||||||
|
typedef struct future future_t; |
||||||
|
|
||||||
|
#define FUTURE_SUCCESS ((void *)1) |
||||||
|
#define FUTURE_FAIL ((void *)0) |
||||||
|
|
||||||
|
// Constructs a new future_t object. Returns NULL on failure.
|
||||||
|
future_t *future_new(void); |
||||||
|
|
||||||
|
// Constructs a new future_t object with an immediate |value|. No waiting will
|
||||||
|
// occur in the call to |future_await| because the value is already present.
|
||||||
|
// Returns NULL on failure.
|
||||||
|
future_t *future_new_immediate(void *value); |
||||||
|
|
||||||
|
// Signals that the |future| is ready, passing |value| back to the context
|
||||||
|
// waiting for the result. Must only be called once for every future.
|
||||||
|
// |future| may not be NULL.
|
||||||
|
void future_ready(future_t *future, void *value); |
||||||
|
|
||||||
|
// Waits for the |future| to be ready. Returns the value set in |future_ready|.
|
||||||
|
// Frees the future before return. |future| may not be NULL.
|
||||||
|
void *future_await(future_t *async_result); |
||||||
|
|
||||||
|
//Free the future if this "future" is not used
|
||||||
|
void future_free(future_t *future); |
||||||
|
#endif /* __FUTURE_H__ */ |
@ -0,0 +1,37 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _HASH_FUNCTIONS_H_ |
||||||
|
#define _HASH_FUNCTIONS_H_ |
||||||
|
|
||||||
|
#include "osi/hash_map.h" |
||||||
|
|
||||||
|
typedef unsigned char hash_key_t[4]; |
||||||
|
|
||||||
|
hash_index_t hash_function_naive(const void *key); |
||||||
|
|
||||||
|
hash_index_t hash_function_integer(const void *key); |
||||||
|
|
||||||
|
// Hashes a pointer based only on its address value
|
||||||
|
hash_index_t hash_function_pointer(const void *key); |
||||||
|
|
||||||
|
hash_index_t hash_function_string(const void *key); |
||||||
|
|
||||||
|
void hash_function_blob(const unsigned char *s, unsigned int len, hash_key_t h); |
||||||
|
|
||||||
|
#endif /* _HASH_FUNCTIONS_H_ */ |
@ -0,0 +1,110 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef _HASH_MAP_H_ |
||||||
|
#define _HASH_MAP_H_ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
struct hash_map_t; |
||||||
|
typedef struct hash_map_t hash_map_t; |
||||||
|
|
||||||
|
typedef struct hash_map_entry_t { |
||||||
|
const void *key; |
||||||
|
void *data; |
||||||
|
const hash_map_t *hash_map; |
||||||
|
} hash_map_entry_t; |
||||||
|
|
||||||
|
typedef size_t hash_index_t; |
||||||
|
|
||||||
|
// Takes a key structure and returns a hash value.
|
||||||
|
typedef hash_index_t (*hash_index_fn)(const void *key); |
||||||
|
typedef bool (*hash_map_iter_cb)(hash_map_entry_t *hash_entry, void *context); |
||||||
|
|
||||||
|
typedef bool (*key_equality_fn)(const void *x, const void *y); |
||||||
|
|
||||||
|
typedef void (*key_free_fn)(void *data); |
||||||
|
typedef void (*data_free_fn)(void *data); |
||||||
|
|
||||||
|
// Returns a new, empty hash_map. Returns NULL if not enough memory could be allocated
|
||||||
|
// for the hash_map structure. The returned hash_map must be freed with |hash_map_free|.
|
||||||
|
// The |num_bucket| specifies the number of hashable buckets for the map and must not
|
||||||
|
// be zero. The |hash_fn| specifies a hash function to be used and must not be NULL.
|
||||||
|
// The |key_fn| and |data_fn| are called whenever a hash_map element is removed from
|
||||||
|
// the hash_map. They can be used to release resources held by the hash_map element,
|
||||||
|
// e.g. memory or file descriptor. |key_fn| and |data_fn| may be NULL if no cleanup
|
||||||
|
// is necessary on element removal. |equality_fn| is used to check for key equality.
|
||||||
|
// If |equality_fn| is NULL, default pointer equality is used.
|
||||||
|
hash_map_t *hash_map_new( |
||||||
|
size_t size, |
||||||
|
hash_index_fn hash_fn, |
||||||
|
key_free_fn key_fn, |
||||||
|
data_free_fn data_fn, |
||||||
|
key_equality_fn equality_fn); |
||||||
|
|
||||||
|
// Frees the hash_map. This function accepts NULL as an argument, in which case it
|
||||||
|
// behaves like a no-op.
|
||||||
|
void hash_map_free(hash_map_t *hash_map); |
||||||
|
|
||||||
|
// Returns true if the hash_map is empty (has no elements), false otherwise.
|
||||||
|
// Note that a NULL |hash_map| is not the same as an empty |hash_map|. This function
|
||||||
|
// does not accept a NULL |hash_map|.
|
||||||
|
//bool hash_map_is_empty(const hash_map_t *hash_map);
|
||||||
|
|
||||||
|
// Returns the number of elements in the hash map. This function does not accept a
|
||||||
|
// NULL |hash_map|.
|
||||||
|
//size_t hash_map_size(const hash_map_t *hash_map);
|
||||||
|
|
||||||
|
// Returns the number of buckets in the hash map. This function does not accept a
|
||||||
|
// NULL |hash_map|.
|
||||||
|
//size_t hash_map_num_buckets(const hash_map_t *hash_map);
|
||||||
|
|
||||||
|
// Returns true if the hash_map has a valid entry for the presented key.
|
||||||
|
// This function does not accept a NULL |hash_map|.
|
||||||
|
bool hash_map_has_key(const hash_map_t *hash_map, const void *key); |
||||||
|
|
||||||
|
// Returns the element indexed by |key| in the hash_map without removing it. |hash_map|
|
||||||
|
// may not be NULL. Returns NULL if no entry indexed by |key|.
|
||||||
|
void *hash_map_get(const hash_map_t *hash_map, const void *key); |
||||||
|
|
||||||
|
// Sets the value |data| indexed by |key| into the |hash_map|. Neither |data| nor
|
||||||
|
// |hash_map| may be NULL. This function does not make copies of |data| nor |key|
|
||||||
|
// so the pointers must remain valid at least until the element is removed from the
|
||||||
|
// hash_map or the hash_map is freed. Returns true if |data| could be set, false
|
||||||
|
// otherwise (e.g. out of memory).
|
||||||
|
bool hash_map_set(hash_map_t *hash_map, const void *key, void *data); |
||||||
|
|
||||||
|
// Removes data indexed by |key| from the hash_map. |hash_map| may not be NULL.
|
||||||
|
// If |key_fn| or |data_fn| functions were specified in |hash_map_new|, they
|
||||||
|
// will be called back with |key| or |data| respectively. This function returns true
|
||||||
|
// if |key| was found in the hash_map and removed, false otherwise.
|
||||||
|
bool hash_map_erase(hash_map_t *hash_map, const void *key); |
||||||
|
|
||||||
|
// Removes all elements in the hash_map. Calling this function will return the hash_map
|
||||||
|
// to the same state it was in after |hash_map_new|. |hash_map| may not be NULL.
|
||||||
|
void hash_map_clear(hash_map_t *hash_map); |
||||||
|
|
||||||
|
// Iterates through the entire |hash_map| and calls |callback| for each data
|
||||||
|
// element and passes through the |context| argument. If the hash_map is
|
||||||
|
// empty, |callback| will never be called. It is not safe to mutate the
|
||||||
|
// hash_map inside the callback. Neither |hash_map| nor |callback| may be NULL.
|
||||||
|
// If |callback| returns false, the iteration loop will immediately exit.
|
||||||
|
void hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context); |
||||||
|
|
||||||
|
#endif /* _HASH_MAP_H_ */ |
@ -0,0 +1,121 @@ |
|||||||
|
#ifndef _LIST_H_ |
||||||
|
#define _LIST_H_ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include <stddef.h> |
||||||
|
struct list_node_t; |
||||||
|
typedef struct list_node_t list_node_t; |
||||||
|
|
||||||
|
struct list_t; |
||||||
|
typedef struct list_t list_t; |
||||||
|
|
||||||
|
typedef void (*list_free_cb)(void *data); |
||||||
|
typedef bool (*list_iter_cb)(void *data, void *context); |
||||||
|
|
||||||
|
// Returns a new, empty list. Returns NULL if not enough memory could be allocated
|
||||||
|
// for the list structure. The returned list must be freed with |list_free|. The
|
||||||
|
// |callback| specifies a function to be called whenever a list element is removed
|
||||||
|
// from the list. It can be used to release resources held by the list element, e.g.
|
||||||
|
// memory or file descriptor. |callback| may be NULL if no cleanup is necessary on
|
||||||
|
// element removal.
|
||||||
|
list_t *list_new(list_free_cb callback); |
||||||
|
|
||||||
|
|
||||||
|
list_node_t *list_free_node(list_t *list, list_node_t *node); |
||||||
|
|
||||||
|
// similar with list_free_node, this function doesn't free the node data
|
||||||
|
list_node_t *list_delete_node(list_t *list, list_node_t *node); |
||||||
|
|
||||||
|
// Frees the list. This function accepts NULL as an argument, in which case it
|
||||||
|
// behaves like a no-op.
|
||||||
|
void list_free(list_t *list); |
||||||
|
|
||||||
|
// Returns true if |list| is empty (has no elements), false otherwise.
|
||||||
|
// |list| may not be NULL.
|
||||||
|
bool list_is_empty(const list_t *list); |
||||||
|
|
||||||
|
// Returns true if the list contains |data|, false otherwise.
|
||||||
|
// |list| may not be NULL.
|
||||||
|
bool list_contains(const list_t *list, const void *data); |
||||||
|
|
||||||
|
// Returns list_node which contains |data|, NULL otherwise.
|
||||||
|
// |list| may not be NULL.
|
||||||
|
list_node_t *list_get_node(const list_t *list, const void *data); |
||||||
|
|
||||||
|
// Returns the length of the |list|. |list| may not be NULL.
|
||||||
|
size_t list_length(const list_t *list); |
||||||
|
|
||||||
|
// Returns the first element in the list without removing it. |list| may not
|
||||||
|
// be NULL or empty.
|
||||||
|
void *list_front(const list_t *list); |
||||||
|
|
||||||
|
// Returns the last element in the list without removing it. |list| may not
|
||||||
|
// be NULL or empty.
|
||||||
|
void *list_back(const list_t *list); |
||||||
|
list_node_t *list_back_node(const list_t *list); |
||||||
|
|
||||||
|
// Inserts |data| after |prev_node| in |list|. |data|, |list|, and |prev_node|
|
||||||
|
// may not be NULL. This function does not make a copy of |data| so the pointer
|
||||||
|
// must remain valid at least until the element is removed from the list or the
|
||||||
|
// list is freed. Returns true if |data| could be inserted, false otherwise
|
||||||
|
// (e.g. out of memory).
|
||||||
|
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data); |
||||||
|
|
||||||
|
// Inserts |data| at the beginning of |list|. Neither |data| nor |list| may be NULL.
|
||||||
|
// This function does not make a copy of |data| so the pointer must remain valid
|
||||||
|
// at least until the element is removed from the list or the list is freed.
|
||||||
|
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
|
||||||
|
bool list_prepend(list_t *list, void *data); |
||||||
|
|
||||||
|
// Inserts |data| at the end of |list|. Neither |data| nor |list| may be NULL.
|
||||||
|
// This function does not make a copy of |data| so the pointer must remain valid
|
||||||
|
// at least until the element is removed from the list or the list is freed.
|
||||||
|
// Returns true if |data| could be inserted, false otherwise (e.g. out of memory).
|
||||||
|
bool list_append(list_t *list, void *data); |
||||||
|
|
||||||
|
// Removes |data| from the list. Neither |list| nor |data| may be NULL. If |data|
|
||||||
|
// is inserted multiple times in the list, this function will only remove the first
|
||||||
|
// instance. If a free function was specified in |list_new|, it will be called back
|
||||||
|
// with |data|. This function returns true if |data| was found in the list and removed,
|
||||||
|
// false otherwise.
|
||||||
|
//list_node_t list_remove_node(list_t *list, list_node_t *prev_node, list_node_t *node);
|
||||||
|
//list_node_t list_insert_node(list_t *list, list_node_t *prev_node, list_node_t *node);
|
||||||
|
|
||||||
|
bool list_remove(list_t *list, void *data); |
||||||
|
|
||||||
|
// similar with list_remove, but do not free the node data
|
||||||
|
bool list_delete(list_t *list, void *data); |
||||||
|
|
||||||
|
// Removes all elements in the list. Calling this function will return the list to the
|
||||||
|
// same state it was in after |list_new|. |list| may not be NULL.
|
||||||
|
void list_clear(list_t *list); |
||||||
|
|
||||||
|
// Iterates through the entire |list| and calls |callback| for each data element.
|
||||||
|
// If the list is empty, |callback| will never be called. It is safe to mutate the
|
||||||
|
// list inside the callback. If an element is added before the node being visited,
|
||||||
|
// there will be no callback for the newly-inserted node. Neither |list| nor
|
||||||
|
// |callback| may be NULL.
|
||||||
|
list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context); |
||||||
|
|
||||||
|
// Returns an iterator to the first element in |list|. |list| may not be NULL.
|
||||||
|
// The returned iterator is valid as long as it does not equal the value returned
|
||||||
|
// by |list_end|.
|
||||||
|
list_node_t *list_begin(const list_t *list); |
||||||
|
|
||||||
|
// Returns an iterator that points past the end of the list. In other words,
|
||||||
|
// this function returns the value of an invalid iterator for the given list.
|
||||||
|
// When an iterator has the same value as what's returned by this function, you
|
||||||
|
// may no longer call |list_next| with the iterator. |list| may not be NULL.
|
||||||
|
list_node_t *list_end(const list_t *list); |
||||||
|
|
||||||
|
// Given a valid iterator |node|, this function returns the next value for the
|
||||||
|
// iterator. If the returned value equals the value returned by |list_end|, the
|
||||||
|
// iterator has reached the end of the list and may no longer be used for any
|
||||||
|
// purpose.
|
||||||
|
list_node_t *list_next(const list_node_t *node); |
||||||
|
|
||||||
|
// Returns the value stored at the location pointed to by the iterator |node|.
|
||||||
|
// |node| must not equal the value returned by |list_end|.
|
||||||
|
void *list_node(const list_node_t *node); |
||||||
|
|
||||||
|
#endif /* _LIST_H_ */ |
@ -0,0 +1,52 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2015 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef __MUTEX_H__ |
||||||
|
#define __MUTEX_H__ |
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/task.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
#include "freertos/semphr.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
#define OSI_MUTEX_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT |
||||||
|
|
||||||
|
#define osi_mutex_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) |
||||||
|
#define osi_mutex_set_invalid( x ) ( ( *x ) = NULL ) |
||||||
|
|
||||||
|
typedef SemaphoreHandle_t osi_mutex_t; |
||||||
|
|
||||||
|
int osi_mutex_new(osi_mutex_t *mutex); |
||||||
|
|
||||||
|
int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout); |
||||||
|
|
||||||
|
void osi_mutex_unlock(osi_mutex_t *mutex); |
||||||
|
|
||||||
|
void osi_mutex_free(osi_mutex_t *mutex); |
||||||
|
|
||||||
|
/* Just for a global mutex */ |
||||||
|
int osi_mutex_global_init(void); |
||||||
|
|
||||||
|
void osi_mutex_global_deinit(void); |
||||||
|
|
||||||
|
void osi_mutex_global_lock(void); |
||||||
|
|
||||||
|
void osi_mutex_global_unlock(void); |
||||||
|
|
||||||
|
#endif /* __MUTEX_H__ */ |
@ -0,0 +1,16 @@ |
|||||||
|
|
||||||
|
#ifndef _OSI_H_ |
||||||
|
#define _OSI_H_ |
||||||
|
|
||||||
|
#include <stdbool.h> |
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
#define UNUSED_ATTR __attribute__((unused)) |
||||||
|
|
||||||
|
#define CONCAT(a, b) a##b |
||||||
|
#define COMPILE_ASSERT(x) |
||||||
|
|
||||||
|
int osi_init(void); |
||||||
|
void osi_deinit(void); |
||||||
|
|
||||||
|
#endif /*_OSI_H_*/ |
@ -0,0 +1,88 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _PKT_LIST_H_ |
||||||
|
#define _PKT_LIST_H_ |
||||||
|
|
||||||
|
#include "sys/queue.h" |
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
struct pkt_queue; |
||||||
|
|
||||||
|
typedef struct pkt_linked_item { |
||||||
|
STAILQ_ENTRY(pkt_linked_item) next; |
||||||
|
uint8_t data[]; |
||||||
|
} pkt_linked_item_t; |
||||||
|
|
||||||
|
#define BT_PKT_LINKED_HDR_SIZE (sizeof (pkt_linked_item_t)) |
||||||
|
|
||||||
|
typedef void (*pkt_queue_free_cb)(pkt_linked_item_t *item); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: create a pkt_queue instance. pkt_queue is a wrapper class of a FIFO implemented by single linked list. |
||||||
|
* The enqueue and dequeue operations of the FIFO are protected against race conditions of multiple tasks |
||||||
|
* return: NULL if not enough memory, otherwise a valid pointer |
||||||
|
*/ |
||||||
|
struct pkt_queue *pkt_queue_create(void); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: enqueue one item to the FIFO |
||||||
|
* param queue: pkt_queue instance created using pkt_queue_create |
||||||
|
* param item: the item to be enqueued to the FIFO |
||||||
|
* return: true if enqueued successfully, false when the arguments passed in are invalid |
||||||
|
*/ |
||||||
|
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: dequeue one item for the FIFO |
||||||
|
* param queue: pkt_queue instance created using pkt_queue_create |
||||||
|
* return: pointer of type pkt_linked_item_t dequeued, NULL if the queue is empty or upon exception |
||||||
|
*/ |
||||||
|
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: get the pointer of the first item from the FIFO but not get it dequeued |
||||||
|
* param queue: pkt_queue instance created using pkt_queue_create |
||||||
|
* return: pointer of the first item in the FIFO, NULL if the FIFO is empty |
||||||
|
*/ |
||||||
|
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: retrieve the number of items existing in the FIFO |
||||||
|
* param queue: pkt_queue instance created using pkt_queue_create |
||||||
|
* return: total number of items in the FIFO |
||||||
|
*/ |
||||||
|
size_t pkt_queue_length(const struct pkt_queue *queue); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: retrieve the status whether the FIFO is empty |
||||||
|
* param queue: pkt_queue instance created using pkt_queue_create |
||||||
|
* return: false if the FIFO is not empty, otherwise true |
||||||
|
*/ |
||||||
|
bool pkt_queue_is_empty(const struct pkt_queue *queue); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: delete the item in the FIFO one by one |
||||||
|
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default |
||||||
|
*/ |
||||||
|
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: delete the items in the FIFO and then destroy the pkt_queue instance. |
||||||
|
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default |
||||||
|
*/ |
||||||
|
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb); |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,43 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2015 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#ifndef __SEMAPHORE_H__ |
||||||
|
#define __SEMAPHORE_H__ |
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/task.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
#include "freertos/semphr.h" |
||||||
|
|
||||||
|
#define OSI_SEM_MAX_TIMEOUT 0xffffffffUL |
||||||
|
|
||||||
|
typedef SemaphoreHandle_t osi_sem_t; |
||||||
|
|
||||||
|
#define osi_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) |
||||||
|
#define osi_sem_set_invalid( x ) ( ( *x ) = NULL ) |
||||||
|
|
||||||
|
int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count); |
||||||
|
|
||||||
|
void osi_sem_free(osi_sem_t *sem); |
||||||
|
|
||||||
|
int osi_sem_take(osi_sem_t *sem, uint32_t timeout); |
||||||
|
|
||||||
|
void osi_sem_give(osi_sem_t *sem); |
||||||
|
|
||||||
|
|
||||||
|
#endif /* __SEMAPHORE_H__ */ |
@ -0,0 +1,120 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __THREAD_H__ |
||||||
|
#define __THREAD_H__ |
||||||
|
|
||||||
|
#include "freertos/FreeRTOSConfig.h" |
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
#include "freertos/task.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
#include "esp_task.h" |
||||||
|
#include "bt_common.h" |
||||||
|
|
||||||
|
#define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT |
||||||
|
|
||||||
|
struct osi_thread; |
||||||
|
struct osi_event; |
||||||
|
|
||||||
|
typedef struct osi_thread osi_thread_t; |
||||||
|
|
||||||
|
typedef void (*osi_thread_func_t)(void *context); |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
OSI_THREAD_CORE_0 = 0, |
||||||
|
OSI_THREAD_CORE_1, |
||||||
|
OSI_THREAD_CORE_AFFINITY, |
||||||
|
} osi_thread_core_t; |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Create a thread or task |
||||||
|
* param name: thread name |
||||||
|
* param stack_size: thread stack size |
||||||
|
* param priority: thread priority |
||||||
|
* param core: the CPU core which this thread run, OSI_THREAD_CORE_AFFINITY means unspecific CPU core |
||||||
|
* param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index |
||||||
|
* return : if create successfully, return thread handler; otherwise return NULL. |
||||||
|
*/ |
||||||
|
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Destroy a thread or task |
||||||
|
* param thread: point of thread handler |
||||||
|
*/ |
||||||
|
void osi_thread_free(osi_thread_t *thread); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Post an msg to a thread and told the thread call the function |
||||||
|
* param thread: point of thread handler |
||||||
|
* param func: callback function that called by target thread |
||||||
|
* param context: argument of callback function |
||||||
|
* param queue_idx: the queue which the msg send to |
||||||
|
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond |
||||||
|
* return : if post successfully, return true, otherwise return false |
||||||
|
*/ |
||||||
|
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Set the priority of thread |
||||||
|
* param thread: point of thread handler |
||||||
|
* param priority: priority |
||||||
|
* return : if set successfully, return true, otherwise return false |
||||||
|
*/ |
||||||
|
bool osi_thread_set_priority(osi_thread_t *thread, int priority); |
||||||
|
|
||||||
|
/* brief: Get thread name
|
||||||
|
* param thread: point of thread handler |
||||||
|
* return: constant point of thread name |
||||||
|
*/ |
||||||
|
const char *osi_thread_name(osi_thread_t *thread); |
||||||
|
|
||||||
|
/* brief: Get the size of the specified queue
|
||||||
|
* param thread: point of thread handler |
||||||
|
* param wq_idx: the queue index of the thread |
||||||
|
* return: queue size |
||||||
|
*/ |
||||||
|
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Create an osi_event struct and register the handler function and its argument |
||||||
|
* An osi_event is a kind of work that can be posted to the workqueue of osi_thread to process, |
||||||
|
* but the work can have at most one instance the thread workqueue before it is processed. This |
||||||
|
* allows the "single post, multiple data processing" jobs. |
||||||
|
* param func: the handler to process the job |
||||||
|
* param context: the argument to be passed to the handler function when the job is being processed |
||||||
|
* return: NULL if no memory, otherwise a valid struct pointer |
||||||
|
*/ |
||||||
|
struct osi_event *osi_event_create(osi_thread_func_t func, void *context); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Bind an osi_event to a specific work queue for an osi_thread. |
||||||
|
* After binding is completed, a function call of API osi_thread_post_event will send a work |
||||||
|
* to the workqueue of the thread, with specified queue index. |
||||||
|
* param func: event: the pointer to osi_event that is created using osi_event_create |
||||||
|
* param thread: the pointer to osi_thread that is created using osi_thread_create |
||||||
|
* param queue_idx: the index of the workqueue of the specified osi_thread, with range starting from 0 to work_queue_num - 1 |
||||||
|
* return: true if osi_event binds to the thread's workqueue successfully, otherwise false |
||||||
|
*/ |
||||||
|
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: Destroy the osi_event struct created by osi_event_create and free the allocated memory |
||||||
|
* param event: the pointer to osi_event |
||||||
|
*/ |
||||||
|
void osi_event_delete(struct osi_event* event); |
||||||
|
|
||||||
|
/*
|
||||||
|
* brief: try sending a work to the binded thread's workqueue, so that it can be handled by the worker thread |
||||||
|
* param event: pointer to osi_event, created by osi_event_create |
||||||
|
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond |
||||||
|
* return: true if the message is enqueued to the thread workqueue, otherwise failed |
||||||
|
* note: if the return value of function is false, it is the case that the workqueue of the thread is full, and users |
||||||
|
* are expected to post the event sometime later to get the work handled. |
||||||
|
*/ |
||||||
|
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout); |
||||||
|
|
||||||
|
#endif /* __THREAD_H__ */ |
@ -0,0 +1,312 @@ |
|||||||
|
|
||||||
|
#include "bt_common.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/list.h" |
||||||
|
#include "osi/osi.h" |
||||||
|
|
||||||
|
struct list_node_t { |
||||||
|
struct list_node_t *next; |
||||||
|
void *data; |
||||||
|
}; |
||||||
|
|
||||||
|
typedef struct list_t { |
||||||
|
list_node_t *head; |
||||||
|
list_node_t *tail; |
||||||
|
size_t length; |
||||||
|
list_free_cb free_cb; |
||||||
|
} list_t; |
||||||
|
|
||||||
|
//static list_node_t *list_free_node_(list_t *list, list_node_t *node);
|
||||||
|
|
||||||
|
// Hidden constructor, only to be used by the hash map for the allocation tracker.
|
||||||
|
// Behaves the same as |list_new|, except you get to specify the allocator.
|
||||||
|
list_t *list_new_internal(list_free_cb callback) |
||||||
|
{ |
||||||
|
list_t *list = (list_t *) osi_calloc(sizeof(list_t)); |
||||||
|
if (!list) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
list->head = list->tail = NULL; |
||||||
|
list->length = 0; |
||||||
|
list->free_cb = callback; |
||||||
|
return list; |
||||||
|
} |
||||||
|
|
||||||
|
list_t *list_new(list_free_cb callback) |
||||||
|
{ |
||||||
|
return list_new_internal(callback); |
||||||
|
} |
||||||
|
|
||||||
|
void list_free(list_t *list) |
||||||
|
{ |
||||||
|
if (!list) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
list_clear(list); |
||||||
|
osi_free(list); |
||||||
|
} |
||||||
|
|
||||||
|
bool list_is_empty(const list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
return (list->length == 0); |
||||||
|
} |
||||||
|
|
||||||
|
bool list_contains(const list_t *list, const void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
|
||||||
|
for (const list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) { |
||||||
|
if (list_node(node) == data) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_get_node(const list_t *list, const void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
list_node_t *p_node_ret = NULL; |
||||||
|
for (list_node_t *node = list_begin(list); node != list_end(list); node = list_next(node)) { |
||||||
|
if (list_node(node) == data) { |
||||||
|
p_node_ret = node; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return p_node_ret; |
||||||
|
} |
||||||
|
|
||||||
|
size_t list_length(const list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
return list->length; |
||||||
|
} |
||||||
|
|
||||||
|
void *list_front(const list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(!list_is_empty(list)); |
||||||
|
|
||||||
|
return list->head->data; |
||||||
|
} |
||||||
|
|
||||||
|
void *list_back(const list_t *list) { |
||||||
|
assert(list != NULL); |
||||||
|
assert(!list_is_empty(list)); |
||||||
|
|
||||||
|
return list->tail->data; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_back_node(const list_t *list) { |
||||||
|
assert(list != NULL); |
||||||
|
assert(!list_is_empty(list)); |
||||||
|
|
||||||
|
return list->tail; |
||||||
|
} |
||||||
|
|
||||||
|
bool list_insert_after(list_t *list, list_node_t *prev_node, void *data) { |
||||||
|
assert(list != NULL); |
||||||
|
assert(prev_node != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t)); |
||||||
|
if (!node) { |
||||||
|
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ ); |
||||||
|
return false; |
||||||
|
} |
||||||
|
node->next = prev_node->next; |
||||||
|
node->data = data; |
||||||
|
prev_node->next = node; |
||||||
|
if (list->tail == prev_node) { |
||||||
|
list->tail = node; |
||||||
|
} |
||||||
|
++list->length; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool list_prepend(list_t *list, void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t)); |
||||||
|
if (!node) { |
||||||
|
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ ); |
||||||
|
return false; |
||||||
|
} |
||||||
|
node->next = list->head; |
||||||
|
node->data = data; |
||||||
|
list->head = node; |
||||||
|
if (list->tail == NULL) { |
||||||
|
list->tail = list->head; |
||||||
|
} |
||||||
|
++list->length; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool list_append(list_t *list, void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
list_node_t *node = (list_node_t *)osi_calloc(sizeof(list_node_t)); |
||||||
|
if (!node) { |
||||||
|
OSI_TRACE_ERROR("%s osi_calloc failed.\n", __FUNCTION__ ); |
||||||
|
return false; |
||||||
|
} |
||||||
|
node->next = NULL; |
||||||
|
node->data = data; |
||||||
|
if (list->tail == NULL) { |
||||||
|
list->head = node; |
||||||
|
list->tail = node; |
||||||
|
} else { |
||||||
|
list->tail->next = node; |
||||||
|
list->tail = node; |
||||||
|
} |
||||||
|
++list->length; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool list_remove(list_t *list, void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
|
||||||
|
if (list_is_empty(list)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (list->head->data == data) { |
||||||
|
list_node_t *next = list_free_node(list, list->head); |
||||||
|
if (list->tail == list->head) { |
||||||
|
list->tail = next; |
||||||
|
} |
||||||
|
list->head = next; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next) |
||||||
|
if (node->data == data) { |
||||||
|
prev->next = list_free_node(list, node); |
||||||
|
if (list->tail == node) { |
||||||
|
list->tail = prev; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
bool list_delete(list_t *list, void *data) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(data != NULL); |
||||||
|
|
||||||
|
if (list_is_empty(list)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (list->head->data == data) { |
||||||
|
list_node_t *next = list_delete_node(list, list->head); |
||||||
|
if (list->tail == list->head) { |
||||||
|
list->tail = next; |
||||||
|
} |
||||||
|
list->head = next; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next) |
||||||
|
if (node->data == data) { |
||||||
|
prev->next = list_delete_node(list, node); |
||||||
|
if (list->tail == node) { |
||||||
|
list->tail = prev; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
void list_clear(list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
for (list_node_t *node = list->head; node; ) { |
||||||
|
node = list_free_node(list, node); |
||||||
|
} |
||||||
|
list->head = NULL; |
||||||
|
list->tail = NULL; |
||||||
|
list->length = 0; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_foreach(const list_t *list, list_iter_cb callback, void *context) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(callback != NULL); |
||||||
|
|
||||||
|
for (list_node_t *node = list->head; node; ) { |
||||||
|
list_node_t *next = node->next; |
||||||
|
if (!callback(node->data, context)) { |
||||||
|
return node; |
||||||
|
} |
||||||
|
node = next; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_begin(const list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
return list->head; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_end(UNUSED_ATTR const list_t *list) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_next(const list_node_t *node) |
||||||
|
{ |
||||||
|
assert(node != NULL); |
||||||
|
return node->next; |
||||||
|
} |
||||||
|
|
||||||
|
void *list_node(const list_node_t *node) |
||||||
|
{ |
||||||
|
assert(node != NULL); |
||||||
|
return node->data; |
||||||
|
} |
||||||
|
|
||||||
|
list_node_t *list_free_node(list_t *list, list_node_t *node) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(node != NULL); |
||||||
|
|
||||||
|
list_node_t *next = node->next; |
||||||
|
|
||||||
|
if (list->free_cb) { |
||||||
|
list->free_cb(node->data); |
||||||
|
} |
||||||
|
osi_free(node); |
||||||
|
--list->length; |
||||||
|
|
||||||
|
return next; |
||||||
|
} |
||||||
|
|
||||||
|
// remove the element from list but do not free the node data
|
||||||
|
list_node_t *list_delete_node(list_t *list, list_node_t *node) |
||||||
|
{ |
||||||
|
assert(list != NULL); |
||||||
|
assert(node != NULL); |
||||||
|
|
||||||
|
list_node_t *next = node->next; |
||||||
|
|
||||||
|
osi_free(node); |
||||||
|
--list->length; |
||||||
|
|
||||||
|
return next; |
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2015 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include "osi/mutex.h" |
||||||
|
|
||||||
|
|
||||||
|
/* static section */ |
||||||
|
static osi_mutex_t gl_mutex; /* Recursive Type */ |
||||||
|
|
||||||
|
|
||||||
|
/** Create a new mutex
|
||||||
|
* @param mutex pointer to the mutex to create |
||||||
|
* @return a new mutex */ |
||||||
|
int osi_mutex_new(osi_mutex_t *mutex) |
||||||
|
{ |
||||||
|
int xReturn = -1; |
||||||
|
|
||||||
|
*mutex = xSemaphoreCreateMutex(); |
||||||
|
|
||||||
|
if (*mutex != NULL) { |
||||||
|
xReturn = 0; |
||||||
|
} |
||||||
|
|
||||||
|
return xReturn; |
||||||
|
} |
||||||
|
|
||||||
|
/** Lock a mutex
|
||||||
|
* @param mutex the mutex to lock */ |
||||||
|
int osi_mutex_lock(osi_mutex_t *mutex, uint32_t timeout) |
||||||
|
{ |
||||||
|
int ret = 0; |
||||||
|
|
||||||
|
if (timeout == OSI_MUTEX_MAX_TIMEOUT) { |
||||||
|
if (xSemaphoreTake(*mutex, portMAX_DELAY) != pdTRUE) { |
||||||
|
ret = -1; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (xSemaphoreTake(*mutex, timeout / portTICK_PERIOD_MS) != pdTRUE) { |
||||||
|
ret = -2; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
/** Unlock a mutex
|
||||||
|
* @param mutex the mutex to unlock */ |
||||||
|
void osi_mutex_unlock(osi_mutex_t *mutex) |
||||||
|
{ |
||||||
|
xSemaphoreGive(*mutex); |
||||||
|
} |
||||||
|
|
||||||
|
/** Delete a semaphore
|
||||||
|
* @param mutex the mutex to delete */ |
||||||
|
void osi_mutex_free(osi_mutex_t *mutex) |
||||||
|
{ |
||||||
|
vSemaphoreDelete(*mutex); |
||||||
|
*mutex = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
int osi_mutex_global_init(void) |
||||||
|
{ |
||||||
|
gl_mutex = xSemaphoreCreateRecursiveMutex(); |
||||||
|
if (gl_mutex == NULL) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mutex_global_deinit(void) |
||||||
|
{ |
||||||
|
vSemaphoreDelete(gl_mutex); |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mutex_global_lock(void) |
||||||
|
{ |
||||||
|
xSemaphoreTakeRecursive(gl_mutex, portMAX_DELAY); |
||||||
|
} |
||||||
|
|
||||||
|
void osi_mutex_global_unlock(void) |
||||||
|
{ |
||||||
|
xSemaphoreGiveRecursive(gl_mutex); |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#include "osi/osi.h" |
||||||
|
#include "osi/mutex.h" |
||||||
|
|
||||||
|
int osi_init(void) |
||||||
|
{ |
||||||
|
int ret = 0; |
||||||
|
|
||||||
|
if (osi_mutex_global_init() != 0) { |
||||||
|
ret = -1; |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_deinit(void) |
||||||
|
{ |
||||||
|
osi_mutex_global_deinit(); |
||||||
|
} |
@ -0,0 +1,144 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "osi/pkt_queue.h" |
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "osi/mutex.h" |
||||||
|
|
||||||
|
|
||||||
|
STAILQ_HEAD(pkt_queue_header, pkt_linked_item); |
||||||
|
|
||||||
|
struct pkt_queue { |
||||||
|
osi_mutex_t lock; |
||||||
|
size_t length; |
||||||
|
struct pkt_queue_header header; |
||||||
|
} pkt_queue_t; |
||||||
|
|
||||||
|
struct pkt_queue *pkt_queue_create(void) |
||||||
|
{ |
||||||
|
struct pkt_queue *queue = calloc(1, sizeof(struct pkt_queue)); |
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
if (osi_mutex_new(&queue->lock) != 0) { |
||||||
|
osi_free(queue); |
||||||
|
} |
||||||
|
struct pkt_queue_header *p = &queue->header; |
||||||
|
STAILQ_INIT(p); |
||||||
|
|
||||||
|
return queue; |
||||||
|
} |
||||||
|
|
||||||
|
static void pkt_queue_cleanup(struct pkt_queue *queue, pkt_queue_free_cb free_cb) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
struct pkt_queue_header *header = &queue->header; |
||||||
|
pkt_linked_item_t *item = STAILQ_FIRST(header); |
||||||
|
pkt_linked_item_t *tmp; |
||||||
|
|
||||||
|
pkt_queue_free_cb free_func = (free_cb != NULL) ? free_cb : (pkt_queue_free_cb)osi_free_func; |
||||||
|
|
||||||
|
while (item != NULL) { |
||||||
|
tmp = STAILQ_NEXT(item, next); |
||||||
|
free_func(item); |
||||||
|
item = tmp; |
||||||
|
queue->length--; |
||||||
|
} |
||||||
|
STAILQ_INIT(header); |
||||||
|
queue->length = 0; |
||||||
|
} |
||||||
|
|
||||||
|
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
pkt_queue_cleanup(queue, free_cb); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
} |
||||||
|
|
||||||
|
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
pkt_queue_cleanup(queue, free_cb); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
osi_mutex_free(&queue->lock); |
||||||
|
osi_free(queue); |
||||||
|
} |
||||||
|
|
||||||
|
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL || queue->length == 0) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
struct pkt_linked_item *item; |
||||||
|
struct pkt_queue_header *header; |
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
header = &queue->header; |
||||||
|
item = STAILQ_FIRST(header); |
||||||
|
if (item != NULL) { |
||||||
|
STAILQ_REMOVE_HEAD(header, next); |
||||||
|
if (queue->length > 0) { |
||||||
|
queue->length--; |
||||||
|
} |
||||||
|
} |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return item; |
||||||
|
} |
||||||
|
|
||||||
|
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item) |
||||||
|
{ |
||||||
|
if (queue == NULL || item == NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
struct pkt_queue_header *header; |
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
header = &queue->header; |
||||||
|
STAILQ_INSERT_TAIL(header, item, next); |
||||||
|
queue->length++; |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
size_t pkt_queue_length(const struct pkt_queue *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return queue->length; |
||||||
|
} |
||||||
|
|
||||||
|
bool pkt_queue_is_empty(const struct pkt_queue *queue) |
||||||
|
{ |
||||||
|
return pkt_queue_length(queue) == 0; |
||||||
|
} |
||||||
|
|
||||||
|
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue) |
||||||
|
{ |
||||||
|
if (queue == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
struct pkt_queue_header *header = &queue->header; |
||||||
|
pkt_linked_item_t *item; |
||||||
|
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
item = STAILQ_FIRST(header); |
||||||
|
osi_mutex_unlock(&queue->lock); |
||||||
|
|
||||||
|
return item; |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2015 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
|
||||||
|
#include "osi/semaphore.h" |
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/ |
||||||
|
// Creates and returns a new semaphore. The "init_count" argument specifies
|
||||||
|
// the initial state of the semaphore, "max_count" specifies the maximum value
|
||||||
|
// that can be reached.
|
||||||
|
int osi_sem_new(osi_sem_t *sem, uint32_t max_count, uint32_t init_count) |
||||||
|
{ |
||||||
|
int ret = -1; |
||||||
|
|
||||||
|
if (sem) { |
||||||
|
*sem = xSemaphoreCreateCounting(max_count, init_count); |
||||||
|
if ((*sem) != NULL) { |
||||||
|
ret = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/ |
||||||
|
// Give a semaphore
|
||||||
|
void osi_sem_give(osi_sem_t *sem) |
||||||
|
{ |
||||||
|
xSemaphoreGive(*sem); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
Blocks the thread while waiting for the semaphore to be |
||||||
|
signaled. If the "timeout" argument is non-zero, the thread should |
||||||
|
only be blocked for the specified time (measured in |
||||||
|
milliseconds). |
||||||
|
|
||||||
|
*/ |
||||||
|
int |
||||||
|
osi_sem_take(osi_sem_t *sem, uint32_t timeout) |
||||||
|
{ |
||||||
|
int ret = 0; |
||||||
|
|
||||||
|
if (timeout == OSI_SEM_MAX_TIMEOUT) { |
||||||
|
if (xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE) { |
||||||
|
ret = -1; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (xSemaphoreTake(*sem, timeout / portTICK_PERIOD_MS) != pdTRUE) { |
||||||
|
ret = -2; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
// Deallocates a semaphore
|
||||||
|
void osi_sem_free(osi_sem_t *sem) |
||||||
|
{ |
||||||
|
vSemaphoreDelete(*sem); |
||||||
|
*sem = NULL; |
||||||
|
} |
@ -0,0 +1,453 @@ |
|||||||
|
/******************************************************************************
|
||||||
|
* |
||||||
|
* Copyright (C) 2014 Google, Inc. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at: |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
******************************************************************************/ |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "osi/allocator.h" |
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
#include "osi/semaphore.h" |
||||||
|
#include "osi/thread.h" |
||||||
|
#include "osi/mutex.h" |
||||||
|
|
||||||
|
struct work_item { |
||||||
|
osi_thread_func_t func; |
||||||
|
void *context; |
||||||
|
}; |
||||||
|
|
||||||
|
struct work_queue { |
||||||
|
QueueHandle_t queue; |
||||||
|
size_t capacity; |
||||||
|
}; |
||||||
|
|
||||||
|
struct osi_thread { |
||||||
|
TaskHandle_t thread_handle; /*!< Store the thread object */ |
||||||
|
int thread_id; /*!< May for some OS, such as Linux */ |
||||||
|
bool stop; |
||||||
|
uint8_t work_queue_num; /*!< Work queue number */ |
||||||
|
struct work_queue **work_queues; /*!< Point to queue array, and the priority inverse array index */ |
||||||
|
osi_sem_t work_sem; |
||||||
|
osi_sem_t stop_sem; |
||||||
|
}; |
||||||
|
|
||||||
|
struct osi_thread_start_arg { |
||||||
|
osi_thread_t *thread; |
||||||
|
osi_sem_t start_sem; |
||||||
|
int error; |
||||||
|
}; |
||||||
|
|
||||||
|
struct osi_event { |
||||||
|
struct work_item item; |
||||||
|
osi_mutex_t lock; |
||||||
|
uint16_t is_queued; |
||||||
|
uint16_t queue_idx; |
||||||
|
osi_thread_t *thread; |
||||||
|
}; |
||||||
|
|
||||||
|
static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100; |
||||||
|
|
||||||
|
static struct work_queue *osi_work_queue_create(size_t capacity) |
||||||
|
{ |
||||||
|
if (capacity == 0) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
struct work_queue *wq = (struct work_queue *)osi_malloc(sizeof(struct work_queue)); |
||||||
|
if (wq != NULL) { |
||||||
|
wq->queue = xQueueCreate(capacity, sizeof(struct work_item)); |
||||||
|
if (wq->queue != 0) { |
||||||
|
wq->capacity = capacity; |
||||||
|
return wq; |
||||||
|
} else { |
||||||
|
osi_free(wq); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void osi_work_queue_delete(struct work_queue *wq) |
||||||
|
{ |
||||||
|
if (wq != NULL) { |
||||||
|
if (wq->queue != 0) { |
||||||
|
vQueueDelete(wq->queue); |
||||||
|
} |
||||||
|
wq->queue = 0; |
||||||
|
wq->capacity = 0; |
||||||
|
osi_free(wq); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
static bool osi_thead_work_queue_get(struct work_queue *wq, struct work_item *item) |
||||||
|
{ |
||||||
|
assert (wq != NULL); |
||||||
|
assert (wq->queue != 0); |
||||||
|
assert (item != NULL); |
||||||
|
|
||||||
|
if (pdTRUE == xQueueReceive(wq->queue, item, 0)) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static bool osi_thead_work_queue_put(struct work_queue *wq, const struct work_item *item, uint32_t timeout) |
||||||
|
{ |
||||||
|
assert (wq != NULL); |
||||||
|
assert (wq->queue != 0); |
||||||
|
assert (item != NULL); |
||||||
|
|
||||||
|
bool ret = true; |
||||||
|
if (timeout == OSI_SEM_MAX_TIMEOUT) { |
||||||
|
if (xQueueSend(wq->queue, item, portMAX_DELAY) != pdTRUE) { |
||||||
|
ret = false; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (xQueueSend(wq->queue, item, timeout / portTICK_PERIOD_MS) != pdTRUE) { |
||||||
|
ret = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
static size_t osi_thead_work_queue_len(struct work_queue *wq) |
||||||
|
{ |
||||||
|
assert (wq != NULL); |
||||||
|
assert (wq->queue != 0); |
||||||
|
assert (wq->capacity != 0); |
||||||
|
|
||||||
|
size_t available_spaces = (size_t)uxQueueSpacesAvailable(wq->queue); |
||||||
|
|
||||||
|
if (available_spaces <= wq->capacity) { |
||||||
|
return wq->capacity - available_spaces; |
||||||
|
} else { |
||||||
|
assert (0); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static void osi_thread_run(void *arg) |
||||||
|
{ |
||||||
|
struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg; |
||||||
|
osi_thread_t *thread = start->thread; |
||||||
|
|
||||||
|
osi_sem_give(&start->start_sem); |
||||||
|
|
||||||
|
while (1) { |
||||||
|
int idx = 0; |
||||||
|
|
||||||
|
osi_sem_take(&thread->work_sem, OSI_SEM_MAX_TIMEOUT); |
||||||
|
|
||||||
|
if (thread->stop) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
struct work_item item; |
||||||
|
while (!thread->stop && idx < thread->work_queue_num) { |
||||||
|
if (osi_thead_work_queue_get(thread->work_queues[idx], &item) == true) { |
||||||
|
item.func(item.context); |
||||||
|
idx = 0; |
||||||
|
continue; |
||||||
|
} else { |
||||||
|
idx++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
thread->thread_handle = NULL; |
||||||
|
osi_sem_give(&thread->stop_sem); |
||||||
|
|
||||||
|
vTaskDelete(NULL); |
||||||
|
} |
||||||
|
|
||||||
|
static int osi_thread_join(osi_thread_t *thread, uint32_t wait_ms) |
||||||
|
{ |
||||||
|
assert(thread != NULL); |
||||||
|
return osi_sem_take(&thread->stop_sem, wait_ms); |
||||||
|
} |
||||||
|
|
||||||
|
static void osi_thread_stop(osi_thread_t *thread) |
||||||
|
{ |
||||||
|
int ret; |
||||||
|
|
||||||
|
assert(thread != NULL); |
||||||
|
|
||||||
|
//stop the thread
|
||||||
|
thread->stop = true; |
||||||
|
osi_sem_give(&thread->work_sem); |
||||||
|
|
||||||
|
//join
|
||||||
|
ret = osi_thread_join(thread, 1000); //wait 1000ms
|
||||||
|
|
||||||
|
//if join failed, delete the task here
|
||||||
|
if (ret != 0 && thread->thread_handle) { |
||||||
|
vTaskDelete(thread->thread_handle); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
|
||||||
|
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]) |
||||||
|
{ |
||||||
|
int ret; |
||||||
|
struct osi_thread_start_arg start_arg = {0}; |
||||||
|
|
||||||
|
if (stack_size <= 0 || |
||||||
|
core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY || |
||||||
|
work_queue_num <= 0 || work_queue_len == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
osi_thread_t *thread = (osi_thread_t *)osi_calloc(sizeof(osi_thread_t)); |
||||||
|
if (thread == NULL) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
|
||||||
|
thread->stop = false; |
||||||
|
thread->work_queues = (struct work_queue **)osi_calloc(sizeof(struct work_queue *) * work_queue_num); |
||||||
|
if (thread->work_queues == NULL) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
thread->work_queue_num = work_queue_num; |
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) { |
||||||
|
size_t queue_len = work_queue_len[i] ? work_queue_len[i] : DEFAULT_WORK_QUEUE_CAPACITY; |
||||||
|
thread->work_queues[i] = osi_work_queue_create(queue_len); |
||||||
|
if (thread->work_queues[i] == NULL) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ret = osi_sem_new(&thread->work_sem, 1, 0); |
||||||
|
if (ret != 0) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
|
||||||
|
ret = osi_sem_new(&thread->stop_sem, 1, 0); |
||||||
|
if (ret != 0) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
|
||||||
|
start_arg.thread = thread; |
||||||
|
ret = osi_sem_new(&start_arg.start_sem, 1, 0); |
||||||
|
if (ret != 0) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
|
||||||
|
if (xTaskCreatePinnedToCore(osi_thread_run, name, stack_size, &start_arg, priority, &thread->thread_handle, core) != pdPASS) { |
||||||
|
goto _err; |
||||||
|
} |
||||||
|
|
||||||
|
osi_sem_take(&start_arg.start_sem, OSI_SEM_MAX_TIMEOUT); |
||||||
|
osi_sem_free(&start_arg.start_sem); |
||||||
|
|
||||||
|
return thread; |
||||||
|
|
||||||
|
_err: |
||||||
|
|
||||||
|
if (thread) { |
||||||
|
if (start_arg.start_sem) { |
||||||
|
osi_sem_free(&start_arg.start_sem); |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->thread_handle) { |
||||||
|
vTaskDelete(thread->thread_handle); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) { |
||||||
|
if (thread->work_queues[i]) { |
||||||
|
osi_work_queue_delete(thread->work_queues[i]); |
||||||
|
} |
||||||
|
thread->work_queues[i] = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->work_queues) { |
||||||
|
osi_free(thread->work_queues); |
||||||
|
thread->work_queues = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->work_sem) { |
||||||
|
osi_sem_free(&thread->work_sem); |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->stop_sem) { |
||||||
|
osi_sem_free(&thread->stop_sem); |
||||||
|
} |
||||||
|
|
||||||
|
osi_free(thread); |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_thread_free(osi_thread_t *thread) |
||||||
|
{ |
||||||
|
if (!thread) |
||||||
|
return; |
||||||
|
|
||||||
|
osi_thread_stop(thread); |
||||||
|
|
||||||
|
for (int i = 0; i < thread->work_queue_num; i++) { |
||||||
|
if (thread->work_queues[i]) { |
||||||
|
osi_work_queue_delete(thread->work_queues[i]); |
||||||
|
thread->work_queues[i] = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->work_queues) { |
||||||
|
osi_free(thread->work_queues); |
||||||
|
thread->work_queues = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->work_sem) { |
||||||
|
osi_sem_free(&thread->work_sem); |
||||||
|
} |
||||||
|
|
||||||
|
if (thread->stop_sem) { |
||||||
|
osi_sem_free(&thread->stop_sem); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
osi_free(thread); |
||||||
|
} |
||||||
|
|
||||||
|
bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context, int queue_idx, uint32_t timeout) |
||||||
|
{ |
||||||
|
assert(thread != NULL); |
||||||
|
assert(func != NULL); |
||||||
|
|
||||||
|
if (queue_idx >= thread->work_queue_num) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
struct work_item item; |
||||||
|
|
||||||
|
item.func = func; |
||||||
|
item.context = context; |
||||||
|
|
||||||
|
if (osi_thead_work_queue_put(thread->work_queues[queue_idx], &item, timeout) == false) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
osi_sem_give(&thread->work_sem); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool osi_thread_set_priority(osi_thread_t *thread, int priority) |
||||||
|
{ |
||||||
|
assert(thread != NULL); |
||||||
|
|
||||||
|
vTaskPrioritySet(thread->thread_handle, priority); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
const char *osi_thread_name(osi_thread_t *thread) |
||||||
|
{ |
||||||
|
assert(thread != NULL); |
||||||
|
|
||||||
|
return pcTaskGetName(thread->thread_handle); |
||||||
|
} |
||||||
|
|
||||||
|
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx) |
||||||
|
{ |
||||||
|
if (wq_idx < 0 || wq_idx >= thread->work_queue_num) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
return (int)(osi_thead_work_queue_len(thread->work_queues[wq_idx])); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
struct osi_event *osi_event_create(osi_thread_func_t func, void *context) |
||||||
|
{ |
||||||
|
struct osi_event *event = osi_calloc(sizeof(struct osi_event)); |
||||||
|
if (event != NULL) { |
||||||
|
if (osi_mutex_new(&event->lock) == 0) { |
||||||
|
event->item.func = func; |
||||||
|
event->item.context = context; |
||||||
|
return event; |
||||||
|
} |
||||||
|
osi_free(event); |
||||||
|
} |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void osi_event_delete(struct osi_event* event) |
||||||
|
{ |
||||||
|
if (event != NULL) { |
||||||
|
osi_mutex_free(&event->lock); |
||||||
|
memset(event, 0, sizeof(struct osi_event)); |
||||||
|
osi_free(event); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx) |
||||||
|
{ |
||||||
|
if (event == NULL || event->thread != NULL) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (thread == NULL || queue_idx >= thread->work_queue_num) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
event->thread = thread; |
||||||
|
event->queue_idx = queue_idx; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
static void osi_thread_generic_event_handler(void *context) |
||||||
|
{ |
||||||
|
struct osi_event *event = (struct osi_event *)context; |
||||||
|
if (event != NULL && event->item.func != NULL) { |
||||||
|
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
event->is_queued = 0; |
||||||
|
osi_mutex_unlock(&event->lock); |
||||||
|
event->item.func(event->item.context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout) |
||||||
|
{ |
||||||
|
assert(event != NULL && event->thread != NULL); |
||||||
|
assert(event->queue_idx >= 0 && event->queue_idx < event->thread->work_queue_num); |
||||||
|
bool ret = false; |
||||||
|
if (event->is_queued == 0) { |
||||||
|
uint16_t acquire_cnt = 0; |
||||||
|
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
event->is_queued += 1; |
||||||
|
acquire_cnt = event->is_queued; |
||||||
|
osi_mutex_unlock(&event->lock); |
||||||
|
|
||||||
|
if (acquire_cnt == 1) { |
||||||
|
ret = osi_thread_post(event->thread, osi_thread_generic_event_handler, event, event->queue_idx, timeout); |
||||||
|
if (!ret) { |
||||||
|
// clear "is_queued" when post failure, to allow for following event posts
|
||||||
|
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT); |
||||||
|
event->is_queued = 0; |
||||||
|
osi_mutex_unlock(&event->lock); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
@ -0,0 +1,446 @@ |
|||||||
|
choice BTDM_CTRL_MODE |
||||||
|
prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)" |
||||||
|
help |
||||||
|
Specify the bluetooth controller mode (BR/EDR, BLE or dual mode). |
||||||
|
|
||||||
|
config BTDM_CTRL_MODE_BLE_ONLY |
||||||
|
bool "BLE Only" |
||||||
|
|
||||||
|
config BTDM_CTRL_MODE_BR_EDR_ONLY |
||||||
|
bool "BR/EDR Only" |
||||||
|
|
||||||
|
config BTDM_CTRL_MODE_BTDM |
||||||
|
bool "Bluetooth Dual Mode" |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
config BTDM_CTRL_BLE_MAX_CONN |
||||||
|
int "BLE Max Connections" |
||||||
|
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 3 |
||||||
|
range 1 9 |
||||||
|
help |
||||||
|
BLE maximum connections of bluetooth controller. |
||||||
|
Each connection uses 1KB static DRAM whenever the BT controller is enabled. |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_MAX_ACL_CONN |
||||||
|
int "BR/EDR ACL Max Connections" |
||||||
|
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 2 |
||||||
|
range 1 7 |
||||||
|
help |
||||||
|
BR/EDR ACL maximum connections of bluetooth controller. |
||||||
|
Each connection uses 1.2 KB DRAM whenever the BT controller is enabled. |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN |
||||||
|
int "BR/EDR Sync(SCO/eSCO) Max Connections" |
||||||
|
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 0 |
||||||
|
range 0 3 |
||||||
|
help |
||||||
|
BR/EDR Synchronize maximum connections of bluetooth controller. |
||||||
|
Each connection uses 2 KB DRAM whenever the BT controller is enabled. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
choice BTDM_CTRL_BR_EDR_SCO_DATA_PATH |
||||||
|
prompt "BR/EDR Sync(SCO/eSCO) default data path" |
||||||
|
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM |
||||||
|
help |
||||||
|
SCO data path, i.e. HCI or PCM. |
||||||
|
SCO data can be sent/received through HCI synchronous packets, or the data |
||||||
|
can be routed to on-chip PCM module on ESP32. PCM input/output signals can |
||||||
|
be "matrixed" to GPIOs. The default data path can also be set using API |
||||||
|
"esp_bredr_sco_datapath_set" |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI |
||||||
|
bool "HCI" |
||||||
|
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM |
||||||
|
bool "PCM" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF |
||||||
|
int |
||||||
|
default 0 if BTDM_CTRL_BR_EDR_SCO_DATA_PATH_HCI |
||||||
|
default 1 if BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM |
||||||
|
default 0 |
||||||
|
|
||||||
|
menuconfig BTDM_CTRL_PCM_ROLE_EDGE_CONFIG |
||||||
|
bool "PCM Signal Config (Role and Polar)" |
||||||
|
depends on BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM |
||||||
|
default y |
||||||
|
|
||||||
|
choice BTDM_CTRL_PCM_ROLE |
||||||
|
prompt "PCM Role" |
||||||
|
depends on BTDM_CTRL_PCM_ROLE_EDGE_CONFIG |
||||||
|
help |
||||||
|
PCM role can be configured as PCM master or PCM slave |
||||||
|
|
||||||
|
config BTDM_CTRL_PCM_ROLE_MASTER |
||||||
|
bool "PCM Master" |
||||||
|
config BTDM_CTRL_PCM_ROLE_SLAVE |
||||||
|
bool "PCM Slave" |
||||||
|
endchoice |
||||||
|
|
||||||
|
choice BTDM_CTRL_PCM_POLAR |
||||||
|
prompt "PCM Polar" |
||||||
|
depends on BTDM_CTRL_PCM_ROLE_EDGE_CONFIG |
||||||
|
help |
||||||
|
PCM polarity can be configured as Falling Edge or Rising Edge |
||||||
|
|
||||||
|
config BTDM_CTRL_PCM_POLAR_FALLING_EDGE |
||||||
|
bool "Falling Edge" |
||||||
|
config BTDM_CTRL_PCM_POLAR_RISING_EDGE |
||||||
|
bool "Rising Edge" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BTDM_CTRL_PCM_ROLE_EFF |
||||||
|
int |
||||||
|
default 0 if BTDM_CTRL_PCM_ROLE_MASTER |
||||||
|
default 1 if BTDM_CTRL_PCM_ROLE_SLAVE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_CTRL_PCM_POLAR_EFF |
||||||
|
int |
||||||
|
default 0 if BTDM_CTRL_PCM_POLAR_FALLING_EDGE |
||||||
|
default 1 if BTDM_CTRL_PCM_POLAR_RISING_EDGE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_CTRL_AUTO_LATENCY |
||||||
|
bool "Auto latency" |
||||||
|
depends on BTDM_CTRL_MODE_BTDM |
||||||
|
default n |
||||||
|
help |
||||||
|
BLE auto latency, used to enhance classic BT performance |
||||||
|
while classic BT and BLE are enabled at the same time. |
||||||
|
|
||||||
|
config BTDM_CTRL_AUTO_LATENCY_EFF |
||||||
|
bool |
||||||
|
default BTDM_CTRL_AUTO_LATENCY if BTDM_CTRL_MODE_BTDM |
||||||
|
default n |
||||||
|
|
||||||
|
config BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT |
||||||
|
bool "Legacy Authentication Vendor Specific Event Enable" |
||||||
|
depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default y |
||||||
|
help |
||||||
|
To protect from BIAS attack during Legacy authentication, |
||||||
|
Legacy authentication Vendor specific event should be enabled |
||||||
|
|
||||||
|
config BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT_EFF |
||||||
|
bool |
||||||
|
default BTDM_CTRL_LEGACY_AUTH_VENDOR_EVT if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 0 |
||||||
|
|
||||||
|
|
||||||
|
config BTDM_CTRL_BLE_MAX_CONN_EFF |
||||||
|
int |
||||||
|
default BTDM_CTRL_BLE_MAX_CONN if BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF |
||||||
|
int |
||||||
|
default BTDM_CTRL_BR_EDR_MAX_ACL_CONN if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF |
||||||
|
int |
||||||
|
default BTDM_CTRL_BR_EDR_MAX_SYNC_CONN if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default 0 |
||||||
|
|
||||||
|
choice BTDM_CTRL_PINNED_TO_CORE_CHOICE |
||||||
|
prompt "The cpu core which bluetooth controller run" |
||||||
|
depends on !FREERTOS_UNICORE |
||||||
|
help |
||||||
|
Specify the cpu core to run bluetooth controller. |
||||||
|
Can not specify no-affinity. |
||||||
|
|
||||||
|
config BTDM_CTRL_PINNED_TO_CORE_0 |
||||||
|
bool "Core 0 (PRO CPU)" |
||||||
|
config BTDM_CTRL_PINNED_TO_CORE_1 |
||||||
|
bool "Core 1 (APP CPU)" |
||||||
|
depends on !FREERTOS_UNICORE |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BTDM_CTRL_PINNED_TO_CORE |
||||||
|
int |
||||||
|
default 0 if BTDM_CTRL_PINNED_TO_CORE_0 |
||||||
|
default 1 if BTDM_CTRL_PINNED_TO_CORE_1 |
||||||
|
default 0 |
||||||
|
|
||||||
|
choice BTDM_CTRL_HCI_MODE_CHOICE |
||||||
|
prompt "HCI mode" |
||||||
|
help |
||||||
|
Speicify HCI mode as VHCI or UART(H4) |
||||||
|
|
||||||
|
config BTDM_CTRL_HCI_MODE_VHCI |
||||||
|
bool "VHCI" |
||||||
|
help |
||||||
|
Normal option. Mostly, choose this VHCI when bluetooth host run on ESP32, too. |
||||||
|
|
||||||
|
config BTDM_CTRL_HCI_MODE_UART_H4 |
||||||
|
bool "UART(H4)" |
||||||
|
help |
||||||
|
If use external bluetooth host which run on other hardware and use UART as the HCI interface, |
||||||
|
choose this option. |
||||||
|
endchoice |
||||||
|
|
||||||
|
menu "HCI UART(H4) Options" |
||||||
|
visible if BTDM_CTRL_HCI_MODE_UART_H4 |
||||||
|
|
||||||
|
config BTDM_CTRL_HCI_UART_NO |
||||||
|
int "UART Number for HCI" |
||||||
|
depends on BTDM_CTRL_HCI_MODE_UART_H4 |
||||||
|
range 1 2 |
||||||
|
default 1 |
||||||
|
help |
||||||
|
Uart number for HCI. The available uart is UART1 and UART2. |
||||||
|
|
||||||
|
config BTDM_CTRL_HCI_UART_BAUDRATE |
||||||
|
int "UART Baudrate for HCI" |
||||||
|
depends on BTDM_CTRL_HCI_MODE_UART_H4 |
||||||
|
range 115200 921600 |
||||||
|
default 921600 |
||||||
|
help |
||||||
|
UART Baudrate for HCI. Please use standard baudrate. |
||||||
|
|
||||||
|
config BTDM_CTRL_HCI_UART_FLOW_CTRL_EN |
||||||
|
bool "Enable UART flow control" |
||||||
|
depends on BTDM_CTRL_HCI_MODE_UART_H4 |
||||||
|
default y |
||||||
|
|
||||||
|
endmenu |
||||||
|
|
||||||
|
menu "MODEM SLEEP Options" |
||||||
|
config BTDM_CTRL_MODEM_SLEEP |
||||||
|
bool "Bluetooth modem sleep" |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable/disable bluetooth controller low power mode. |
||||||
|
|
||||||
|
choice BTDM_CTRL_MODEM_SLEEP_MODE |
||||||
|
prompt "Bluetooth Modem sleep mode" |
||||||
|
depends on BTDM_CTRL_MODEM_SLEEP |
||||||
|
help |
||||||
|
To select which strategy to use for modem sleep |
||||||
|
|
||||||
|
config BTDM_CTRL_MODEM_SLEEP_MODE_ORIG |
||||||
|
bool "ORIG Mode(sleep with low power clock)" |
||||||
|
help |
||||||
|
ORIG mode is a bluetooth sleep mode that can be used for dual mode controller. In this mode, |
||||||
|
bluetooth controller sleeps between BR/EDR frames and BLE events. A low power clock is used to |
||||||
|
maintain bluetooth reference clock. |
||||||
|
|
||||||
|
config BTDM_CTRL_MODEM_SLEEP_MODE_EVED |
||||||
|
bool "EVED Mode(For internal test only)" |
||||||
|
help |
||||||
|
EVED mode is for BLE only and is only for internal test. Do not use it for production. this |
||||||
|
mode is not compatible with DFS nor light sleep |
||||||
|
endchoice |
||||||
|
|
||||||
|
choice BTDM_CTRL_LOW_POWER_CLOCK |
||||||
|
prompt "Bluetooth low power clock" |
||||||
|
depends on BTDM_CTRL_MODEM_SLEEP_MODE_ORIG |
||||||
|
help |
||||||
|
Select the low power clock source for bluetooth controller. Bluetooth low power clock is |
||||||
|
the clock source to maintain time in sleep mode. |
||||||
|
|
||||||
|
- "Main crystal" option provides good accuracy and can support Dynamic Frequency Scaling |
||||||
|
to be used with Bluetooth modem sleep. Light sleep is not supported. |
||||||
|
- "External 32kHz crystal" option allows user to use a 32.768kHz crystal as Bluetooth low |
||||||
|
power clock. This option is allowed as long as External 32kHz crystal is configured as |
||||||
|
the system RTC clock source. This option provides good accuracy and supports Bluetooth |
||||||
|
modem sleep to be used alongside Dynamic Frequency Scaling or light sleep. |
||||||
|
|
||||||
|
config BTDM_CTRL_LPCLK_SEL_MAIN_XTAL |
||||||
|
bool "Main crystal" |
||||||
|
help |
||||||
|
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is |
||||||
|
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but |
||||||
|
cannot work when light sleep is enabled. Main crystal has a good performance in accuracy as |
||||||
|
the bluetooth low power clock source. |
||||||
|
|
||||||
|
config BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL |
||||||
|
bool "External 32kHz crystal" |
||||||
|
depends on RTC_CLK_SRC_EXT_CRYS |
||||||
|
help |
||||||
|
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency |
||||||
|
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth |
||||||
|
modem sleep to be used with both DFS and light sleep. |
||||||
|
endchoice |
||||||
|
|
||||||
|
endmenu |
||||||
|
|
||||||
|
choice BTDM_BLE_SLEEP_CLOCK_ACCURACY |
||||||
|
prompt "BLE Sleep Clock Accuracy" |
||||||
|
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default BTDM_BLE_DEFAULT_SCA_250PPM |
||||||
|
help |
||||||
|
BLE Sleep Clock Accuracy(SCA) for the local device is used to estimate window widening in BLE |
||||||
|
connection events. With a lower level of clock accuracy(e.g. 500ppm over 250ppm), the slave |
||||||
|
needs a larger RX window to synchronize with master in each anchor point, thus resulting in an |
||||||
|
increase of power consumption but a higher level of robustness in keeping connected. According |
||||||
|
to the requirements of Bluetooth Core specification 4.2, the worst-case accuracy of Classic |
||||||
|
Bluetooth low power oscialltor(LPO) is +/-250ppm in STANDBY and in low power modes such as |
||||||
|
sniff. For BLE the worst-case SCA is +/-500ppm. |
||||||
|
|
||||||
|
- "151ppm to 250ppm" option is the default value for Bluetooth Dual mode |
||||||
|
- "251ppm to 500ppm" option can be used in BLE only mode when using external 32kHz crystal as |
||||||
|
low power clock. This option is provided in case that BLE sleep clock has a lower level of |
||||||
|
accuracy, or other error sources contribute to the inaccurate timing during sleep. |
||||||
|
|
||||||
|
config BTDM_BLE_DEFAULT_SCA_500PPM |
||||||
|
bool "251ppm to 500ppm" |
||||||
|
depends on BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL && BTDM_CTRL_MODE_BLE_ONLY |
||||||
|
config BTDM_BLE_DEFAULT_SCA_250PPM |
||||||
|
bool "151ppm to 250ppm" |
||||||
|
endchoice |
||||||
|
config BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF |
||||||
|
int |
||||||
|
default 0 if BTDM_BLE_DEFAULT_SCA_500PPM |
||||||
|
default 1 if BTDM_BLE_DEFAULT_SCA_250PPM |
||||||
|
default 1 |
||||||
|
|
||||||
|
config BTDM_BLE_SCAN_DUPL |
||||||
|
bool "BLE Scan Duplicate Options" |
||||||
|
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY) |
||||||
|
default y |
||||||
|
help |
||||||
|
This select enables parameters setting of BLE scan duplicate. |
||||||
|
|
||||||
|
choice BTDM_SCAN_DUPL_TYPE |
||||||
|
prompt "Scan Duplicate Type" |
||||||
|
default BTDM_SCAN_DUPL_TYPE_DEVICE |
||||||
|
depends on BTDM_BLE_SCAN_DUPL |
||||||
|
help |
||||||
|
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use |
||||||
|
advertiser address filtering. The adv packet of the same address is only allowed to be reported once. |
||||||
|
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising |
||||||
|
data and device address filtering. All different adv packets with the same address are allowed to be |
||||||
|
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data |
||||||
|
filtering. All same advertising data only allow to be reported once even though they are from |
||||||
|
different devices. |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_TYPE_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address" |
||||||
|
help |
||||||
|
This way is to use advertiser address filtering. The adv packet of the same address is only |
||||||
|
allowed to be reported once |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_TYPE_DATA |
||||||
|
bool "Scan Duplicate By Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data filtering. All same advertising data only allow to be reported |
||||||
|
once even though they are from different devices. |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address And Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data and device address filtering. All different adv packets with |
||||||
|
the same address are allowed to be reported. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_TYPE |
||||||
|
int |
||||||
|
depends on BTDM_BLE_SCAN_DUPL |
||||||
|
default 0 if BTDM_SCAN_DUPL_TYPE_DEVICE |
||||||
|
default 1 if BTDM_SCAN_DUPL_TYPE_DATA |
||||||
|
default 2 if BTDM_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_CACHE_SIZE |
||||||
|
int "Maximum number of devices in scan duplicate filter" |
||||||
|
depends on BTDM_BLE_SCAN_DUPL |
||||||
|
range 10 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
Maximum number of devices which can be recorded in scan duplicate filter. |
||||||
|
When the maximum amount of device in the filter is reached, the oldest device will be refreshed. |
||||||
|
|
||||||
|
config BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD |
||||||
|
int "Duplicate scan list refresh period (seconds)" |
||||||
|
depends on BTDM_BLE_SCAN_DUPL |
||||||
|
range 0 1000 |
||||||
|
default 0 |
||||||
|
help |
||||||
|
If the period value is non-zero, the controller will periodically clear the device information |
||||||
|
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared |
||||||
|
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the |
||||||
|
Host in advertising report events. |
||||||
|
There are two scenarios where the ADV packet will be repeatedly reported: |
||||||
|
1. The duplicate scan cache is full, the controller will delete the oldest device information and |
||||||
|
add new device information. |
||||||
|
2. When the refresh period is up, the controller will clear all device information and start filtering |
||||||
|
again. |
||||||
|
|
||||||
|
config BTDM_BLE_MESH_SCAN_DUPL_EN |
||||||
|
bool "Special duplicate scan mechanism for BLE Mesh scan" |
||||||
|
depends on BTDM_BLE_SCAN_DUPL |
||||||
|
default n |
||||||
|
help |
||||||
|
This enables the BLE scan duplicate for special BLE Mesh scan. |
||||||
|
|
||||||
|
config BTDM_MESH_DUPL_SCAN_CACHE_SIZE |
||||||
|
int "Maximum number of Mesh adv packets in scan duplicate filter" |
||||||
|
depends on BTDM_BLE_MESH_SCAN_DUPL_EN |
||||||
|
range 10 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh. |
||||||
|
When the maximum amount of device in the filter is reached, the cache will be refreshed. |
||||||
|
|
||||||
|
config BTDM_CTRL_FULL_SCAN_SUPPORTED |
||||||
|
bool "BLE full scan feature supported" |
||||||
|
depends on BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM |
||||||
|
default y |
||||||
|
help |
||||||
|
The full scan function is mainly used to provide BLE scan performance. |
||||||
|
This is required for scenes with high scan performance requirements, such as BLE Mesh scenes. |
||||||
|
|
||||||
|
config BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
bool "BLE adv report flow control supported" |
||||||
|
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY) |
||||||
|
default y |
||||||
|
help |
||||||
|
The function is mainly used to enable flow control for advertising reports. When it is enabled, |
||||||
|
advertising reports will be discarded by the controller if the number of unprocessed advertising |
||||||
|
reports exceeds the size of BLE adv report flow control. |
||||||
|
|
||||||
|
config BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM |
||||||
|
int "BLE adv report flow control number" |
||||||
|
depends on BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 50 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
The number of unprocessed advertising report that Bluedroid can save.If you set |
||||||
|
`BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. |
||||||
|
If you set `BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, Bluedroid may cache a |
||||||
|
lot of adv packets and this may cause system memory run out. For example, if you set |
||||||
|
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set |
||||||
|
`BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv |
||||||
|
packets as fast as possible, otherwise it will cause adv packets lost. |
||||||
|
|
||||||
|
config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD |
||||||
|
int "BLE adv lost event threshold value" |
||||||
|
depends on BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 1 1000 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
When adv report flow control is enabled, The ADV lost event will be generated when the number |
||||||
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. |
||||||
|
If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it |
||||||
|
may cause adv packets lost more. |
||||||
|
|
||||||
|
|
||||||
|
config BTDM_RESERVE_DRAM |
||||||
|
hex |
||||||
|
default 0xdb5c if BT_ENABLED |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BTDM_CTRL_HLI |
||||||
|
bool "High level interrupt" |
||||||
|
depends on BT_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Using Level 4 interrupt for Bluetooth. |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,297 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
#include "esp_log.h" |
||||||
|
#include "esp_heap_caps.h" |
||||||
|
#include "xtensa/core-macros.h" |
||||||
|
#include "soc/dport_reg.h" |
||||||
|
#include "hli_api.h" |
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
|
||||||
|
#if CONFIG_BTDM_CTRL_HLI |
||||||
|
#define HLI_MAX_HANDLERS 4 |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
intr_handler_t handler; |
||||||
|
void* arg; |
||||||
|
uint32_t intr_reg; |
||||||
|
uint32_t intr_mask; |
||||||
|
} hli_handler_info_t; |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
#define CUSTOMER_TYPE_REQUEST (0) |
||||||
|
#define CUSTOMER_TYPE_RELEASE (1) |
||||||
|
struct { |
||||||
|
uint32_t cb_type; |
||||||
|
union { |
||||||
|
int (* request)(uint32_t, uint32_t, uint32_t); |
||||||
|
int (* release)(uint32_t); |
||||||
|
} cb; |
||||||
|
} customer_cb; |
||||||
|
uint32_t arg0, arg1, arg2; |
||||||
|
} customer_swisr_t; |
||||||
|
|
||||||
|
static void IRAM_ATTR customer_swisr_handle(customer_swisr_t *cus_swisr) |
||||||
|
{ |
||||||
|
if (cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_REQUEST) { |
||||||
|
if (cus_swisr->customer_cb.cb.request != NULL) { |
||||||
|
cus_swisr->customer_cb.cb.request(cus_swisr->arg0, cus_swisr->arg1, cus_swisr->arg2); |
||||||
|
} |
||||||
|
} else if(cus_swisr->customer_cb.cb_type == CUSTOMER_TYPE_RELEASE) { |
||||||
|
if (cus_swisr->customer_cb.cb.release != NULL) { |
||||||
|
cus_swisr->customer_cb.cb.release(cus_swisr->arg0); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS]; |
||||||
|
|
||||||
|
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask) |
||||||
|
{ |
||||||
|
for (hli_handler_info_t* hip = s_hli_handlers; |
||||||
|
hip < s_hli_handlers + HLI_MAX_HANDLERS; |
||||||
|
++hip) { |
||||||
|
if (hip->handler == NULL) { |
||||||
|
hip->arg = arg; |
||||||
|
hip->intr_reg = intr_reg; |
||||||
|
hip->intr_mask = intr_mask; |
||||||
|
hip->handler = handler; /* set last, indicates the entry as valid */ |
||||||
|
return ESP_OK; |
||||||
|
} |
||||||
|
} |
||||||
|
return ESP_ERR_NO_MEM; |
||||||
|
} |
||||||
|
|
||||||
|
void IRAM_ATTR hli_c_handler(void) |
||||||
|
{ |
||||||
|
bool handled = false; |
||||||
|
/* Iterate over registered interrupt handlers,
|
||||||
|
* and check if the expected mask is present in the interrupt status register. |
||||||
|
*/ |
||||||
|
for (hli_handler_info_t* hip = s_hli_handlers; |
||||||
|
hip < s_hli_handlers + HLI_MAX_HANDLERS; |
||||||
|
++hip) { |
||||||
|
if (hip->handler == NULL) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
uint32_t reg = hip->intr_reg; |
||||||
|
uint32_t val; |
||||||
|
if (reg == 0) { /* special case for CPU internal interrupts */ |
||||||
|
val = XTHAL_GET_INTERRUPT(); |
||||||
|
} else { |
||||||
|
/* "reg" might not be in DPORT, but this will work in any case */ |
||||||
|
val = DPORT_REG_READ(reg); |
||||||
|
} |
||||||
|
if ((val & hip->intr_mask) != 0) { |
||||||
|
handled = true; |
||||||
|
(*hip->handler)(hip->arg); |
||||||
|
} |
||||||
|
} |
||||||
|
if (!handled) { |
||||||
|
/* no handler found, it is OK in this case. */ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t IRAM_ATTR hli_intr_disable(void) |
||||||
|
{ |
||||||
|
/* disable level 4 and below */ |
||||||
|
return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2); |
||||||
|
} |
||||||
|
|
||||||
|
void IRAM_ATTR hli_intr_restore(uint32_t state) |
||||||
|
{ |
||||||
|
XTOS_RESTORE_JUST_INTLEVEL(state); |
||||||
|
} |
||||||
|
|
||||||
|
#define HLI_META_QUEUE_SIZE 16 |
||||||
|
#define HLI_QUEUE_MAX_ELEM_SIZE 32 |
||||||
|
#define HLI_QUEUE_SW_INT_NUM 29 |
||||||
|
|
||||||
|
#define HLI_QUEUE_FLAG_SEMAPHORE BIT(0) |
||||||
|
#define HLI_QUEUE_FLAG_CUSTOMER BIT(1) |
||||||
|
|
||||||
|
static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL; |
||||||
|
static intr_handle_t ret_handle; |
||||||
|
|
||||||
|
static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr) |
||||||
|
{ |
||||||
|
return (ptr == queue->bufend) ? queue->buf : ptr; |
||||||
|
} |
||||||
|
|
||||||
|
static inline bool IRAM_ATTR queue_empty(hli_queue_handle_t queue) |
||||||
|
{ |
||||||
|
return queue->begin == queue->end; |
||||||
|
} |
||||||
|
|
||||||
|
static inline bool IRAM_ATTR queue_full(hli_queue_handle_t queue) |
||||||
|
{ |
||||||
|
return wrap_ptr(queue, queue->end + queue->elem_size) == queue->begin; |
||||||
|
} |
||||||
|
|
||||||
|
static void IRAM_ATTR queue_isr_handler(void* arg) |
||||||
|
{ |
||||||
|
int do_yield = pdFALSE; |
||||||
|
XTHAL_SET_INTCLEAR(BIT(HLI_QUEUE_SW_INT_NUM)); |
||||||
|
hli_queue_handle_t queue; |
||||||
|
|
||||||
|
while (hli_queue_get(s_meta_queue_ptr, &queue)) { |
||||||
|
static DRAM_ATTR char scratch[HLI_QUEUE_MAX_ELEM_SIZE]; |
||||||
|
while (hli_queue_get(queue, scratch)) { |
||||||
|
int res = pdPASS; |
||||||
|
if ((queue->flags & HLI_QUEUE_FLAG_CUSTOMER) != 0) { |
||||||
|
customer_swisr_handle((customer_swisr_t *)scratch); |
||||||
|
} else if ((queue->flags & HLI_QUEUE_FLAG_SEMAPHORE) != 0) { |
||||||
|
res = xSemaphoreGiveFromISR((SemaphoreHandle_t) queue->downstream, &do_yield); |
||||||
|
} else { |
||||||
|
res = xQueueSendFromISR(queue->downstream, scratch, &do_yield); |
||||||
|
} |
||||||
|
if (res == pdFAIL) { |
||||||
|
/* Failed to send to downstream queue, it is OK in this case. */ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (do_yield) { |
||||||
|
portYIELD_FROM_ISR(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Notify the level 3 handler that an element is added to the given hli queue.
|
||||||
|
* Do this by placing the queue handle onto s_meta_queue, and raising a SW interrupt. |
||||||
|
* |
||||||
|
* This function must be called with HL interrupts disabled! |
||||||
|
*/ |
||||||
|
static void IRAM_ATTR queue_signal(hli_queue_handle_t queue) |
||||||
|
{ |
||||||
|
/* See if the queue is already in s_meta_queue, before adding */ |
||||||
|
bool found = false; |
||||||
|
const hli_queue_handle_t *end = (hli_queue_handle_t*) s_meta_queue_ptr->end; |
||||||
|
hli_queue_handle_t *item = (hli_queue_handle_t*) s_meta_queue_ptr->begin; |
||||||
|
for (;item != end; item = (hli_queue_handle_t*) wrap_ptr(s_meta_queue_ptr, (char*) (item + 1))) { |
||||||
|
if (*item == queue) { |
||||||
|
found = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!found) { |
||||||
|
bool res = hli_queue_put(s_meta_queue_ptr, &queue); |
||||||
|
if (!res) { |
||||||
|
esp_rom_printf(DRAM_STR("Fatal error in queue_signal: s_meta_queue full\n")); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
XTHAL_SET_INTSET(BIT(HLI_QUEUE_SW_INT_NUM)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void queue_init(hli_queue_handle_t queue, size_t buf_size, size_t elem_size, QueueHandle_t downstream) |
||||||
|
{ |
||||||
|
queue->elem_size = elem_size; |
||||||
|
queue->begin = queue->buf; |
||||||
|
queue->end = queue->buf; |
||||||
|
queue->bufend = queue->buf + buf_size; |
||||||
|
queue->downstream = downstream; |
||||||
|
queue->flags = 0; |
||||||
|
} |
||||||
|
|
||||||
|
void hli_queue_setup(void) |
||||||
|
{ |
||||||
|
if (s_meta_queue_ptr == NULL) { |
||||||
|
s_meta_queue_ptr = hli_queue_create(HLI_META_QUEUE_SIZE, sizeof(void*), NULL); |
||||||
|
ESP_ERROR_CHECK(esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, ESP_INTR_FLAG_IRAM, queue_isr_handler, NULL, &ret_handle)); |
||||||
|
xt_ints_on(BIT(HLI_QUEUE_SW_INT_NUM)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void hli_queue_shutdown(void) |
||||||
|
{ |
||||||
|
if (s_meta_queue_ptr != NULL) { |
||||||
|
hli_queue_delete(s_meta_queue_ptr); |
||||||
|
s_meta_queue_ptr = NULL; |
||||||
|
esp_intr_free(ret_handle); |
||||||
|
xt_ints_off(BIT(HLI_QUEUE_SW_INT_NUM)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream) |
||||||
|
{ |
||||||
|
const size_t buf_elem = nelem + 1; |
||||||
|
if (elem_size > HLI_QUEUE_MAX_ELEM_SIZE) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
size_t buf_size = buf_elem * elem_size; |
||||||
|
hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(struct hli_queue_t) + buf_size, |
||||||
|
MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); |
||||||
|
if (res == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
queue_init(res, buf_size, elem_size, downstream); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream) |
||||||
|
{ |
||||||
|
hli_queue_handle_t res = hli_queue_create(nelem, elem_size, (QueueHandle_t) downstream); |
||||||
|
if (res == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
res->flags |= HLI_QUEUE_FLAG_CUSTOMER; |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream) |
||||||
|
{ |
||||||
|
const size_t elem_size = 1; |
||||||
|
hli_queue_handle_t res = hli_queue_create(max_count, elem_size, (QueueHandle_t) downstream); |
||||||
|
if (res == NULL) { |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
res->flags |= HLI_QUEUE_FLAG_SEMAPHORE; |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
void hli_queue_delete(hli_queue_handle_t queue) |
||||||
|
{ |
||||||
|
free(queue); |
||||||
|
} |
||||||
|
|
||||||
|
bool IRAM_ATTR hli_queue_get(hli_queue_handle_t queue, void* out) |
||||||
|
{ |
||||||
|
uint32_t int_state = hli_intr_disable(); |
||||||
|
bool res = false; |
||||||
|
if (!queue_empty(queue)) { |
||||||
|
memcpy(out, queue->begin, queue->elem_size); |
||||||
|
queue->begin = wrap_ptr(queue, queue->begin + queue->elem_size); |
||||||
|
res = true; |
||||||
|
} |
||||||
|
hli_intr_restore(int_state); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
bool IRAM_ATTR hli_queue_put(hli_queue_handle_t queue, const void* data) |
||||||
|
{ |
||||||
|
uint32_t int_state = hli_intr_disable(); |
||||||
|
bool res = false; |
||||||
|
bool was_empty = queue_empty(queue); |
||||||
|
if (!queue_full(queue)) { |
||||||
|
memcpy(queue->end, data, queue->elem_size); |
||||||
|
queue->end = wrap_ptr(queue, queue->end + queue->elem_size); |
||||||
|
if (was_empty && queue != s_meta_queue_ptr) { |
||||||
|
queue_signal(queue); |
||||||
|
} |
||||||
|
res = true; |
||||||
|
} |
||||||
|
hli_intr_restore(int_state); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
bool IRAM_ATTR hli_semaphore_give(hli_queue_handle_t queue) |
||||||
|
{ |
||||||
|
uint8_t data = 0; |
||||||
|
return hli_queue_put(queue, &data); |
||||||
|
} |
||||||
|
|
||||||
|
#endif /* CONFIG_BTDM_CTRL_HLI */ |
@ -0,0 +1,167 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include "esp_err.h" |
||||||
|
#include "esp_intr_alloc.h" |
||||||
|
#include "freertos/FreeRTOS.h" |
||||||
|
#include "freertos/queue.h" |
||||||
|
#include "freertos/semphr.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
#if CONFIG_BTDM_CTRL_HLI |
||||||
|
|
||||||
|
/*** Queues ***/ |
||||||
|
|
||||||
|
struct hli_queue_t |
||||||
|
{ |
||||||
|
size_t elem_size; |
||||||
|
char* begin; |
||||||
|
char* end; |
||||||
|
const char* bufend; |
||||||
|
QueueHandle_t downstream; |
||||||
|
int flags; |
||||||
|
char buf[0]; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a high level interrupt function |
||||||
|
* |
||||||
|
* @param handler interrupt handler function |
||||||
|
* @param arg argument to pass to the interrupt handler |
||||||
|
* @param intr_reg address of the peripheral register containing the interrupt status, |
||||||
|
* or value 0 to get the status from CPU INTERRUPT register |
||||||
|
* @param intr_mask mask of the interrupt, in the interrupt status register |
||||||
|
* @return |
||||||
|
* - ESP_OK on success |
||||||
|
* - ESP_ERR_NO_MEM if too many handlers are registered |
||||||
|
*/ |
||||||
|
esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mask all interrupts (including high level ones) on the current CPU |
||||||
|
* |
||||||
|
* @return uint32_t interrupt status, pass it to hli_intr_restore |
||||||
|
*/ |
||||||
|
uint32_t hli_intr_disable(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Re-enable interrupts |
||||||
|
* |
||||||
|
* @param state value returned by hli_intr_disable |
||||||
|
*/ |
||||||
|
void hli_intr_restore(uint32_t state); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a hli queue |
||||||
|
*/ |
||||||
|
typedef struct hli_queue_t* hli_queue_handle_t; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize hli_queue module. Must be called once before using hli queue APIs. |
||||||
|
*/ |
||||||
|
void hli_queue_setup(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shutdown hli_queue module. |
||||||
|
*/ |
||||||
|
void hli_queue_shutdown(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a hli queue, wrapping a FreeRTOS queue |
||||||
|
* |
||||||
|
* This queue can be used from high level interrupts, |
||||||
|
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this |
||||||
|
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3 |
||||||
|
* software interrupt. |
||||||
|
* |
||||||
|
* @param nelem number of elements in the queue |
||||||
|
* @param elem_size size of one element; must match element size of a downstream queue |
||||||
|
* @param downstream FreeRTOS queue to send the values to |
||||||
|
* @return hli_queue_handle_t handle of the created queue, or NULL on failure |
||||||
|
*/ |
||||||
|
hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a customer hli queue, wrapping a FreeRTOS queue |
||||||
|
* |
||||||
|
* This queue can be used from high level interrupts, |
||||||
|
* but **ONLY ON THE CPU WHERE hli_queue_setup WAS CALLED**. Values sent to this |
||||||
|
* queue are automatically forwarded to "downstream" FreeRTOS queue using a level 3 |
||||||
|
* software interrupt. |
||||||
|
* |
||||||
|
* @param nelem number of elements in the queue |
||||||
|
* @param elem_size size of one element; must match element size of a downstream queue |
||||||
|
* @param downstream FreeRTOS queue to send the values to |
||||||
|
* @return hli_queue_handle_t handle of the created queue, or NULL on failure |
||||||
|
*/ |
||||||
|
hli_queue_handle_t hli_customer_queue_create(size_t nelem, size_t elem_size, QueueHandle_t downstream); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a hli queue, wrapping a FreeRTOS semaphore |
||||||
|
* |
||||||
|
* See notes on hli_queue_create. |
||||||
|
* |
||||||
|
* @param max_count maximum semaphore count |
||||||
|
* @param downstream FreeRTOS semaphore to forward the calls to |
||||||
|
* @return hli_queue_handle_t handle of the created queue, or NULL on failure |
||||||
|
*/ |
||||||
|
hli_queue_handle_t hli_semaphore_create(size_t max_count, SemaphoreHandle_t downstream); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a hli queue |
||||||
|
* |
||||||
|
* Make sure noone is using the queue before deleting it. |
||||||
|
* |
||||||
|
* @param queue handle returned by hli_queue_create or hli_semaphore_create |
||||||
|
*/ |
||||||
|
void hli_queue_delete(hli_queue_handle_t queue); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get one element from a hli queue |
||||||
|
* |
||||||
|
* Usually not used, values get sent to a downstream FreeRTOS queue automatically. |
||||||
|
* However if downstream queue is NULL, this API can be used to get values from a hli queue. |
||||||
|
* |
||||||
|
* @param queue handle of a queue |
||||||
|
* @param out pointer where to store the element |
||||||
|
* @return true if the element was successfully read from the queue |
||||||
|
*/ |
||||||
|
bool hli_queue_get(hli_queue_handle_t queue, void* out); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Put one element into a hli queue |
||||||
|
* |
||||||
|
* This puts copies an element into the queue and raises a software interrupt (level 3). |
||||||
|
* In the interrupt, the value is copied to a FreeRTOS "downstream" queue. |
||||||
|
* |
||||||
|
* Note that if the value does not fit into a downstream queue, no error is returned, |
||||||
|
* and the value is lost. |
||||||
|
* |
||||||
|
* @param queue handle of a queue |
||||||
|
* @param data pointer to the element to be sent |
||||||
|
* @return true if data was placed into the hli queue successfully |
||||||
|
*/ |
||||||
|
bool hli_queue_put(hli_queue_handle_t queue, const void* data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief "Give" a semaphore wrapped by a hli queue |
||||||
|
* |
||||||
|
* @param queue handle returned by hli_semaphore_create |
||||||
|
* @return true if the event was sent to a hli queue successfully |
||||||
|
*/ |
||||||
|
bool hli_semaphore_give(hli_queue_handle_t queue); |
||||||
|
|
||||||
|
#endif /* CONFIG_BTDM_CTRL_HLI */ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,267 @@ |
|||||||
|
/* |
||||||
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
#include <xtensa/coreasm.h> |
||||||
|
#include <xtensa/corebits.h> |
||||||
|
#include <xtensa/config/system.h> |
||||||
|
#include "xtensa_context.h" |
||||||
|
#include "sdkconfig.h" |
||||||
|
#include "soc/soc.h" |
||||||
|
|
||||||
|
#if CONFIG_BTDM_CTRL_HLI |
||||||
|
|
||||||
|
/* Interrupt stack size, for C code. |
||||||
|
* TODO: reduce and make configurable. |
||||||
|
*/ |
||||||
|
#define L4_INTR_STACK_SIZE 4096 |
||||||
|
|
||||||
|
/* Save area for the CPU state: |
||||||
|
* - 64 words for the general purpose registers |
||||||
|
* - 7 words for some of the special registers: |
||||||
|
* - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed |
||||||
|
* - SAR, LBEG, LEND, LCOUNT — since the C code might use these |
||||||
|
* - EPC1 — since the C code might cause window overflow exceptions |
||||||
|
* This is not laid out as standard exception frame structure |
||||||
|
* for simplicity of the save/restore code. |
||||||
|
*/ |
||||||
|
#define REG_FILE_SIZE (64 * 4) |
||||||
|
#define SPECREG_OFFSET REG_FILE_SIZE |
||||||
|
#define SPECREG_SIZE (7 * 4) |
||||||
|
#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET + SPECREG_SIZE) |
||||||
|
|
||||||
|
.data |
||||||
|
_l4_intr_stack: |
||||||
|
.space L4_INTR_STACK_SIZE
|
||||||
|
_l4_save_ctx: |
||||||
|
.space REG_SAVE_AREA_SIZE
|
||||||
|
|
||||||
|
.section .iram1,"ax" |
||||||
|
.global xt_highint4
|
||||||
|
.type xt_highint4,@function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
xt_highint4: |
||||||
|
|
||||||
|
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX |
||||||
|
/* |
||||||
|
Here, Timer2 is used to count a little time(50us). |
||||||
|
The subsequent dram0 write operation is blocked due to live lock, which will |
||||||
|
cause timer2 to timeout and trigger a level 5 interrupt. |
||||||
|
*/ |
||||||
|
rsr.ccount a0 |
||||||
|
addmi a0, a0, (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ*50) |
||||||
|
wsr a0, CCOMPARE2 |
||||||
|
|
||||||
|
/* Enable Timer 2 interrupt */ |
||||||
|
rsr a0, INTENABLE |
||||||
|
extui a0, a0, 16, 1 |
||||||
|
bnez a0, 1f |
||||||
|
movi a0, 0 |
||||||
|
xsr a0, INTENABLE /* disable all interrupts */ |
||||||
|
/* And a0 with (1 << 16) for Timer 2 interrupt mask */ |
||||||
|
addmi a0, a0, (1<<14) |
||||||
|
addmi a0, a0, (1<<14) |
||||||
|
addmi a0, a0, (1<<14) |
||||||
|
addmi a0, a0, (1<<14) |
||||||
|
wsr a0, INTENABLE /* Enable Timer 2 */ |
||||||
|
1: |
||||||
|
#endif |
||||||
|
|
||||||
|
movi a0, _l4_save_ctx |
||||||
|
/* save 4 lower registers */ |
||||||
|
s32i a1, a0, 4 |
||||||
|
s32i a2, a0, 8 |
||||||
|
s32i a3, a0, 12 |
||||||
|
rsr a2, EXCSAVE_4 /* holds the value of a0 */ |
||||||
|
s32i a2, a0, 0 |
||||||
|
|
||||||
|
/* Save special registers */ |
||||||
|
addi a0, a0, SPECREG_OFFSET |
||||||
|
rsr a2, WINDOWBASE |
||||||
|
s32i a2, a0, 0 |
||||||
|
rsr a2, WINDOWSTART |
||||||
|
s32i a2, a0, 4 |
||||||
|
rsr a2, SAR |
||||||
|
s32i a2, a0, 8 |
||||||
|
rsr a2, LBEG |
||||||
|
s32i a2, a0, 12 |
||||||
|
rsr a2, LEND |
||||||
|
s32i a2, a0, 16 |
||||||
|
rsr a2, LCOUNT |
||||||
|
s32i a2, a0, 20 |
||||||
|
rsr a2, EPC1 |
||||||
|
s32i a2, a0, 24 |
||||||
|
|
||||||
|
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX |
||||||
|
movi a0, 0 |
||||||
|
xsr a0, INTENABLE /* disable all interrupts */ |
||||||
|
movi a2, ~(1<<16) |
||||||
|
and a0, a2, a0 |
||||||
|
wsr a0, INTENABLE |
||||||
|
#endif |
||||||
|
|
||||||
|
/* disable exception mode, window overflow */ |
||||||
|
movi a0, PS_INTLEVEL(5) | PS_EXCM |
||||||
|
wsr a0, PS |
||||||
|
rsync |
||||||
|
|
||||||
|
/* Save the remaining physical registers. |
||||||
|
* 4 registers are already saved, which leaves 60 registers to save. |
||||||
|
* (FIXME: consider the case when the CPU is configured with physical 32 registers) |
||||||
|
* These 60 registers are saved in 5 iterations, 12 registers at a time. |
||||||
|
*/ |
||||||
|
movi a1, 5 |
||||||
|
movi a3, _l4_save_ctx + 4 * 4 |
||||||
|
|
||||||
|
/* This is repeated 5 times, each time the window is shifted by 12 registers. |
||||||
|
* We come here with a1 = downcounter, a3 = save pointer, a2 and a0 unused. |
||||||
|
*/ |
||||||
|
1: |
||||||
|
s32i a4, a3, 0 |
||||||
|
s32i a5, a3, 4 |
||||||
|
s32i a6, a3, 8 |
||||||
|
s32i a7, a3, 12 |
||||||
|
s32i a8, a3, 16 |
||||||
|
s32i a9, a3, 20 |
||||||
|
s32i a10, a3, 24 |
||||||
|
s32i a11, a3, 28 |
||||||
|
s32i a12, a3, 32 |
||||||
|
s32i a13, a3, 36 |
||||||
|
s32i a14, a3, 40 |
||||||
|
s32i a15, a3, 44 |
||||||
|
|
||||||
|
/* We are about to rotate the window, so that a12-a15 will become the new a0-a3. |
||||||
|
* Copy a0-a3 to a12-15 to still have access to these values. |
||||||
|
* At the same time we can decrement the counter and adjust the save area pointer |
||||||
|
*/ |
||||||
|
|
||||||
|
/* a0 is constant (_l4_save_ctx), no need to copy */ |
||||||
|
addi a13, a1, -1 /* copy and decrement the downcounter */ |
||||||
|
/* a2 is scratch so no need to copy */ |
||||||
|
addi a15, a3, 48 /* copy and adjust the save area pointer */ |
||||||
|
beqz a13, 2f /* have saved all registers ? */ |
||||||
|
rotw 3 /* rotate the window and go back */ |
||||||
|
j 1b |
||||||
|
|
||||||
|
/* the loop is complete */ |
||||||
|
2: |
||||||
|
rotw 4 /* this brings us back to the original window */ |
||||||
|
/* a0 still points to _l4_save_ctx */ |
||||||
|
|
||||||
|
/* Can clear WINDOWSTART now, all registers are saved */ |
||||||
|
rsr a2, WINDOWBASE |
||||||
|
/* WINDOWSTART = (1 << WINDOWBASE) */ |
||||||
|
movi a3, 1 |
||||||
|
ssl a2 |
||||||
|
sll a3, a3 |
||||||
|
wsr a3, WINDOWSTART |
||||||
|
|
||||||
|
_highint4_stack_switch: |
||||||
|
movi a0, 0 |
||||||
|
movi sp, _l4_intr_stack + L4_INTR_STACK_SIZE - 16 |
||||||
|
s32e a0, sp, -12 /* For GDB: set null SP */ |
||||||
|
s32e a0, sp, -16 /* For GDB: set null PC */ |
||||||
|
movi a0, _highint4_stack_switch /* For GDB: cosmetics, for the frame where stack switch happened */ |
||||||
|
|
||||||
|
/* Set up PS for C, disable all interrupts except NMI and debug, and clear EXCM. */ |
||||||
|
movi a6, PS_INTLEVEL(4) | PS_UM | PS_WOE |
||||||
|
wsr a6, PS |
||||||
|
rsync |
||||||
|
|
||||||
|
/* Call C handler */ |
||||||
|
mov a6, sp |
||||||
|
call4 hli_c_handler |
||||||
|
|
||||||
|
l32e sp, sp, -12 /* switch back to the original stack */ |
||||||
|
|
||||||
|
/* Done with C handler; re-enable exception mode, disabling window overflow */ |
||||||
|
movi a2, PS_INTLEVEL(5) | PS_EXCM /* TOCHECK */ |
||||||
|
wsr a2, PS |
||||||
|
rsync |
||||||
|
|
||||||
|
/* Restore the special registers. |
||||||
|
* WINDOWSTART will be restored near the end. |
||||||
|
*/ |
||||||
|
movi a0, _l4_save_ctx + SPECREG_OFFSET |
||||||
|
l32i a2, a0, 8 |
||||||
|
wsr a2, SAR |
||||||
|
l32i a2, a0, 12 |
||||||
|
wsr a2, LBEG |
||||||
|
l32i a2, a0, 16 |
||||||
|
wsr a2, LEND |
||||||
|
l32i a2, a0, 20 |
||||||
|
wsr a2, LCOUNT |
||||||
|
l32i a2, a0, 24 |
||||||
|
wsr a2, EPC1 |
||||||
|
|
||||||
|
/* Restoring the physical registers. |
||||||
|
* This is the reverse to the saving process above. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Rotate back to the final window, then start loading 12 registers at a time, |
||||||
|
* in 5 iterations. |
||||||
|
* Again, a1 is the downcounter and a3 is the save area pointer. |
||||||
|
* After each rotation, a1 and a3 are copied from a13 and a15. |
||||||
|
* To simplify the loop, we put the initial values into a13 and a15. |
||||||
|
*/ |
||||||
|
rotw -4 |
||||||
|
movi a15, _l4_save_ctx + 64 * 4 /* point to the end of the save area */ |
||||||
|
movi a13, 5 |
||||||
|
|
||||||
|
1: |
||||||
|
/* Copy a1 and a3 from their previous location, |
||||||
|
* at the same time decrementing and adjusting the save area pointer. |
||||||
|
*/ |
||||||
|
addi a1, a13, -1 |
||||||
|
addi a3, a15, -48 |
||||||
|
|
||||||
|
/* Load 12 registers */ |
||||||
|
l32i a4, a3, 0 |
||||||
|
l32i a5, a3, 4 |
||||||
|
l32i a6, a3, 8 |
||||||
|
l32i a7, a3, 12 |
||||||
|
l32i a8, a3, 16 |
||||||
|
l32i a9, a3, 20 |
||||||
|
l32i a10, a3, 24 |
||||||
|
l32i a11, a3, 28 /* ensure PS and EPC written */ |
||||||
|
l32i a12, a3, 32 |
||||||
|
l32i a13, a3, 36 |
||||||
|
l32i a14, a3, 40 |
||||||
|
l32i a15, a3, 44 |
||||||
|
|
||||||
|
/* Done with the loop? */ |
||||||
|
beqz a1, 2f |
||||||
|
/* If no, rotate the window and repeat */ |
||||||
|
rotw -3 |
||||||
|
j 1b |
||||||
|
|
||||||
|
2: |
||||||
|
/* Done with the loop. Only 4 registers (a0-a3 in the original window) remain |
||||||
|
* to be restored. Also need to restore WINDOWSTART, since all the general |
||||||
|
* registers are now in place. |
||||||
|
*/ |
||||||
|
movi a0, _l4_save_ctx |
||||||
|
|
||||||
|
l32i a2, a0, SPECREG_OFFSET + 4 |
||||||
|
wsr a2, WINDOWSTART |
||||||
|
|
||||||
|
l32i a1, a0, 4 |
||||||
|
l32i a2, a0, 8 |
||||||
|
l32i a3, a0, 12 |
||||||
|
rsr a0, EXCSAVE_4 /* holds the value of a0 before the interrupt handler */ |
||||||
|
|
||||||
|
/* Return from the interrupt, restoring PS from EPS_4 */ |
||||||
|
rfi 4 |
||||||
|
|
||||||
|
#endif /* CONFIG_BTDM_CTRL_HLI */ |
||||||
|
|
||||||
|
/* The linker has no reason to link in this file; all symbols it exports are already defined
|
||||||
|
(weakly!) in the default int handler. Define a symbol here so we can use it to have the |
||||||
|
linker inspect this anyway. */ |
||||||
|
|
||||||
|
.global ld_include_hli_vectors_bt
|
||||||
|
ld_include_hli_vectors_bt: |
@ -0,0 +1,466 @@ |
|||||||
|
|
||||||
|
menu "HCI Config" |
||||||
|
|
||||||
|
choice BT_LE_HCI_INTERFACE |
||||||
|
prompt "Select HCI interface" |
||||||
|
default BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
|
||||||
|
config BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
bool "ram" |
||||||
|
help |
||||||
|
Use RAM as HCI interface |
||||||
|
config BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
bool "uart" |
||||||
|
help |
||||||
|
Use UART as HCI interface |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_PORT |
||||||
|
int "HCI UART port" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1 |
||||||
|
help |
||||||
|
Set the port number of HCI UART |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_FLOWCTRL |
||||||
|
bool "HCI uart Hardware Flow ctrl" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default n |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TX_PIN |
||||||
|
int "HCI uart Tx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 19 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RX_PIN |
||||||
|
int "HCI uart Rx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 10 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RTS_PIN |
||||||
|
int "HCI uart RTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 4 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_CTS_PIN |
||||||
|
int "HCI uart CTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 5 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_BAUD |
||||||
|
int "HCI uart baudrate" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 921600 |
||||||
|
help |
||||||
|
HCI uart baud rate 115200 ~ 1000000 |
||||||
|
|
||||||
|
choice BT_LE_HCI_UART_PARITY |
||||||
|
prompt "select uart parity" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
bool "PARITY_DISABLE" |
||||||
|
help |
||||||
|
UART_PARITY_DISABLE |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_EVEN |
||||||
|
bool "PARITY_EVEN" |
||||||
|
help |
||||||
|
UART_PARITY_EVEN |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_ODD |
||||||
|
bool "PARITY_ODD" |
||||||
|
help |
||||||
|
UART_PARITY_ODD |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TASK_STACK_SIZE |
||||||
|
int "HCI uart task stack size" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1000 |
||||||
|
help |
||||||
|
Set the size of uart task stack |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT |
||||||
|
bool |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable NPL porting for controller. |
||||||
|
|
||||||
|
|
||||||
|
menuconfig BT_LE_50_FEATURE_SUPPORT |
||||||
|
bool "Enable BLE 5 feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE 5 feature |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_2M_PHY |
||||||
|
bool "Enable 2M Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable 2M-PHY |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
bool "Enable coded Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable coded-PHY |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV |
||||||
|
bool "Enable extended advertising" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable this option to do extended advertising. Extended advertising |
||||||
|
will be supported from BLE 5.0 onwards. |
||||||
|
|
||||||
|
if BT_LE_EXT_ADV |
||||||
|
config BT_LE_MAX_EXT_ADV_INSTANCES |
||||||
|
int "Maximum number of extended advertising instances." |
||||||
|
range 0 4 |
||||||
|
default 1 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Change this option to set maximum number of extended advertising |
||||||
|
instances. Minimum there is always one instance of |
||||||
|
advertising. Enter how many more advertising instances you |
||||||
|
want. |
||||||
|
Each extended advertising instance will take about 0.5k DRAM. |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
int "Maximum length of the advertising data." |
||||||
|
range 0 1650 |
||||||
|
default 1650 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Defines the length of the extended adv data. The value should not |
||||||
|
exceed 1650. |
||||||
|
|
||||||
|
config BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
bool "Enable periodic advertisement." |
||||||
|
default y |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Enable this option to start periodic advertisement. |
||||||
|
|
||||||
|
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER |
||||||
|
bool "Enable Transer Sync Events" |
||||||
|
depends on BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default y |
||||||
|
help |
||||||
|
This enables controller transfer periodic sync events to host |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_SYNCS |
||||||
|
int "Maximum number of periodic advertising syncs" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
range 0 3 |
||||||
|
default 1 if BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default 0 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic sync |
||||||
|
connections. This should be less than maximum connections allowed by |
||||||
|
controller. |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST |
||||||
|
int "Maximum number of periodic advertiser list" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
range 1 5 |
||||||
|
default 5 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic advertiser list. |
||||||
|
|
||||||
|
menu "Memory Settings" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_COUNT |
||||||
|
int "MSYS_1 Block Count" |
||||||
|
default 12 |
||||||
|
help |
||||||
|
MSYS is a system level mbuf registry. For prepare write & prepare |
||||||
|
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH |
||||||
|
enabled cases, this block count is increased by 8 than user defined |
||||||
|
count. |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_SIZE |
||||||
|
int "MSYS_1 Block Size" |
||||||
|
default 256 |
||||||
|
help |
||||||
|
Dynamic memory size of block 1 |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_COUNT |
||||||
|
int "MSYS_2 Block Count" |
||||||
|
default 24 |
||||||
|
help |
||||||
|
Dynamic memory count |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_SIZE |
||||||
|
int "MSYS_2 Block Size" |
||||||
|
default 320 |
||||||
|
help |
||||||
|
Dynamic memory size of block 2 |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_COUNT |
||||||
|
int "ACL Buffer count" |
||||||
|
default 10 |
||||||
|
help |
||||||
|
The number of ACL data buffers. |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_SIZE |
||||||
|
int "ACL Buffer size" |
||||||
|
default 517 |
||||||
|
help |
||||||
|
This is the maximum size of the data portion of HCI ACL data packets. |
||||||
|
It does not include the HCI data header (of 4 bytes) |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_BUF_SIZE |
||||||
|
int "HCI Event Buffer size" |
||||||
|
default 257 if BT_LE_EXT_ADV |
||||||
|
default 70 |
||||||
|
help |
||||||
|
This is the size of each HCI event buffer in bytes. In case of |
||||||
|
extended advertising, packets can be fragmented. 257 bytes is the |
||||||
|
maximum size of a packet. |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_HI_BUF_COUNT |
||||||
|
int "High Priority HCI Event Buffer count" |
||||||
|
default 30 |
||||||
|
help |
||||||
|
This is the high priority HCI events' buffer size. High-priority |
||||||
|
event buffers are for everything except advertising reports. If there |
||||||
|
are no free high-priority event buffers then host will try to allocate a |
||||||
|
low-priority buffer instead |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_LO_BUF_COUNT |
||||||
|
int "Low Priority HCI Event Buffer count" |
||||||
|
default 8 |
||||||
|
help |
||||||
|
This is the low priority HCI events' buffer size. Low-priority event |
||||||
|
buffers are only used for advertising reports. If there are no free |
||||||
|
low-priority event buffers, then an incoming advertising report will |
||||||
|
get dropped |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
int "Controller task stack size" |
||||||
|
default 5120 if BLE_MESH |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
This configures stack size of NimBLE controller task |
||||||
|
|
||||||
|
menuconfig BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
bool "Controller log enable" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable controller log |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED |
||||||
|
bool "enable controller log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable controller log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_HCI_ENABLED |
||||||
|
bool "enable HCI log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable hci log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_DUMP_ONLY |
||||||
|
bool "Controller log dump mode only" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Only operate in dump mode |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF1_SIZE |
||||||
|
int "size of the first BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the first BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF2_SIZE |
||||||
|
int "size of the second BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 1024 |
||||||
|
help |
||||||
|
Configure the size of the second BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_HCI_BUF_SIZE |
||||||
|
int "size of the BLE HCI LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the BLE HCI LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LL_RESOLV_LIST_SIZE |
||||||
|
int "BLE LL Resolving list size" |
||||||
|
range 1 5 |
||||||
|
default 4 |
||||||
|
help |
||||||
|
Configure the size of resolving list used in link layer. |
||||||
|
|
||||||
|
menuconfig BT_LE_SECURITY_ENABLE |
||||||
|
bool "Enable BLE SM feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE sm feature |
||||||
|
|
||||||
|
config BT_LE_SM_LEGACY |
||||||
|
bool "Security manager legacy pairing" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager legacy pairing |
||||||
|
|
||||||
|
config BT_LE_SM_SC |
||||||
|
bool "Security manager secure connections (4.2)" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager secure connections |
||||||
|
|
||||||
|
config BT_LE_SM_SC_DEBUG_KEYS |
||||||
|
bool "Use predefined public-private key pair" |
||||||
|
default n |
||||||
|
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC |
||||||
|
help |
||||||
|
If this option is enabled, SM uses predefined DH key pair as described |
||||||
|
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to |
||||||
|
decrypt air traffic easily and thus should only be used for debugging. |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION |
||||||
|
bool "Enable LE encryption" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable encryption connection |
||||||
|
|
||||||
|
config BT_LE_CRYPTO_STACK_MBEDTLS |
||||||
|
bool "Override TinyCrypt with mbedTLS for crypto computations" |
||||||
|
default y |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
select MBEDTLS_ECP_RESTARTABLE |
||||||
|
select MBEDTLS_CMAC_C |
||||||
|
help |
||||||
|
Enable this option to choose mbedTLS instead of TinyCrypt for crypto |
||||||
|
computations. |
||||||
|
|
||||||
|
config BT_LE_WHITELIST_SIZE |
||||||
|
int "BLE white list size" |
||||||
|
range 1 15 |
||||||
|
default 12 |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
help |
||||||
|
BLE list size |
||||||
|
|
||||||
|
config BT_LE_LL_DUP_SCAN_LIST_COUNT |
||||||
|
int "BLE duplicate scan list count" |
||||||
|
range 1 100 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
config the max count of duplicate scan list |
||||||
|
|
||||||
|
config BT_LE_LL_SCA |
||||||
|
int "BLE Sleep clock accuracy" |
||||||
|
range 0 500 |
||||||
|
default 60 |
||||||
|
help |
||||||
|
Sleep clock accuracy of our device (in ppm) |
||||||
|
|
||||||
|
config BT_LE_MAX_CONNECTIONS |
||||||
|
int "Maximum number of concurrent connections" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
range 1 2 |
||||||
|
default 2 |
||||||
|
help |
||||||
|
Defines maximum number of concurrent BLE connections. For ESP32, user |
||||||
|
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu |
||||||
|
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to |
||||||
|
configure BT_CTRL_BLE_MAX_ACT from controller menu. |
||||||
|
Each connection will take about 1k DRAM. |
||||||
|
|
||||||
|
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM |
||||||
|
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" |
||||||
|
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
depends on ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
help |
||||||
|
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to |
||||||
|
better avoid dramatic performance deterioration of Wi-Fi. |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
bool "Force Enable" |
||||||
|
help |
||||||
|
Always enable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
bool "Force Disable" |
||||||
|
help |
||||||
|
Disable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
int |
||||||
|
default 0 if !ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
|
||||||
|
config BT_LE_SLEEP_ENABLE |
||||||
|
bool "Enable BLE sleep" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable BLE sleep |
||||||
|
|
||||||
|
config BT_LE_USE_ESP_TIMER |
||||||
|
bool "Use Esp Timer for callout" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
bool "BLE adv report flow control supported" |
||||||
|
default y |
||||||
|
help |
||||||
|
The function is mainly used to enable flow control for advertising reports. When it is enabled, |
||||||
|
advertising reports will be discarded by the controller if the number of unprocessed advertising |
||||||
|
reports exceeds the size of BLE adv report flow control. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM |
||||||
|
int "BLE adv report flow control number" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 50 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
The number of unprocessed advertising report that bluetooth host can save.If you set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a |
||||||
|
lot of adv packets and this may cause system memory run out. For example, if you set |
||||||
|
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv |
||||||
|
packets as fast as possible, otherwise it will cause adv packets lost. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD |
||||||
|
int "BLE adv lost event threshold value" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 1 1000 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
When adv report flow control is enabled, The ADV lost event will be generated when the number |
||||||
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it |
||||||
|
may cause adv packets lost more. |
||||||
|
|
||||||
|
config BT_LE_RELEASE_IRAM_SUPPORTED |
||||||
|
bool |
||||||
|
default y |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,220 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ESP_BT_CFG_H__ |
||||||
|
#define __ESP_BT_CFG_H__ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include "esp_err.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
#include "syscfg/syscfg.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) |
||||||
|
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#else |
||||||
|
|
||||||
|
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) |
||||||
|
#endif |
||||||
|
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#else |
||||||
|
#define HCI_UART_EN 0 // hci ram mode
|
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#else |
||||||
|
#define NIMBLE_SLEEP_ENABLE 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
|
||||||
|
|
||||||
|
#if HCI_UART_EN |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Unchanged configuration */ |
||||||
|
|
||||||
|
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */ |
||||||
|
|
||||||
|
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376) |
||||||
|
|
||||||
|
#define BLE_LL_SUB_VERS_NR_N (0x0000) |
||||||
|
|
||||||
|
#define BLE_LL_JITTER_USECS_N (16) |
||||||
|
|
||||||
|
#define BLE_PHY_MAX_PWR_DBM_N (10) |
||||||
|
|
||||||
|
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000) |
||||||
|
|
||||||
|
#ifdef CONFIG_XTAL_FREQ_26 |
||||||
|
#define RTC_FREQ_N (40000) /* in Hz */ |
||||||
|
#else |
||||||
|
#define RTC_FREQ_N (32000) /* in Hz */ |
||||||
|
#endif // CONFIG_XTAL_FREQ_26
|
||||||
|
|
||||||
|
#define BLE_LL_TX_PWR_DBM_N (9) |
||||||
|
|
||||||
|
|
||||||
|
#define RUN_BQB_TEST (0) |
||||||
|
#define RUN_QA_TEST (0) |
||||||
|
#define NIMBLE_DISABLE_SCAN_BACKOFF (0) |
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* __ESP_BT_CFG_H__ */ |
@ -0,0 +1,477 @@ |
|||||||
|
config BT_CTRL_MODE_EFF |
||||||
|
int |
||||||
|
default 1 |
||||||
|
|
||||||
|
config BT_CTRL_BLE_MAX_ACT |
||||||
|
int "BLE Max Instances" |
||||||
|
default 6 |
||||||
|
range 1 10 |
||||||
|
help |
||||||
|
BLE maximum activities of bluetooth controller,both of connections, |
||||||
|
scan , sync and adv(periodic adv, multi-adv). Each instance needs to |
||||||
|
consume 828 bytes, you can save RAM by modifying the instance value |
||||||
|
according to actual needs. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_MAX_ACT_EFF |
||||||
|
int |
||||||
|
default BT_CTRL_BLE_MAX_ACT |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB |
||||||
|
int "BLE static ACL TX buffer numbers" |
||||||
|
range 0 12 |
||||||
|
default 0 |
||||||
|
help |
||||||
|
BLE ACL buffer have two methods to be allocated. One is persistent allocating |
||||||
|
(alloate when controller initialise, never free until controller de-initialise) |
||||||
|
another is dynamically allocating (allocate before TX and free after TX). |
||||||
|
|
||||||
|
choice BT_CTRL_PINNED_TO_CORE_CHOICE |
||||||
|
prompt "The cpu core which bluetooth controller run" |
||||||
|
depends on !FREERTOS_UNICORE |
||||||
|
help |
||||||
|
Specify the cpu core to run bluetooth controller. |
||||||
|
Can not specify no-affinity. |
||||||
|
|
||||||
|
config BT_CTRL_PINNED_TO_CORE_0 |
||||||
|
bool "Core 0 (PRO CPU)" |
||||||
|
config BT_CTRL_PINNED_TO_CORE_1 |
||||||
|
bool "Core 1 (APP CPU)" |
||||||
|
depends on !FREERTOS_UNICORE |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_PINNED_TO_CORE |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_PINNED_TO_CORE_0 |
||||||
|
default 1 if BT_CTRL_PINNED_TO_CORE_1 |
||||||
|
default 0 |
||||||
|
|
||||||
|
choice BT_CTRL_HCI_MODE_CHOICE |
||||||
|
prompt "HCI mode" |
||||||
|
help |
||||||
|
Specify HCI mode as VHCI or UART(H4) |
||||||
|
|
||||||
|
config BT_CTRL_HCI_MODE_VHCI |
||||||
|
bool "VHCI" |
||||||
|
help |
||||||
|
Normal option. Mostly, choose this VHCI when bluetooth host run on ESP32S3 or ESP32C3. |
||||||
|
|
||||||
|
config BT_CTRL_HCI_MODE_UART_H4 |
||||||
|
bool "UART(H4)" |
||||||
|
help |
||||||
|
If use external bluetooth host which run on other hardware and use UART as the HCI interface, |
||||||
|
choose this option. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_HCI_TL |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_HCI_MODE_UART_H4 |
||||||
|
default 1 if BT_CTRL_HCI_M0DE_VHCI |
||||||
|
default 1 |
||||||
|
help |
||||||
|
HCI mode as VHCI or UART(H4) |
||||||
|
|
||||||
|
config BT_CTRL_ADV_DUP_FILT_MAX |
||||||
|
int "The maxinum number of 5.0 extend duplicate scan filter" |
||||||
|
range 1 500 |
||||||
|
default 30 |
||||||
|
help |
||||||
|
The maxinum number of suplicate scan filter |
||||||
|
|
||||||
|
choice BT_BLE_CCA_MODE |
||||||
|
prompt "BLE CCA mode" |
||||||
|
default BT_BLE_CCA_MODE_NONE |
||||||
|
help |
||||||
|
Define BT BLE CCA mode |
||||||
|
|
||||||
|
config BT_BLE_CCA_MODE_NONE |
||||||
|
bool "NONE" |
||||||
|
config BT_BLE_CCA_MODE_HW |
||||||
|
bool "Hardware" |
||||||
|
config BT_BLE_CCA_MODE_SW |
||||||
|
bool "Software" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_BLE_CCA_MODE |
||||||
|
int |
||||||
|
default 0 if BT_BLE_CCA_MODE_NONE |
||||||
|
default 1 if BT_BLE_CCA_MODE_HW |
||||||
|
default 2 if BT_BLE_CCA_MODE_SW |
||||||
|
|
||||||
|
config BT_CTRL_HW_CCA_VAL |
||||||
|
int "CCA threshold value" |
||||||
|
range 20 100 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm. |
||||||
|
|
||||||
|
config BT_CTRL_HW_CCA_EFF |
||||||
|
int |
||||||
|
default 1 if BT_CTRL_HW_CCA |
||||||
|
default 0 |
||||||
|
help |
||||||
|
If other devices are sending packets in the air and the signal is strong, |
||||||
|
the packet hw to be sent this time is cancelled. |
||||||
|
|
||||||
|
choice BT_CTRL_CE_LENGTH_TYPE |
||||||
|
prompt "Connection event length determination method" |
||||||
|
help |
||||||
|
Specify connection event length determination |
||||||
|
|
||||||
|
config BT_CTRL_CE_LENGTH_TYPE_ORIG |
||||||
|
bool "ORIGINAL" |
||||||
|
config BT_CTRL_CE_LENGTH_TYPE_CE |
||||||
|
bool "Use CE parameter for HCI command" |
||||||
|
config BT_CTRL_CE_LENGTH_TYPE_SD |
||||||
|
bool "Use Espressif self-defined method" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_CE_LENGTH_TYPE_EFF |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_CE_LENGTH_TYPE_ORIG |
||||||
|
default 1 if BT_CTRL_CE_LENGTH_TYPE_CE |
||||||
|
default 2 if BT_CTRL_CE_LENGTH_TYPE_SD |
||||||
|
|
||||||
|
choice BT_CTRL_TX_ANTENNA_INDEX |
||||||
|
prompt "default Tx anntena used" |
||||||
|
help |
||||||
|
Specify default Tx antenna used for bluetooth |
||||||
|
|
||||||
|
config BT_CTRL_TX_ANTENNA_INDEX_0 |
||||||
|
bool "Antenna 0" |
||||||
|
config BT_CTRL_TX_ANTENNA_INDEX_1 |
||||||
|
bool "Antenna 1" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_TX_ANTENNA_INDEX_EFF |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_TX_ANTENNA_INDEX_0 |
||||||
|
default 1 if BT_CTRL_TX_ANTENNA_INDEX_1 |
||||||
|
|
||||||
|
choice BT_CTRL_RX_ANTENNA_INDEX |
||||||
|
prompt "default Rx anntena used" |
||||||
|
help |
||||||
|
Specify default Rx antenna used for bluetooth |
||||||
|
|
||||||
|
config BT_CTRL_RX_ANTENNA_INDEX_0 |
||||||
|
bool "Antenna 0" |
||||||
|
config BT_CTRL_RX_ANTENNA_INDEX_1 |
||||||
|
bool "Antenna 1" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_RX_ANTENNA_INDEX_EFF |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_RX_ANTENNA_INDEX_0 |
||||||
|
default 1 if BT_CTRL_RX_ANTENNA_INDEX_1 |
||||||
|
|
||||||
|
choice BT_CTRL_DFT_TX_POWER_LEVEL |
||||||
|
prompt "BLE default Tx power level" |
||||||
|
default BT_CTRL_DFT_TX_POWER_LEVEL_P9 |
||||||
|
help |
||||||
|
Specify default Tx power level |
||||||
|
|
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N24 |
||||||
|
bool "-24dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N21 |
||||||
|
bool "-21dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N18 |
||||||
|
bool "-18dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N15 |
||||||
|
bool "-15dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N12 |
||||||
|
bool "-12dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N9 |
||||||
|
bool "-9dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N6 |
||||||
|
bool "-6dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N3 |
||||||
|
bool "-3dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_N0 |
||||||
|
bool "0dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P3 |
||||||
|
bool "+3dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P6 |
||||||
|
bool "+6dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P9 |
||||||
|
bool "+9dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P12 |
||||||
|
bool "+12dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P15 |
||||||
|
bool "+15dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P18 |
||||||
|
bool "+18dBm" |
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_P21 |
||||||
|
bool "+21dBm" |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_DFT_TX_POWER_LEVEL_EFF |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_DFT_TX_POWER_LEVEL_N24 |
||||||
|
default 1 if BT_CTRL_DFT_TX_POWER_LEVEL_N21 |
||||||
|
default 2 if BT_CTRL_DFT_TX_POWER_LEVEL_N18 |
||||||
|
default 3 if BT_CTRL_DFT_TX_POWER_LEVEL_N15 |
||||||
|
default 4 if BT_CTRL_DFT_TX_POWER_LEVEL_N12 |
||||||
|
default 5 if BT_CTRL_DFT_TX_POWER_LEVEL_N9 |
||||||
|
default 6 if BT_CTRL_DFT_TX_POWER_LEVEL_N6 |
||||||
|
default 7 if BT_CTRL_DFT_TX_POWER_LEVEL_N3 |
||||||
|
default 8 if BT_CTRL_DFT_TX_POWER_LEVEL_N0 |
||||||
|
default 9 if BT_CTRL_DFT_TX_POWER_LEVEL_P3 |
||||||
|
default 10 if BT_CTRL_DFT_TX_POWER_LEVEL_P6 |
||||||
|
default 11 if BT_CTRL_DFT_TX_POWER_LEVEL_P9 |
||||||
|
default 12 if BT_CTRL_DFT_TX_POWER_LEVEL_P12 |
||||||
|
default 13 if BT_CTRL_DFT_TX_POWER_LEVEL_P15 |
||||||
|
default 14 if BT_CTRL_DFT_TX_POWER_LEVEL_P18 |
||||||
|
default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P21 |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
bool "BLE adv report flow control supported" |
||||||
|
default y |
||||||
|
help |
||||||
|
The function is mainly used to enable flow control for advertising reports. When it is enabled, |
||||||
|
advertising reports will be discarded by the controller if the number of unprocessed advertising |
||||||
|
reports exceeds the size of BLE adv report flow control. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM |
||||||
|
int "BLE adv report flow control number" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 50 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
The number of unprocessed advertising report that bluetooth host can save.If you set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a |
||||||
|
lot of adv packets and this may cause system memory run out. For example, if you set |
||||||
|
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv |
||||||
|
packets as fast as possible, otherwise it will cause adv packets lost. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD |
||||||
|
int "BLE adv lost event threshold value" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 1 1000 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
When adv report flow control is enabled, The ADV lost event will be generated when the number |
||||||
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it |
||||||
|
may cause adv packets lost more. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_SCAN_DUPL |
||||||
|
bool "BLE Scan Duplicate Options" |
||||||
|
default y |
||||||
|
help |
||||||
|
This select enables parameters setting of BLE scan duplicate. |
||||||
|
|
||||||
|
choice BT_CTRL_SCAN_DUPL_TYPE |
||||||
|
prompt "Scan Duplicate Type" |
||||||
|
default BT_CTRL_SCAN_DUPL_TYPE_DEVICE |
||||||
|
depends on BT_CTRL_BLE_SCAN_DUPL |
||||||
|
help |
||||||
|
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use |
||||||
|
advertiser address filtering. The adv packet of the same address is only allowed to be reported once. |
||||||
|
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising |
||||||
|
data and device address filtering. All different adv packets with the same address are allowed to be |
||||||
|
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data |
||||||
|
filtering. All same advertising data only allow to be reported once even though they are from |
||||||
|
different devices. |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_DUPL_TYPE_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address" |
||||||
|
help |
||||||
|
Advertising packets with the same address, address type, and advertising type are reported once. |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_DUPL_TYPE_DATA |
||||||
|
bool "Scan Duplicate By Advertising Data" |
||||||
|
help |
||||||
|
Advertising packets with identical advertising data, address type, and advertising type |
||||||
|
are reported only once, even if they originate from different devices. |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address And Advertising Data" |
||||||
|
help |
||||||
|
Advertising packets with the same address, advertising data, address type, |
||||||
|
and advertising type are reported only once. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_DUPL_TYPE |
||||||
|
int |
||||||
|
depends on BT_CTRL_BLE_SCAN_DUPL |
||||||
|
default 0 if BT_CTRL_SCAN_DUPL_TYPE_DEVICE |
||||||
|
default 1 if BT_CTRL_SCAN_DUPL_TYPE_DATA |
||||||
|
default 2 if BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_DUPL_CACHE_SIZE |
||||||
|
int "Maximum number of devices in scan duplicate filter" |
||||||
|
depends on BT_CTRL_BLE_SCAN_DUPL |
||||||
|
range 10 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
Maximum number of devices which can be recorded in scan duplicate filter. |
||||||
|
When the maximum amount of device in the filter is reached, the cache will be refreshed. |
||||||
|
|
||||||
|
config BT_CTRL_DUPL_SCAN_CACHE_REFRESH_PERIOD |
||||||
|
int "Duplicate scan list refresh period (seconds)" |
||||||
|
depends on BT_CTRL_BLE_SCAN_DUPL |
||||||
|
range 0 1000 |
||||||
|
default 0 |
||||||
|
help |
||||||
|
If the period value is non-zero, the controller will periodically clear the device information |
||||||
|
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared |
||||||
|
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the |
||||||
|
Host in advertising report events. |
||||||
|
There are two scenarios where the ADV packet will be repeatedly reported: |
||||||
|
1. The duplicate scan cache is full, the controller will delete the oldest device information and |
||||||
|
add new device information. |
||||||
|
2. When the refresh period is up, the controller will clear all device information and start filtering |
||||||
|
again. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_MESH_SCAN_DUPL_EN |
||||||
|
bool "Special duplicate scan mechanism for BLE Mesh scan" |
||||||
|
depends on BT_CTRL_BLE_SCAN_DUPL |
||||||
|
default n |
||||||
|
help |
||||||
|
This enables the BLE scan duplicate for special BLE Mesh scan. |
||||||
|
|
||||||
|
config BT_CTRL_MESH_DUPL_SCAN_CACHE_SIZE |
||||||
|
int "Maximum number of Mesh adv packets in scan duplicate filter" |
||||||
|
depends on BT_CTRL_BLE_MESH_SCAN_DUPL_EN |
||||||
|
range 10 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh. |
||||||
|
When the maximum amount of device in the filter is reached, the cache will be refreshed. |
||||||
|
|
||||||
|
choice BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM |
||||||
|
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" |
||||||
|
default BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
depends on ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
help |
||||||
|
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to |
||||||
|
better avoid dramatic performance deterioration of Wi-Fi. |
||||||
|
|
||||||
|
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
bool "Force Enable" |
||||||
|
help |
||||||
|
Always enable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
|
||||||
|
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
bool "Force Disable" |
||||||
|
help |
||||||
|
Disable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
int |
||||||
|
default 0 if !ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
default 1 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
default 0 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
|
||||||
|
menu "MODEM SLEEP Options" |
||||||
|
visible if BT_ENABLED |
||||||
|
|
||||||
|
config BT_CTRL_MODEM_SLEEP |
||||||
|
bool "Bluetooth modem sleep" |
||||||
|
depends on !BT_CTRL_HCI_MODE_UART_H4 |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable/disable bluetooth controller low power mode. |
||||||
|
Modem sleep is not supported to be used with UART HCI. |
||||||
|
|
||||||
|
config BT_CTRL_MODEM_SLEEP_MODE_1 |
||||||
|
bool "Bluetooth Modem sleep Mode 1" |
||||||
|
depends on BT_CTRL_MODEM_SLEEP |
||||||
|
default y |
||||||
|
help |
||||||
|
Mode 1 is the currently supported sleep mode. In this mode, |
||||||
|
bluetooth controller sleeps between and BLE events. A low |
||||||
|
power clock is used to maintain bluetooth reference clock. |
||||||
|
|
||||||
|
choice BT_CTRL_LOW_POWER_CLOCK |
||||||
|
prompt "Bluetooth low power clock" |
||||||
|
depends on BT_CTRL_MODEM_SLEEP_MODE_1 |
||||||
|
help |
||||||
|
Select the low power clock source for bluetooth controller |
||||||
|
|
||||||
|
config BT_CTRL_LPCLK_SEL_MAIN_XTAL |
||||||
|
bool "Main crystal" |
||||||
|
help |
||||||
|
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is |
||||||
|
selected, bluetooth modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, and |
||||||
|
bluetooth can work under light sleep enabled. Main crystal has a relatively better performance |
||||||
|
than other bluetooth low power clock sources. |
||||||
|
config BT_CTRL_LPCLK_SEL_EXT_32K_XTAL |
||||||
|
bool "External 32kHz crystal" |
||||||
|
depends on RTC_CLK_SRC_EXT_CRYS |
||||||
|
help |
||||||
|
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency |
||||||
|
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth |
||||||
|
modem sleep to be used with both DFS and light sleep. |
||||||
|
|
||||||
|
config BT_CTRL_LPCLK_SEL_RTC_SLOW |
||||||
|
bool "Internal 150kHz RC oscillator" |
||||||
|
depends on RTC_CLK_SRC_INT_RC |
||||||
|
help |
||||||
|
Internal 150kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is required |
||||||
|
in Bluetooth communication, so don't select this option in scenarios such as BLE connection state. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP |
||||||
|
bool "power up main XTAL during light sleep" |
||||||
|
depends on (BT_CTRL_LPCLK_SEL_MAIN_XTAL || BT_CTRL_LPCLK_SEL_EXT_32K_XTAL) && FREERTOS_USE_TICKLESS_IDLE |
||||||
|
default n |
||||||
|
help |
||||||
|
If this option is selected, the main crystal will power up during light sleep when the low power clock |
||||||
|
selects an external 32kHz crystal but the external 32kHz crystal does not exist or the low power clock |
||||||
|
selects the main crystal. |
||||||
|
|
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_CTRL_SLEEP_MODE_EFF |
||||||
|
int |
||||||
|
default 1 if BT_CTRL_MODEM_SLEEP_MODE_1 |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_CTRL_SLEEP_CLOCK_EFF |
||||||
|
int |
||||||
|
default 1 if BT_CTRL_LPCLK_SEL_MAIN_XTAL |
||||||
|
default 2 if BT_CTRL_LPCLK_SEL_EXT_32K_XTAL |
||||||
|
default 3 if BT_CTRL_LPCLK_SEL_RTC_SLOW |
||||||
|
|
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_CTRL_HCI_TL_EFF |
||||||
|
int |
||||||
|
default 0 if BT_CTRL_HCI_MODE_UART_H4 |
||||||
|
default 1 if BT_CTRL_HCI_M0DE_VHCI |
||||||
|
default 1 |
||||||
|
|
||||||
|
config BT_CTRL_AGC_RECORRECT_EN |
||||||
|
bool "Enable HW AGC recorrect" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable uncoded phy AGC recorrect |
||||||
|
|
||||||
|
config BT_CTRL_CODED_AGC_RECORRECT_EN |
||||||
|
bool "Enable coded phy AGC recorrect" |
||||||
|
depends on BT_CTRL_AGC_RECORRECT_EN |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable coded phy AGC recorrect |
||||||
|
|
||||||
|
config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX |
||||||
|
bool "Disable active scan backoff" |
||||||
|
default n |
||||||
|
help |
||||||
|
Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to |
||||||
|
minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active |
||||||
|
scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU. |
||||||
|
|
||||||
|
config BT_BLE_ADV_DATA_LENGTH_ZERO_AUX |
||||||
|
bool "Enable aux packet when ext adv data length is zero" |
||||||
|
default n |
||||||
|
help |
||||||
|
When this option is enabled, auxiliary packets will be present in the events of |
||||||
|
'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0. |
||||||
|
If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0. |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,564 @@ |
|||||||
|
|
||||||
|
menu "HCI Config" |
||||||
|
|
||||||
|
choice BT_LE_HCI_INTERFACE |
||||||
|
prompt "Select HCI interface" |
||||||
|
default BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
|
||||||
|
config BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
bool "ram" |
||||||
|
help |
||||||
|
Use RAM as HCI interface |
||||||
|
config BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
bool "uart" |
||||||
|
help |
||||||
|
Use UART as HCI interface |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_PORT |
||||||
|
int "HCI UART port" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1 |
||||||
|
help |
||||||
|
Set the port number of HCI UART |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_FLOWCTRL |
||||||
|
bool "HCI uart Hardware Flow ctrl" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default n |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TX_PIN |
||||||
|
int "HCI uart Tx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 19 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RX_PIN |
||||||
|
int "HCI uart Rx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 10 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RTS_PIN |
||||||
|
int "HCI uart RTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 4 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_CTS_PIN |
||||||
|
int "HCI uart CTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 5 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_BAUD |
||||||
|
int "HCI uart baudrate" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 921600 |
||||||
|
help |
||||||
|
HCI uart baud rate 115200 ~ 1000000 |
||||||
|
|
||||||
|
choice BT_LE_HCI_UART_PARITY |
||||||
|
prompt "select uart parity" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
bool "PARITY_DISABLE" |
||||||
|
help |
||||||
|
UART_PARITY_DISABLE |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_EVEN |
||||||
|
bool "PARITY_EVEN" |
||||||
|
help |
||||||
|
UART_PARITY_EVEN |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_ODD |
||||||
|
bool "PARITY_ODD" |
||||||
|
help |
||||||
|
UART_PARITY_ODD |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TASK_STACK_SIZE |
||||||
|
int "HCI uart task stack size" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1000 |
||||||
|
help |
||||||
|
Set the size of uart task stack |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT |
||||||
|
bool |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable NPL porting for controller. |
||||||
|
|
||||||
|
|
||||||
|
menuconfig BT_LE_50_FEATURE_SUPPORT |
||||||
|
bool "Enable BLE 5 feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE 5 feature |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_2M_PHY |
||||||
|
bool "Enable 2M Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable 2M-PHY |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
bool "Enable coded Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable coded-PHY |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV |
||||||
|
bool "Enable extended advertising" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable this option to do extended advertising. Extended advertising |
||||||
|
will be supported from BLE 5.0 onwards. |
||||||
|
|
||||||
|
if BT_LE_EXT_ADV |
||||||
|
config BT_LE_MAX_EXT_ADV_INSTANCES |
||||||
|
int "Maximum number of extended advertising instances." |
||||||
|
range 0 4 |
||||||
|
default 1 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Change this option to set maximum number of extended advertising |
||||||
|
instances. Minimum there is always one instance of |
||||||
|
advertising. Enter how many more advertising instances you |
||||||
|
want. |
||||||
|
Each extended advertising instance will take about 0.5k DRAM. |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
int "Maximum length of the advertising data." |
||||||
|
range 0 1650 |
||||||
|
default 1650 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Defines the length of the extended adv data. The value should not |
||||||
|
exceed 1650. |
||||||
|
|
||||||
|
config BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
bool "Enable periodic advertisement." |
||||||
|
default y |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Enable this option to start periodic advertisement. |
||||||
|
|
||||||
|
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER |
||||||
|
bool "Enable Transer Sync Events" |
||||||
|
depends on BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default y |
||||||
|
help |
||||||
|
This enables controller transfer periodic sync events to host |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_SYNCS |
||||||
|
int "Maximum number of periodic advertising syncs" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
range 0 8 |
||||||
|
default 1 if BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default 0 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic sync |
||||||
|
connections. This should be less than maximum connections allowed by |
||||||
|
controller. |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST |
||||||
|
int "Maximum number of periodic advertiser list" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
range 1 5 |
||||||
|
default 5 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic advertiser list. |
||||||
|
|
||||||
|
config BT_LE_POWER_CONTROL_ENABLED |
||||||
|
bool "Enable controller support for BLE Power Control" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED && IDF_TARGET_ESP32C6 |
||||||
|
default n |
||||||
|
help |
||||||
|
Set this option to enable the Power Control feature on controller |
||||||
|
|
||||||
|
menu "Memory Settings" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_COUNT |
||||||
|
int "MSYS_1 Block Count" |
||||||
|
default 12 |
||||||
|
help |
||||||
|
MSYS is a system level mbuf registry. For prepare write & prepare |
||||||
|
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH |
||||||
|
enabled cases, this block count is increased by 8 than user defined |
||||||
|
count. |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_SIZE |
||||||
|
int "MSYS_1 Block Size" |
||||||
|
default 256 |
||||||
|
help |
||||||
|
Dynamic memory size of block 1 |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_COUNT |
||||||
|
int "MSYS_2 Block Count" |
||||||
|
default 24 |
||||||
|
help |
||||||
|
Dynamic memory count |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_SIZE |
||||||
|
int "MSYS_2 Block Size" |
||||||
|
default 320 |
||||||
|
help |
||||||
|
Dynamic memory size of block 2 |
||||||
|
|
||||||
|
config BT_LE_MSYS_BUF_FROM_HEAP |
||||||
|
bool "Get Msys Mbuf from heap" |
||||||
|
default y |
||||||
|
depends on BT_LE_MSYS_INIT_IN_CONTROLLER |
||||||
|
help |
||||||
|
This option sets the source of the shared msys mbuf memory between |
||||||
|
the Host and the Controller. Allocate the memory from the heap if |
||||||
|
this option is sets, from the mempool otherwise. |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_COUNT |
||||||
|
int "ACL Buffer count" |
||||||
|
default 10 |
||||||
|
help |
||||||
|
The number of ACL data buffers. |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_SIZE |
||||||
|
int "ACL Buffer size" |
||||||
|
default 517 |
||||||
|
help |
||||||
|
This is the maximum size of the data portion of HCI ACL data packets. |
||||||
|
It does not include the HCI data header (of 4 bytes) |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_BUF_SIZE |
||||||
|
int "HCI Event Buffer size" |
||||||
|
default 257 if BT_LE_EXT_ADV |
||||||
|
default 70 |
||||||
|
help |
||||||
|
This is the size of each HCI event buffer in bytes. In case of |
||||||
|
extended advertising, packets can be fragmented. 257 bytes is the |
||||||
|
maximum size of a packet. |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_HI_BUF_COUNT |
||||||
|
int "High Priority HCI Event Buffer count" |
||||||
|
default 30 |
||||||
|
help |
||||||
|
This is the high priority HCI events' buffer size. High-priority |
||||||
|
event buffers are for everything except advertising reports. If there |
||||||
|
are no free high-priority event buffers then host will try to allocate a |
||||||
|
low-priority buffer instead |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_LO_BUF_COUNT |
||||||
|
int "Low Priority HCI Event Buffer count" |
||||||
|
default 8 |
||||||
|
help |
||||||
|
This is the low priority HCI events' buffer size. Low-priority event |
||||||
|
buffers are only used for advertising reports. If there are no free |
||||||
|
low-priority event buffers, then an incoming advertising report will |
||||||
|
get dropped |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
int "Controller task stack size" |
||||||
|
default 5120 if BLE_MESH |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
This configures stack size of NimBLE controller task |
||||||
|
|
||||||
|
menuconfig BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
bool "Controller log enable" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable controller log |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED |
||||||
|
bool "enable controller log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable controller log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_HCI_ENABLED |
||||||
|
bool "enable HCI log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable hci log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_DUMP_ONLY |
||||||
|
bool "Controller log dump mode only" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Only operate in dump mode |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF1_SIZE |
||||||
|
int "size of the first BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the first BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF2_SIZE |
||||||
|
int "size of the second BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 1024 |
||||||
|
help |
||||||
|
Configure the size of the second BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_HCI_BUF_SIZE |
||||||
|
int "size of the BLE HCI LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the BLE HCI LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LL_RESOLV_LIST_SIZE |
||||||
|
int "BLE LL Resolving list size" |
||||||
|
range 1 5 |
||||||
|
default 4 |
||||||
|
help |
||||||
|
Configure the size of resolving list used in link layer. |
||||||
|
|
||||||
|
menuconfig BT_LE_SECURITY_ENABLE |
||||||
|
bool "Enable BLE SM feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE sm feature |
||||||
|
|
||||||
|
config BT_LE_SM_LEGACY |
||||||
|
bool "Security manager legacy pairing" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager legacy pairing |
||||||
|
|
||||||
|
config BT_LE_SM_SC |
||||||
|
bool "Security manager secure connections (4.2)" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager secure connections |
||||||
|
|
||||||
|
config BT_LE_SM_SC_DEBUG_KEYS |
||||||
|
bool "Use predefined public-private key pair" |
||||||
|
default n |
||||||
|
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC |
||||||
|
help |
||||||
|
If this option is enabled, SM uses predefined DH key pair as described |
||||||
|
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to |
||||||
|
decrypt air traffic easily and thus should only be used for debugging. |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION |
||||||
|
bool "Enable LE encryption" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable encryption connection |
||||||
|
|
||||||
|
config BT_LE_CRYPTO_STACK_MBEDTLS |
||||||
|
bool "Override TinyCrypt with mbedTLS for crypto computations" |
||||||
|
default y |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
select MBEDTLS_ECP_RESTARTABLE |
||||||
|
select MBEDTLS_CMAC_C |
||||||
|
help |
||||||
|
Enable this option to choose mbedTLS instead of TinyCrypt for crypto |
||||||
|
computations. |
||||||
|
|
||||||
|
config BT_LE_WHITELIST_SIZE |
||||||
|
int "BLE white list size" |
||||||
|
range 1 15 |
||||||
|
default 12 |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
help |
||||||
|
BLE list size |
||||||
|
|
||||||
|
config BT_LE_LL_DUP_SCAN_LIST_COUNT |
||||||
|
int "BLE duplicate scan list count" |
||||||
|
range 5 100 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
config the max count of duplicate scan list |
||||||
|
|
||||||
|
config BT_LE_LL_SCA |
||||||
|
int "BLE Sleep clock accuracy" |
||||||
|
range 0 500 |
||||||
|
default 60 |
||||||
|
help |
||||||
|
Sleep clock accuracy of our device (in ppm) |
||||||
|
|
||||||
|
config BT_LE_MAX_CONNECTIONS |
||||||
|
int "Maximum number of concurrent connections" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
range 1 70 |
||||||
|
default 3 |
||||||
|
help |
||||||
|
Defines maximum number of concurrent BLE connections. For ESP32, user |
||||||
|
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu |
||||||
|
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to |
||||||
|
configure BT_CTRL_BLE_MAX_ACT from controller menu. |
||||||
|
Each connection will take about 1k DRAM. |
||||||
|
|
||||||
|
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM |
||||||
|
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" |
||||||
|
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
depends on ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
help |
||||||
|
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to |
||||||
|
better avoid dramatic performance deterioration of Wi-Fi. |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
bool "Force Enable" |
||||||
|
help |
||||||
|
Always enable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
bool "Force Disable" |
||||||
|
help |
||||||
|
Disable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
int |
||||||
|
default 0 if !ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
|
||||||
|
config BT_LE_SLEEP_ENABLE |
||||||
|
bool "Enable BLE sleep" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable BLE sleep |
||||||
|
|
||||||
|
choice BT_LE_LP_CLK_SRC |
||||||
|
prompt "BLE low power clock source" |
||||||
|
default BT_LE_LP_CLK_SRC_MAIN_XTAL |
||||||
|
config BT_LE_LP_CLK_SRC_MAIN_XTAL |
||||||
|
bool "Use main XTAL as RTC clock source" |
||||||
|
help |
||||||
|
User main XTAL as RTC clock source. |
||||||
|
This option is recommended if external 32.768k XTAL is not available. |
||||||
|
Using the external 32.768 kHz XTAL will have lower current consumption |
||||||
|
in light sleep compared to using the main XTAL. |
||||||
|
|
||||||
|
config BT_LE_LP_CLK_SRC_DEFAULT |
||||||
|
bool "Use system RTC slow clock source" |
||||||
|
help |
||||||
|
Use the same slow clock source as system RTC |
||||||
|
Using any clock source other than external 32.768 kHz XTAL supports only |
||||||
|
legacy ADV and SCAN due to low clock accuracy. |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_USE_ESP_TIMER |
||||||
|
bool "Enable Esp Timer for Callout" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Set this option to use Esp Timer which has higher priority timer |
||||||
|
instead of FreeRTOS timer |
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
bool "BLE adv report flow control supported" |
||||||
|
default y |
||||||
|
help |
||||||
|
The function is mainly used to enable flow control for advertising reports. When it is enabled, |
||||||
|
advertising reports will be discarded by the controller if the number of unprocessed advertising |
||||||
|
reports exceeds the size of BLE adv report flow control. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM |
||||||
|
int "BLE adv report flow control number" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 50 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
The number of unprocessed advertising report that bluetooth host can save.If you set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a |
||||||
|
lot of adv packets and this may cause system memory run out. For example, if you set |
||||||
|
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv |
||||||
|
packets as fast as possible, otherwise it will cause adv packets lost. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD |
||||||
|
int "BLE adv lost event threshold value" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 1 1000 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
When adv report flow control is enabled, The ADV lost event will be generated when the number |
||||||
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it |
||||||
|
may cause adv packets lost more. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL |
||||||
|
bool "BLE Scan Duplicate Options" |
||||||
|
default y |
||||||
|
help |
||||||
|
This select enables parameters setting of BLE scan duplicate. |
||||||
|
|
||||||
|
choice BT_LE_SCAN_DUPL_TYPE |
||||||
|
prompt "Scan Duplicate Type" |
||||||
|
default BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
help |
||||||
|
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use |
||||||
|
advertiser address filtering. The adv packet of the same address is only allowed to be reported once. |
||||||
|
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising |
||||||
|
data and device address filtering. All different adv packets with the same address are allowed to be |
||||||
|
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data |
||||||
|
filtering. All same advertising data only allow to be reported once even though they are from |
||||||
|
different devices. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address" |
||||||
|
help |
||||||
|
This way is to use advertiser address filtering. The adv packet of the same address is only |
||||||
|
allowed to be reported once |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DATA |
||||||
|
bool "Scan Duplicate By Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data filtering. All same advertising data only allow to be reported |
||||||
|
once even though they are from different devices. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address And Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data and device address filtering. All different adv packets with |
||||||
|
the same address are allowed to be reported. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE |
||||||
|
int |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
default 0 if BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
default 1 if BT_LE_SCAN_DUPL_TYPE_DATA |
||||||
|
default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD |
||||||
|
int "Duplicate scan list refresh period (seconds)" |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
range 0 1000 |
||||||
|
default 0 |
||||||
|
help |
||||||
|
If the period value is non-zero, the controller will periodically clear the device information |
||||||
|
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared |
||||||
|
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the |
||||||
|
Host in advertising report events. |
||||||
|
There are two scenarios where the ADV packet will be repeatedly reported: |
||||||
|
1. The duplicate scan cache is full, the controller will delete the oldest device information and |
||||||
|
add new device information. |
||||||
|
2. When the refresh period is up, the controller will clear all device information and start filtering |
||||||
|
again. |
||||||
|
|
||||||
|
config BT_LE_MSYS_INIT_IN_CONTROLLER |
||||||
|
bool "Msys Mbuf Init in Controller" |
||||||
|
default y |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,219 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ESP_BT_CFG_H__ |
||||||
|
#define __ESP_BT_CFG_H__ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include "esp_err.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
#include "syscfg/syscfg.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL) |
||||||
|
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
#else |
||||||
|
|
||||||
|
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED) |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) |
||||||
|
#endif |
||||||
|
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#else |
||||||
|
#define HCI_UART_EN 0 // hci ram mode
|
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#else |
||||||
|
#define NIMBLE_SLEEP_ENABLE 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
|
||||||
|
|
||||||
|
#if HCI_UART_EN |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Unchanged configuration */ |
||||||
|
|
||||||
|
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */ |
||||||
|
|
||||||
|
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376) |
||||||
|
|
||||||
|
#define BLE_LL_SUB_VERS_NR_N (0x0000) |
||||||
|
|
||||||
|
#define BLE_LL_JITTER_USECS_N (16) |
||||||
|
|
||||||
|
#define BLE_PHY_MAX_PWR_DBM_N (10) |
||||||
|
|
||||||
|
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000) |
||||||
|
|
||||||
|
#define RTC_FREQ_N (32768) /* in Hz */ |
||||||
|
|
||||||
|
#define BLE_LL_TX_PWR_DBM_N (9) |
||||||
|
|
||||||
|
|
||||||
|
#define RUN_BQB_TEST (0) |
||||||
|
#define RUN_QA_TEST (0) |
||||||
|
#define NIMBLE_DISABLE_SCAN_BACKOFF (0) |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* __ESP_BT_CFG_H__ */ |
@ -0,0 +1,556 @@ |
|||||||
|
|
||||||
|
menu "HCI Config" |
||||||
|
|
||||||
|
choice BT_LE_HCI_INTERFACE |
||||||
|
prompt "Select HCI interface" |
||||||
|
default BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
|
||||||
|
config BT_LE_HCI_INTERFACE_USE_RAM |
||||||
|
bool "ram" |
||||||
|
help |
||||||
|
Use RAM as HCI interface |
||||||
|
config BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
bool "uart" |
||||||
|
help |
||||||
|
Use UART as HCI interface |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_PORT |
||||||
|
int "HCI UART port" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1 |
||||||
|
help |
||||||
|
Set the port number of HCI UART |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_FLOWCTRL |
||||||
|
bool "HCI uart Hardware Flow ctrl" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default n |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TX_PIN |
||||||
|
int "HCI uart Tx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 19 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RX_PIN |
||||||
|
int "HCI uart Rx gpio" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 10 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_RTS_PIN |
||||||
|
int "HCI uart RTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 4 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_CTS_PIN |
||||||
|
int "HCI uart CTS gpio" |
||||||
|
depends on BT_LE_HCI_UART_FLOWCTRL |
||||||
|
default 5 |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_BAUD |
||||||
|
int "HCI uart baudrate" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 921600 |
||||||
|
help |
||||||
|
HCI uart baud rate 115200 ~ 1000000 |
||||||
|
|
||||||
|
choice BT_LE_HCI_UART_PARITY |
||||||
|
prompt "select uart parity" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_UART_PARITY_DISABLE |
||||||
|
bool "PARITY_DISABLE" |
||||||
|
help |
||||||
|
UART_PARITY_DISABLE |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_EVEN |
||||||
|
bool "PARITY_EVEN" |
||||||
|
help |
||||||
|
UART_PARITY_EVEN |
||||||
|
config BT_LE_HCI_UART_UART_PARITY_ODD |
||||||
|
bool "PARITY_ODD" |
||||||
|
help |
||||||
|
UART_PARITY_ODD |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_HCI_UART_TASK_STACK_SIZE |
||||||
|
int "HCI uart task stack size" |
||||||
|
depends on BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
default 1000 |
||||||
|
help |
||||||
|
Set the size of uart task stack |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT |
||||||
|
bool |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable NPL porting for controller. |
||||||
|
|
||||||
|
|
||||||
|
menuconfig BT_LE_50_FEATURE_SUPPORT |
||||||
|
bool "Enable BLE 5 feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE 5 feature |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_2M_PHY |
||||||
|
bool "Enable 2M Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable 2M-PHY |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
bool "Enable coded Phy" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable coded-PHY |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV |
||||||
|
bool "Enable extended advertising" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable this option to do extended advertising. Extended advertising |
||||||
|
will be supported from BLE 5.0 onwards. |
||||||
|
|
||||||
|
if BT_LE_EXT_ADV |
||||||
|
config BT_LE_MAX_EXT_ADV_INSTANCES |
||||||
|
int "Maximum number of extended advertising instances." |
||||||
|
range 0 4 |
||||||
|
default 1 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Change this option to set maximum number of extended advertising |
||||||
|
instances. Minimum there is always one instance of |
||||||
|
advertising. Enter how many more advertising instances you |
||||||
|
want. |
||||||
|
Each extended advertising instance will take about 0.5k DRAM. |
||||||
|
|
||||||
|
config BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
int "Maximum length of the advertising data." |
||||||
|
range 0 1650 |
||||||
|
default 1650 |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Defines the length of the extended adv data. The value should not |
||||||
|
exceed 1650. |
||||||
|
|
||||||
|
config BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
bool "Enable periodic advertisement." |
||||||
|
default y |
||||||
|
depends on BT_LE_EXT_ADV |
||||||
|
help |
||||||
|
Enable this option to start periodic advertisement. |
||||||
|
|
||||||
|
config BT_LE_PERIODIC_ADV_SYNC_TRANSFER |
||||||
|
bool "Enable Transer Sync Events" |
||||||
|
depends on BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default y |
||||||
|
help |
||||||
|
This enables controller transfer periodic sync events to host |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_SYNCS |
||||||
|
int "Maximum number of periodic advertising syncs" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
range 0 8 |
||||||
|
default 1 if BT_LE_ENABLE_PERIODIC_ADV |
||||||
|
default 0 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic sync |
||||||
|
connections. This should be less than maximum connections allowed by |
||||||
|
controller. |
||||||
|
|
||||||
|
config BT_LE_MAX_PERIODIC_ADVERTISER_LIST |
||||||
|
int "Maximum number of periodic advertiser list" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
range 1 5 |
||||||
|
default 5 |
||||||
|
help |
||||||
|
Set this option to set the upper limit for number of periodic advertiser list. |
||||||
|
|
||||||
|
config BT_LE_POWER_CONTROL_ENABLED |
||||||
|
bool "Enable controller support for BLE Power Control" |
||||||
|
depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED |
||||||
|
default n |
||||||
|
help |
||||||
|
Set this option to enable the Power Control feature on controller |
||||||
|
|
||||||
|
menu "Memory Settings" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_COUNT |
||||||
|
int "MSYS_1 Block Count" |
||||||
|
default 12 |
||||||
|
help |
||||||
|
MSYS is a system level mbuf registry. For prepare write & prepare |
||||||
|
responses MBUFs are allocated out of msys_1 pool. For NIMBLE_MESH |
||||||
|
enabled cases, this block count is increased by 8 than user defined |
||||||
|
count. |
||||||
|
|
||||||
|
config BT_LE_MSYS_1_BLOCK_SIZE |
||||||
|
int "MSYS_1 Block Size" |
||||||
|
default 256 |
||||||
|
help |
||||||
|
Dynamic memory size of block 1 |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_COUNT |
||||||
|
int "MSYS_2 Block Count" |
||||||
|
default 24 |
||||||
|
help |
||||||
|
Dynamic memory count |
||||||
|
|
||||||
|
config BT_LE_MSYS_2_BLOCK_SIZE |
||||||
|
int "MSYS_2 Block Size" |
||||||
|
default 320 |
||||||
|
help |
||||||
|
Dynamic memory size of block 2 |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_COUNT |
||||||
|
int "ACL Buffer count" |
||||||
|
default 10 |
||||||
|
help |
||||||
|
The number of ACL data buffers. |
||||||
|
|
||||||
|
config BT_LE_ACL_BUF_SIZE |
||||||
|
int "ACL Buffer size" |
||||||
|
default 517 |
||||||
|
help |
||||||
|
This is the maximum size of the data portion of HCI ACL data packets. |
||||||
|
It does not include the HCI data header (of 4 bytes) |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_BUF_SIZE |
||||||
|
int "HCI Event Buffer size" |
||||||
|
default 257 if BT_LE_EXT_ADV |
||||||
|
default 70 |
||||||
|
help |
||||||
|
This is the size of each HCI event buffer in bytes. In case of |
||||||
|
extended advertising, packets can be fragmented. 257 bytes is the |
||||||
|
maximum size of a packet. |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_HI_BUF_COUNT |
||||||
|
int "High Priority HCI Event Buffer count" |
||||||
|
default 30 |
||||||
|
help |
||||||
|
This is the high priority HCI events' buffer size. High-priority |
||||||
|
event buffers are for everything except advertising reports. If there |
||||||
|
are no free high-priority event buffers then host will try to allocate a |
||||||
|
low-priority buffer instead |
||||||
|
|
||||||
|
config BT_LE_HCI_EVT_LO_BUF_COUNT |
||||||
|
int "Low Priority HCI Event Buffer count" |
||||||
|
default 8 |
||||||
|
help |
||||||
|
This is the low priority HCI events' buffer size. Low-priority event |
||||||
|
buffers are only used for advertising reports. If there are no free |
||||||
|
low-priority event buffers, then an incoming advertising report will |
||||||
|
get dropped |
||||||
|
endmenu |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
int "Controller task stack size" |
||||||
|
default 5120 if BLE_MESH |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
This configures stack size of NimBLE controller task |
||||||
|
|
||||||
|
menuconfig BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
bool "Controller log enable" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable controller log |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_CTRL_ENABLED |
||||||
|
bool "enable controller log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable controller log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_HCI_ENABLED |
||||||
|
bool "enable HCI log module" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable hci log module |
||||||
|
|
||||||
|
config BT_LE_CONTROLLER_LOG_DUMP_ONLY |
||||||
|
bool "Controller log dump mode only" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Only operate in dump mode |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF1_SIZE |
||||||
|
int "size of the first BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the first BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_CTRL_BUF2_SIZE |
||||||
|
int "size of the second BLE controller LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 1024 |
||||||
|
help |
||||||
|
Configure the size of the second BLE controller LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LOG_HCI_BUF_SIZE |
||||||
|
int "size of the BLE HCI LOG buffer" |
||||||
|
depends on BT_LE_CONTROLLER_LOG_ENABLED |
||||||
|
default 4096 |
||||||
|
help |
||||||
|
Configure the size of the BLE HCI LOG buffer. |
||||||
|
|
||||||
|
config BT_LE_LL_RESOLV_LIST_SIZE |
||||||
|
int "BLE LL Resolving list size" |
||||||
|
range 1 5 |
||||||
|
default 4 |
||||||
|
help |
||||||
|
Configure the size of resolving list used in link layer. |
||||||
|
|
||||||
|
menuconfig BT_LE_SECURITY_ENABLE |
||||||
|
bool "Enable BLE SM feature" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable BLE sm feature |
||||||
|
|
||||||
|
config BT_LE_SM_LEGACY |
||||||
|
bool "Security manager legacy pairing" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager legacy pairing |
||||||
|
|
||||||
|
config BT_LE_SM_SC |
||||||
|
bool "Security manager secure connections (4.2)" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable security manager secure connections |
||||||
|
|
||||||
|
config BT_LE_SM_SC_DEBUG_KEYS |
||||||
|
bool "Use predefined public-private key pair" |
||||||
|
default n |
||||||
|
depends on BT_LE_SECURITY_ENABLE && BT_LE_SM_SC |
||||||
|
help |
||||||
|
If this option is enabled, SM uses predefined DH key pair as described |
||||||
|
in Core Specification, Vol. 3, Part H, 2.3.5.6.1. This allows to |
||||||
|
decrypt air traffic easily and thus should only be used for debugging. |
||||||
|
|
||||||
|
config BT_LE_LL_CFG_FEAT_LE_ENCRYPTION |
||||||
|
bool "Enable LE encryption" |
||||||
|
depends on BT_LE_SECURITY_ENABLE |
||||||
|
default y |
||||||
|
help |
||||||
|
Enable encryption connection |
||||||
|
|
||||||
|
config BT_LE_CRYPTO_STACK_MBEDTLS |
||||||
|
bool "Override TinyCrypt with mbedTLS for crypto computations" |
||||||
|
default y |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
select MBEDTLS_ECP_RESTARTABLE |
||||||
|
select MBEDTLS_CMAC_C |
||||||
|
help |
||||||
|
Enable this option to choose mbedTLS instead of TinyCrypt for crypto |
||||||
|
computations. |
||||||
|
|
||||||
|
config BT_LE_WHITELIST_SIZE |
||||||
|
int "BLE white list size" |
||||||
|
range 1 15 |
||||||
|
default 12 |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
help |
||||||
|
BLE list size |
||||||
|
|
||||||
|
config BT_LE_LL_DUP_SCAN_LIST_COUNT |
||||||
|
int "BLE duplicate scan list count" |
||||||
|
range 5 100 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
config the max count of duplicate scan list |
||||||
|
|
||||||
|
config BT_LE_LL_SCA |
||||||
|
int "BLE Sleep clock accuracy" |
||||||
|
range 0 500 |
||||||
|
default 60 |
||||||
|
help |
||||||
|
Sleep clock accuracy of our device (in ppm) |
||||||
|
|
||||||
|
config BT_LE_MAX_CONNECTIONS |
||||||
|
int "Maximum number of concurrent connections" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
range 1 35 |
||||||
|
default 3 |
||||||
|
help |
||||||
|
Defines maximum number of concurrent BLE connections. For ESP32, user |
||||||
|
is expected to configure BTDM_CTRL_BLE_MAX_CONN from controller menu |
||||||
|
along with this option. Similarly for ESP32-C3 or ESP32-S3, user is expected to |
||||||
|
configure BT_CTRL_BLE_MAX_ACT from controller menu. |
||||||
|
Each connection will take about 1k DRAM. |
||||||
|
|
||||||
|
choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM |
||||||
|
prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" |
||||||
|
default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
depends on ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
help |
||||||
|
When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to |
||||||
|
better avoid dramatic performance deterioration of Wi-Fi. |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
bool "Force Enable" |
||||||
|
help |
||||||
|
Always enable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
bool "Force Disable" |
||||||
|
help |
||||||
|
Disable the limitation on max tx/rx time for Coded-PHY connection |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
int |
||||||
|
default 0 if !ESP_COEX_SW_COEXIST_ENABLE |
||||||
|
default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN |
||||||
|
default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS |
||||||
|
|
||||||
|
config BT_LE_SLEEP_ENABLE |
||||||
|
bool "Enable BLE sleep" |
||||||
|
default n |
||||||
|
help |
||||||
|
Enable BLE sleep |
||||||
|
|
||||||
|
choice BT_LE_LP_CLK_SRC |
||||||
|
prompt "BLE low power clock source" |
||||||
|
default BT_LE_LP_CLK_SRC_MAIN_XTAL |
||||||
|
config BT_LE_LP_CLK_SRC_MAIN_XTAL |
||||||
|
bool "Use main XTAL as RTC clock source" |
||||||
|
help |
||||||
|
User main XTAL as RTC clock source. |
||||||
|
This option is recommended if external 32.768k XTAL is not available. |
||||||
|
Using the external 32.768 kHz XTAL will have lower current consumption |
||||||
|
in light sleep compared to using the main XTAL. |
||||||
|
|
||||||
|
config BT_LE_LP_CLK_SRC_DEFAULT |
||||||
|
bool "Use system RTC slow clock source" |
||||||
|
help |
||||||
|
Use the same slow clock source as system RTC |
||||||
|
Using any clock source other than external 32.768 kHz XTAL supports only |
||||||
|
legacy ADV and SCAN due to low clock accuracy. |
||||||
|
|
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_USE_ESP_TIMER |
||||||
|
bool "Enable Esp Timer for Callout" |
||||||
|
depends on !BT_NIMBLE_ENABLED |
||||||
|
default y |
||||||
|
help |
||||||
|
Set this option to use Esp Timer which has higher priority timer |
||||||
|
instead of FreeRTOS timer |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
bool "BLE adv report flow control supported" |
||||||
|
default y |
||||||
|
help |
||||||
|
The function is mainly used to enable flow control for advertising reports. When it is enabled, |
||||||
|
advertising reports will be discarded by the controller if the number of unprocessed advertising |
||||||
|
reports exceeds the size of BLE adv report flow control. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM |
||||||
|
int "BLE adv report flow control number" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 50 1000 |
||||||
|
default 100 |
||||||
|
help |
||||||
|
The number of unprocessed advertising report that bluetooth host can save.If you set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a |
||||||
|
lot of adv packets and this may cause system memory run out. For example, if you set |
||||||
|
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set |
||||||
|
`BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv |
||||||
|
packets as fast as possible, otherwise it will cause adv packets lost. |
||||||
|
|
||||||
|
config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD |
||||||
|
int "BLE adv lost event threshold value" |
||||||
|
depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP |
||||||
|
range 1 1000 |
||||||
|
default 20 |
||||||
|
help |
||||||
|
When adv report flow control is enabled, The ADV lost event will be generated when the number |
||||||
|
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. |
||||||
|
If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it |
||||||
|
may cause adv packets lost more. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL |
||||||
|
bool "BLE Scan Duplicate Options" |
||||||
|
default y |
||||||
|
help |
||||||
|
This select enables parameters setting of BLE scan duplicate. |
||||||
|
|
||||||
|
choice BT_LE_SCAN_DUPL_TYPE |
||||||
|
prompt "Scan Duplicate Type" |
||||||
|
default BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
help |
||||||
|
Scan duplicate have three ways. one is "Scan Duplicate By Device Address", This way is to use |
||||||
|
advertiser address filtering. The adv packet of the same address is only allowed to be reported once. |
||||||
|
Another way is "Scan Duplicate By Device Address And Advertising Data". This way is to use advertising |
||||||
|
data and device address filtering. All different adv packets with the same address are allowed to be |
||||||
|
reported. The last way is "Scan Duplicate By Advertising Data". This way is to use advertising data |
||||||
|
filtering. All same advertising data only allow to be reported once even though they are from |
||||||
|
different devices. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address" |
||||||
|
help |
||||||
|
This way is to use advertiser address filtering. The adv packet of the same address is only |
||||||
|
allowed to be reported once |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DATA |
||||||
|
bool "Scan Duplicate By Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data filtering. All same advertising data only allow to be reported |
||||||
|
once even though they are from different devices. |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
bool "Scan Duplicate By Device Address And Advertising Data" |
||||||
|
help |
||||||
|
This way is to use advertising data and device address filtering. All different adv packets with |
||||||
|
the same address are allowed to be reported. |
||||||
|
endchoice |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_TYPE |
||||||
|
int |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
default 0 if BT_LE_SCAN_DUPL_TYPE_DEVICE |
||||||
|
default 1 if BT_LE_SCAN_DUPL_TYPE_DATA |
||||||
|
default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE |
||||||
|
default 0 |
||||||
|
|
||||||
|
config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD |
||||||
|
int "Duplicate scan list refresh period (seconds)" |
||||||
|
depends on BT_LE_SCAN_DUPL |
||||||
|
range 0 1000 |
||||||
|
default 0 |
||||||
|
help |
||||||
|
If the period value is non-zero, the controller will periodically clear the device information |
||||||
|
stored in the scan duuplicate filter. If it is 0, the scan duuplicate filter will not be cleared |
||||||
|
until the scanning is disabled. Duplicate advertisements for this period should not be sent to the |
||||||
|
Host in advertising report events. |
||||||
|
There are two scenarios where the ADV packet will be repeatedly reported: |
||||||
|
1. The duplicate scan cache is full, the controller will delete the oldest device information and |
||||||
|
add new device information. |
||||||
|
2. When the refresh period is up, the controller will clear all device information and start filtering |
||||||
|
again. |
||||||
|
|
||||||
|
config BT_LE_MSYS_INIT_IN_CONTROLLER |
||||||
|
bool |
||||||
|
default y |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,220 @@ |
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __ESP_BT_CFG_H__ |
||||||
|
#define __ESP_BT_CFG_H__ |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include "esp_err.h" |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
#include "syscfg/syscfg.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_ENABLED |
||||||
|
|
||||||
|
#if CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_ACL_FROM_LL_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE MYNEWT_VAL(BLE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL) |
||||||
|
#if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
#else |
||||||
|
|
||||||
|
#if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (2) |
||||||
|
#else |
||||||
|
#define BLE_LL_SCAN_PHY_NUMBER_N (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (CONFIG_BT_LE_MAX_CONNECTIONS) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_CONNECTIONS (2) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (CONFIG_BT_LE_ACL_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_SIZE (255) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (CONFIG_BT_LE_ACL_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_ACL_BUF_COUNT (24) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (CONFIG_BT_LE_HCI_EVT_BUF_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_BUF_SIZE (70) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (CONFIG_BT_LE_EXT_ADV_MAX_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_EXT_ADV_MAX_SIZE (31) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES (1) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (CONFIG_BT_LE_WHITELIST_SIZE) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_NIMBLE_WHITELIST_SIZE (12) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT (30) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED) |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) |
||||||
|
#endif |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART |
||||||
|
#else |
||||||
|
#define HCI_UART_EN 0 // hci ram mode
|
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE |
||||||
|
#else |
||||||
|
#define NIMBLE_SLEEP_ENABLE 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_TX_CCA_ENABLED |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (CONFIG_BT_LE_TX_CCA_ENABLED) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_TX_CCA_ENABLED (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef CONFIG_BT_LE_CCA_RSSI_THRESH |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (CONFIG_BT_LE_CCA_RSSI_THRESH) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_CCA_RSSI_THRESH (50) |
||||||
|
#endif |
||||||
|
|
||||||
|
#define DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N DEFAULT_BT_LE_EXT_ADV_MAX_SIZE |
||||||
|
|
||||||
|
|
||||||
|
#if HCI_UART_EN |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (CONFIG_BT_LE_HCI_UART_TX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (CONFIG_BT_LE_HCI_UART_RX_PIN) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (CONFIG_BT_LE_HCI_UART_PORT) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (CONFIG_BT_LE_HCI_UART_BAUD) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#else |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PORT (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_BAUD (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_PARITY (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) |
||||||
|
#define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Unchanged configuration */ |
||||||
|
|
||||||
|
#define BLE_LL_CTRL_PROC_TIMEOUT_MS_N (40000) /* ms */ |
||||||
|
|
||||||
|
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS_N (1) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_ADV_MAX_USECS_N (852) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N (502) |
||||||
|
|
||||||
|
#define BLE_LL_SCHED_MAX_ADV_PDU_USECS_N (376) |
||||||
|
|
||||||
|
#define BLE_LL_SUB_VERS_NR_N (0x0000) |
||||||
|
|
||||||
|
#define BLE_LL_JITTER_USECS_N (16) |
||||||
|
|
||||||
|
#define BLE_PHY_MAX_PWR_DBM_N (10) |
||||||
|
|
||||||
|
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000) |
||||||
|
|
||||||
|
#define RTC_FREQ_N (32768) /* in Hz */ |
||||||
|
|
||||||
|
#define BLE_LL_TX_PWR_DBM_N (9) |
||||||
|
|
||||||
|
|
||||||
|
#define RUN_BQB_TEST (0) |
||||||
|
#define RUN_QA_TEST (0) |
||||||
|
#define NIMBLE_DISABLE_SCAN_BACKOFF (0) |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif /* __ESP_BT_CFG_H__ */ |
@ -0,0 +1 @@ |
|||||||
|
source "$IDF_PATH/components/bt/controller/esp32c3/Kconfig.in" |
@ -0,0 +1,30 @@ |
|||||||
|
stages: |
||||||
|
- deploy |
||||||
|
|
||||||
|
push_master_to_github: |
||||||
|
stage: deploy |
||||||
|
tags: |
||||||
|
- internet |
||||||
|
only: |
||||||
|
- master |
||||||
|
- /^release\/v/ |
||||||
|
- /^v\d+\.\d+/ |
||||||
|
# when: on_success |
||||||
|
image: $CI_DOCKER_REGISTRY/esp32-ci-env |
||||||
|
variables: |
||||||
|
GIT_DEPTH: 0 |
||||||
|
script: |
||||||
|
- mkdir -p ~/.ssh |
||||||
|
- chmod 700 ~/.ssh |
||||||
|
- echo -n $GH_PUSH_KEY > ~/.ssh/id_rsa_base64 |
||||||
|
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa |
||||||
|
- chmod 600 ~/.ssh/id_rsa |
||||||
|
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config |
||||||
|
- git remote add github git@github.com:espressif/esp32-bt-lib.git |
||||||
|
# Ref: esp-idf tools/ci/push_to_github.sh |
||||||
|
- | |
||||||
|
if [ -n "${CI_COMMIT_TAG}" ]; then |
||||||
|
git push github "${CI_COMMIT_TAG}" |
||||||
|
else |
||||||
|
git push github "${CI_COMMIT_SHA}:refs/heads/${CI_COMMIT_REF_NAME}" |
||||||
|
fi |
@ -0,0 +1,202 @@ |
|||||||
|
|
||||||
|
Apache License |
||||||
|
Version 2.0, January 2004 |
||||||
|
http://www.apache.org/licenses/ |
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||||
|
|
||||||
|
1. Definitions. |
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||||
|
the copyright owner that is granting the License. |
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||||
|
other entities that control, are controlled by, or are under common |
||||||
|
control with that entity. For the purposes of this definition, |
||||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||||
|
direction or management of such entity, whether by contract or |
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||||
|
exercising permissions granted by this License. |
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, |
||||||
|
including but not limited to software source code, documentation |
||||||
|
source, and configuration files. |
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical |
||||||
|
transformation or translation of a Source form, including but |
||||||
|
not limited to compiled object code, generated documentation, |
||||||
|
and conversions to other media types. |
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||||
|
Object form, made available under the License, as indicated by a |
||||||
|
copyright notice that is included in or attached to the work |
||||||
|
(an example is provided in the Appendix below). |
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||||
|
form, that is based on (or derived from) the Work and for which the |
||||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||||
|
of this License, Derivative Works shall not include works that remain |
||||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||||
|
the Work and Derivative Works thereof. |
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including |
||||||
|
the original version of the Work and any modifications or additions |
||||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||||
|
means any form of electronic, verbal, or written communication sent |
||||||
|
to the Licensor or its representatives, including but not limited to |
||||||
|
communication on electronic mailing lists, source code control systems, |
||||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||||
|
excluding communication that is conspicuously marked or otherwise |
||||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||||
|
subsequently incorporated within the Work. |
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||||
|
Work and such Derivative Works in Source or Object form. |
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
(except as stated in this section) patent license to make, have made, |
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||||
|
where such license applies only to those patent claims licensable |
||||||
|
by such Contributor that are necessarily infringed by their |
||||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||||
|
institute patent litigation against any entity (including a |
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||||
|
or a Contribution incorporated within the Work constitutes direct |
||||||
|
or contributory patent infringement, then any patent licenses |
||||||
|
granted to You under this License for that Work shall terminate |
||||||
|
as of the date such litigation is filed. |
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||||
|
Work or Derivative Works thereof in any medium, with or without |
||||||
|
modifications, and in Source or Object form, provided that You |
||||||
|
meet the following conditions: |
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or |
||||||
|
Derivative Works a copy of this License; and |
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices |
||||||
|
stating that You changed the files; and |
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||||
|
that You distribute, all copyright, patent, trademark, and |
||||||
|
attribution notices from the Source form of the Work, |
||||||
|
excluding those notices that do not pertain to any part of |
||||||
|
the Derivative Works; and |
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||||
|
distribution, then any Derivative Works that You distribute must |
||||||
|
include a readable copy of the attribution notices contained |
||||||
|
within such NOTICE file, excluding those notices that do not |
||||||
|
pertain to any part of the Derivative Works, in at least one |
||||||
|
of the following places: within a NOTICE text file distributed |
||||||
|
as part of the Derivative Works; within the Source form or |
||||||
|
documentation, if provided along with the Derivative Works; or, |
||||||
|
within a display generated by the Derivative Works, if and |
||||||
|
wherever such third-party notices normally appear. The contents |
||||||
|
of the NOTICE file are for informational purposes only and |
||||||
|
do not modify the License. You may add Your own attribution |
||||||
|
notices within Derivative Works that You distribute, alongside |
||||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||||
|
that such additional attribution notices cannot be construed |
||||||
|
as modifying the License. |
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and |
||||||
|
may provide additional or different license terms and conditions |
||||||
|
for use, reproduction, or distribution of Your modifications, or |
||||||
|
for any such Derivative Works as a whole, provided Your use, |
||||||
|
reproduction, and distribution of the Work otherwise complies with |
||||||
|
the conditions stated in this License. |
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||||
|
by You to the Licensor shall be under the terms and conditions of |
||||||
|
this License, without any additional terms or conditions. |
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||||
|
the terms of any separate license agreement you may have executed |
||||||
|
with Licensor regarding such Contributions. |
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||||
|
except as required for reasonable and customary use in describing the |
||||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||||
|
agreed to in writing, Licensor provides the Work (and each |
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||||
|
implied, including, without limitation, any warranties or conditions |
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||||
|
appropriateness of using or redistributing the Work and assume any |
||||||
|
risks associated with Your exercise of permissions under this License. |
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||||
|
whether in tort (including negligence), contract, or otherwise, |
||||||
|
unless required by applicable law (such as deliberate and grossly |
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||||
|
liable to You for damages, including any direct, indirect, special, |
||||||
|
incidental, or consequential damages of any character arising as a |
||||||
|
result of this License or out of the use or inability to use the |
||||||
|
Work (including but not limited to damages for loss of goodwill, |
||||||
|
work stoppage, computer failure or malfunction, or any and all |
||||||
|
other commercial damages or losses), even if such Contributor |
||||||
|
has been advised of the possibility of such damages. |
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||||
|
or other liability obligations and/or rights consistent with this |
||||||
|
License. However, in accepting such obligations, You may act only |
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||||
|
of any other Contributor, and only if You agree to indemnify, |
||||||
|
defend, and hold each Contributor harmless for any liability |
||||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||||
|
of your accepting any such warranty or additional liability. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work. |
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following |
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||||
|
replaced with your own identifying information. (Don't include |
||||||
|
the brackets!) The text should be enclosed in the appropriate |
||||||
|
comment syntax for the file format. We also recommend that a |
||||||
|
file or class name and description of purpose be included on the |
||||||
|
same "printed page" as the copyright notice for easier |
||||||
|
identification within third-party archives. |
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] |
||||||
|
|
||||||
|
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. |
@ -0,0 +1,10 @@ |
|||||||
|
ESP32 BT/BLE Stack Libraries |
||||||
|
==================== |
||||||
|
|
||||||
|
This repository contains binary libraries supporting the ESP32 RF subsystems. It is used as a submodule within `Espressif IoT Development Framework`_ (ESP-IDF). |
||||||
|
|
||||||
|
Files in this repository are Copyright (C) 2015-2016 Espressif Systems. |
||||||
|
|
||||||
|
These binary libraries are provided under the same license as the parent esp-idf project - the Apache License 2.0 as provided in the file LICENSE. (The license text refers to this as "Object" form.) |
||||||
|
|
||||||
|
.. _Espressif IoT Development Framework: https://github.com/espressif/esp-idf |
Binary file not shown.
@ -0,0 +1,9 @@ |
|||||||
|
Apache Mynewt NimBLE |
||||||
|
Copyright 2015-2021 The Apache Software Foundation |
||||||
|
Modifications Copyright 2017-2022 Espressif Systems (Shanghai) CO., LTD. |
||||||
|
|
||||||
|
This product includes software developed at |
||||||
|
The Apache Software Foundation (http://www.apache.org/). |
||||||
|
|
||||||
|
Portions of this software were developed at |
||||||
|
Runtime Inc, copyright 2015. |
@ -0,0 +1 @@ |
|||||||
|
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details. |
Binary file not shown.
@ -0,0 +1,31 @@ |
|||||||
|
stages: |
||||||
|
- deploy |
||||||
|
|
||||||
|
push_master_to_github: |
||||||
|
stage: deploy |
||||||
|
tags: |
||||||
|
- internet |
||||||
|
only: |
||||||
|
- master |
||||||
|
- /^release\/v/ |
||||||
|
# when: on_success |
||||||
|
image: $CI_DOCKER_REGISTRY/esp32-ci-env |
||||||
|
variables: |
||||||
|
GIT_STRATEGY: clone |
||||||
|
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master |
||||||
|
script: |
||||||
|
- mkdir -p ~/.ssh |
||||||
|
- chmod 700 ~/.ssh |
||||||
|
- echo -n $GH_PUSH_KEY > ~/.ssh/id_rsa_base64 |
||||||
|
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa |
||||||
|
- chmod 600 ~/.ssh/id_rsa |
||||||
|
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config |
||||||
|
- git remote add github git@github.com:espressif/esp32c3-bt-lib.git |
||||||
|
# What the next line of script does: goes through the list of refs for all branches we push to github, |
||||||
|
# generates a snippet of shell which is evaluated. The snippet checks CI_BUILD_REF against the SHA |
||||||
|
# (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch |
||||||
|
# and then pushes that ref to a corresponding github branch |
||||||
|
# |
||||||
|
# NB: In gitlab 9.x, CI_BUILD_REF was deprecated. New name is CI_COMMIT_REF. If below command suddenly |
||||||
|
# generates bash syntax errors, this is probably why. |
||||||
|
- eval $(git for-each-ref --shell bash --format 'if [ $CI_BUILD_REF == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS) |
@ -0,0 +1,202 @@ |
|||||||
|
|
||||||
|
Apache License |
||||||
|
Version 2.0, January 2004 |
||||||
|
http://www.apache.org/licenses/ |
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||||
|
|
||||||
|
1. Definitions. |
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, |
||||||
|
and distribution as defined by Sections 1 through 9 of this document. |
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by |
||||||
|
the copyright owner that is granting the License. |
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all |
||||||
|
other entities that control, are controlled by, or are under common |
||||||
|
control with that entity. For the purposes of this definition, |
||||||
|
"control" means (i) the power, direct or indirect, to cause the |
||||||
|
direction or management of such entity, whether by contract or |
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity. |
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity |
||||||
|
exercising permissions granted by this License. |
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, |
||||||
|
including but not limited to software source code, documentation |
||||||
|
source, and configuration files. |
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical |
||||||
|
transformation or translation of a Source form, including but |
||||||
|
not limited to compiled object code, generated documentation, |
||||||
|
and conversions to other media types. |
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or |
||||||
|
Object form, made available under the License, as indicated by a |
||||||
|
copyright notice that is included in or attached to the work |
||||||
|
(an example is provided in the Appendix below). |
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object |
||||||
|
form, that is based on (or derived from) the Work and for which the |
||||||
|
editorial revisions, annotations, elaborations, or other modifications |
||||||
|
represent, as a whole, an original work of authorship. For the purposes |
||||||
|
of this License, Derivative Works shall not include works that remain |
||||||
|
separable from, or merely link (or bind by name) to the interfaces of, |
||||||
|
the Work and Derivative Works thereof. |
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including |
||||||
|
the original version of the Work and any modifications or additions |
||||||
|
to that Work or Derivative Works thereof, that is intentionally |
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner |
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of |
||||||
|
the copyright owner. For the purposes of this definition, "submitted" |
||||||
|
means any form of electronic, verbal, or written communication sent |
||||||
|
to the Licensor or its representatives, including but not limited to |
||||||
|
communication on electronic mailing lists, source code control systems, |
||||||
|
and issue tracking systems that are managed by, or on behalf of, the |
||||||
|
Licensor for the purpose of discussing and improving the Work, but |
||||||
|
excluding communication that is conspicuously marked or otherwise |
||||||
|
designated in writing by the copyright owner as "Not a Contribution." |
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||||
|
on behalf of whom a Contribution has been received by Licensor and |
||||||
|
subsequently incorporated within the Work. |
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
copyright license to reproduce, prepare Derivative Works of, |
||||||
|
publicly display, publicly perform, sublicense, and distribute the |
||||||
|
Work and such Derivative Works in Source or Object form. |
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of |
||||||
|
this License, each Contributor hereby grants to You a perpetual, |
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||||
|
(except as stated in this section) patent license to make, have made, |
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||||
|
where such license applies only to those patent claims licensable |
||||||
|
by such Contributor that are necessarily infringed by their |
||||||
|
Contribution(s) alone or by combination of their Contribution(s) |
||||||
|
with the Work to which such Contribution(s) was submitted. If You |
||||||
|
institute patent litigation against any entity (including a |
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||||
|
or a Contribution incorporated within the Work constitutes direct |
||||||
|
or contributory patent infringement, then any patent licenses |
||||||
|
granted to You under this License for that Work shall terminate |
||||||
|
as of the date such litigation is filed. |
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the |
||||||
|
Work or Derivative Works thereof in any medium, with or without |
||||||
|
modifications, and in Source or Object form, provided that You |
||||||
|
meet the following conditions: |
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or |
||||||
|
Derivative Works a copy of this License; and |
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices |
||||||
|
stating that You changed the files; and |
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works |
||||||
|
that You distribute, all copyright, patent, trademark, and |
||||||
|
attribution notices from the Source form of the Work, |
||||||
|
excluding those notices that do not pertain to any part of |
||||||
|
the Derivative Works; and |
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its |
||||||
|
distribution, then any Derivative Works that You distribute must |
||||||
|
include a readable copy of the attribution notices contained |
||||||
|
within such NOTICE file, excluding those notices that do not |
||||||
|
pertain to any part of the Derivative Works, in at least one |
||||||
|
of the following places: within a NOTICE text file distributed |
||||||
|
as part of the Derivative Works; within the Source form or |
||||||
|
documentation, if provided along with the Derivative Works; or, |
||||||
|
within a display generated by the Derivative Works, if and |
||||||
|
wherever such third-party notices normally appear. The contents |
||||||
|
of the NOTICE file are for informational purposes only and |
||||||
|
do not modify the License. You may add Your own attribution |
||||||
|
notices within Derivative Works that You distribute, alongside |
||||||
|
or as an addendum to the NOTICE text from the Work, provided |
||||||
|
that such additional attribution notices cannot be construed |
||||||
|
as modifying the License. |
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and |
||||||
|
may provide additional or different license terms and conditions |
||||||
|
for use, reproduction, or distribution of Your modifications, or |
||||||
|
for any such Derivative Works as a whole, provided Your use, |
||||||
|
reproduction, and distribution of the Work otherwise complies with |
||||||
|
the conditions stated in this License. |
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||||
|
any Contribution intentionally submitted for inclusion in the Work |
||||||
|
by You to the Licensor shall be under the terms and conditions of |
||||||
|
this License, without any additional terms or conditions. |
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify |
||||||
|
the terms of any separate license agreement you may have executed |
||||||
|
with Licensor regarding such Contributions. |
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade |
||||||
|
names, trademarks, service marks, or product names of the Licensor, |
||||||
|
except as required for reasonable and customary use in describing the |
||||||
|
origin of the Work and reproducing the content of the NOTICE file. |
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or |
||||||
|
agreed to in writing, Licensor provides the Work (and each |
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||||
|
implied, including, without limitation, any warranties or conditions |
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||||
|
appropriateness of using or redistributing the Work and assume any |
||||||
|
risks associated with Your exercise of permissions under this License. |
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, |
||||||
|
whether in tort (including negligence), contract, or otherwise, |
||||||
|
unless required by applicable law (such as deliberate and grossly |
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be |
||||||
|
liable to You for damages, including any direct, indirect, special, |
||||||
|
incidental, or consequential damages of any character arising as a |
||||||
|
result of this License or out of the use or inability to use the |
||||||
|
Work (including but not limited to damages for loss of goodwill, |
||||||
|
work stoppage, computer failure or malfunction, or any and all |
||||||
|
other commercial damages or losses), even if such Contributor |
||||||
|
has been advised of the possibility of such damages. |
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing |
||||||
|
the Work or Derivative Works thereof, You may choose to offer, |
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity, |
||||||
|
or other liability obligations and/or rights consistent with this |
||||||
|
License. However, in accepting such obligations, You may act only |
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf |
||||||
|
of any other Contributor, and only if You agree to indemnify, |
||||||
|
defend, and hold each Contributor harmless for any liability |
||||||
|
incurred by, or claims asserted against, such Contributor by reason |
||||||
|
of your accepting any such warranty or additional liability. |
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS |
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work. |
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following |
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]" |
||||||
|
replaced with your own identifying information. (Don't include |
||||||
|
the brackets!) The text should be enclosed in the appropriate |
||||||
|
comment syntax for the file format. We also recommend that a |
||||||
|
file or class name and description of purpose be included on the |
||||||
|
same "printed page" as the copyright notice for easier |
||||||
|
identification within third-party archives. |
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner] |
||||||
|
|
||||||
|
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. |
@ -0,0 +1,10 @@ |
|||||||
|
ESP32-C3 and ESP32-S3 BLE Stack Libraries |
||||||
|
========================================= |
||||||
|
|
||||||
|
This repository contains binary libraries supporting the ESP32C3 and ESP32S3 RF subsystems. It is used as a submodule within `Espressif IoT Development Framework`_ (ESP-IDF). |
||||||
|
|
||||||
|
Files in this repository are Copyright (C) 2021 Espressif Systems. |
||||||
|
|
||||||
|
These binary libraries are provided under the same license as the parent esp-idf project - the Apache License 2.0 as provided in the file LICENSE. (The license text refers to this as "Object" form.) |
||||||
|
|
||||||
|
.. _Espressif IoT Development Framework: https://github.com/espressif/esp-idf |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,9 @@ |
|||||||
|
Apache Mynewt NimBLE |
||||||
|
Copyright 2015-2021 The Apache Software Foundation |
||||||
|
Modifications Copyright 2017-2023 Espressif Systems (Shanghai) CO., LTD. |
||||||
|
|
||||||
|
This product includes software developed at |
||||||
|
The Apache Software Foundation (http://www.apache.org/). |
||||||
|
|
||||||
|
Portions of this software were developed at |
||||||
|
Runtime Inc, copyright 2015. |
@ -0,0 +1 @@ |
|||||||
|
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details. |
Binary file not shown.
@ -0,0 +1,9 @@ |
|||||||
|
Apache Mynewt NimBLE |
||||||
|
Copyright 2015-2022 The Apache Software Foundation |
||||||
|
Modifications Copyright 2017-2023 Espressif Systems (Shanghai) CO., LTD. |
||||||
|
|
||||||
|
This product includes software developed at |
||||||
|
The Apache Software Foundation (http://www.apache.org/). |
||||||
|
|
||||||
|
Portions of this software were developed at |
||||||
|
Runtime Inc, copyright 2015. |
@ -0,0 +1 @@ |
|||||||
|
This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details. |
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue