Merge branch 'develop' of JF/PineTime into master
This commit is contained in:
commit
3f7360ca18
136
.clang-format
Normal file
136
.clang-format
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: true
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortLambdasOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: true
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 140
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: false
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: false
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: BeforeHash
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: true
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
# Needs new Clang: SpaceAroundPointerQualifiers: After
|
||||||
|
Standard: Latest
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 8
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
...
|
26
.clang-tidy
Normal file
26
.clang-tidy
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Checks: '*,
|
||||||
|
-llvmlibc-callee-namespace,
|
||||||
|
-llvm-header-guard,
|
||||||
|
-llvm-namespace-comment,
|
||||||
|
-google-build-using-namespace,
|
||||||
|
-google-runtime-int,
|
||||||
|
-google-readability-namespace-comments,
|
||||||
|
-fuchsia-statically-constructed-objects,
|
||||||
|
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||||
|
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||||
|
-cppcoreguidelines-pro-type-union-access,
|
||||||
|
-cppcoreguidelines-pro-type-cstyle-cast,
|
||||||
|
-cppcoreguidelines-pro-type-vararg,
|
||||||
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
|
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||||
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-uppercase-literal-suffix,
|
||||||
|
-modernize-use-trailing-return-type,
|
||||||
|
-modernize-avoid-c-arrays,
|
||||||
|
-hicpp-signed-bitwise,
|
||||||
|
-hicpp-no-assembler,
|
||||||
|
-hicpp-avoid-c-arrays,
|
||||||
|
-hicpp-uppercase-literal-suffix,
|
||||||
|
-cert-err58-cpp,
|
||||||
|
-cert-err60-cpp'
|
15
.gitattributes
vendored
Normal file
15
.gitattributes
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Explicitly declare text files you want to always be normalized and converted
|
||||||
|
# to native line endings on checkout.
|
||||||
|
*.c text
|
||||||
|
*.cpp text
|
||||||
|
*.h text
|
||||||
|
*.hpp text
|
||||||
|
|
||||||
|
# Denote all files that are truly binary and should not be modified.
|
||||||
|
*.png binary
|
||||||
|
*.bin binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
5
.gitconfig
Normal file
5
.gitconfig
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[core]
|
||||||
|
whitespace = blank-at-eol,blank-at-eof,space-before-tab
|
||||||
|
autocrlf = input
|
||||||
|
[apply]
|
||||||
|
whitespace = fix
|
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
liberapay: JF002
|
25
.idea/codeStyles/Project.xml
generated
25
.idea/codeStyles/Project.xml
generated
@ -8,10 +8,30 @@
|
|||||||
<option name="INDENT_DIRECTIVE_AS_CODE" value="true" />
|
<option name="INDENT_DIRECTIVE_AS_CODE" value="true" />
|
||||||
<option name="SPACE_BEFORE_TEMPLATE_DECLARATION_LT" value="true" />
|
<option name="SPACE_BEFORE_TEMPLATE_DECLARATION_LT" value="true" />
|
||||||
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
<option name="SPACE_BEFORE_POINTER_IN_DECLARATION" value="false" />
|
||||||
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
<!-- Disabled until clang-format can do it <option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" /> -->
|
||||||
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
</Objective-C>
|
</Objective-C>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<rules>
|
||||||
|
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
</rules>
|
||||||
|
</Objective-C-extensions>
|
||||||
<codeStyleSettings language="ObjectiveC">
|
<codeStyleSettings language="ObjectiveC">
|
||||||
<option name="RIGHT_MARGIN" value="140" />
|
<option name="RIGHT_MARGIN" value="140" />
|
||||||
<option name="IF_BRACE_FORCE" value="3" />
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
@ -27,5 +47,8 @@
|
|||||||
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
|
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
|
||||||
</indentOptions>
|
</indentOptions>
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
|
<clangFormatSettings>
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</clangFormatSettings>
|
||||||
</code_scheme>
|
</code_scheme>
|
||||||
</component>
|
</component>
|
@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(pinetime VERSION 0.11.0 LANGUAGES C CXX ASM)
|
project(pinetime VERSION 0.12.0 LANGUAGES C CXX ASM)
|
||||||
|
|
||||||
set(NRF_TARGET "nrf52")
|
set(NRF_TARGET "nrf52")
|
||||||
|
|
||||||
|
33
CONTRIBUTING.md
Normal file
33
CONTRIBUTING.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
This contribution guide is in progress, improvements are welcome.
|
||||||
|
|
||||||
|
### Code style
|
||||||
|
|
||||||
|
Any C++ code PRs should aim to follow the style of existing code in the project.
|
||||||
|
|
||||||
|
Using an autoformatter is heavily recommended, but make sure it's configured properly.
|
||||||
|
|
||||||
|
There's currently preconfigured autoformatter rules for:
|
||||||
|
|
||||||
|
* CLion (IntelliJ) in .idea/codeStyles/Project.xml
|
||||||
|
|
||||||
|
You can use those to configure your own IDE if it's not already on the list.
|
||||||
|
|
||||||
|
#### Linting errors and compiler warnings
|
||||||
|
|
||||||
|
Try to avoid any currently enabled warnings and try to reduce the amount of linter errors.
|
||||||
|
|
||||||
|
#### Spelling
|
||||||
|
|
||||||
|
Make sure you spellcheck your code before commiting it.
|
||||||
|
|
||||||
|
#### TODO, FIXME
|
||||||
|
|
||||||
|
Check before commiting that you haven't forgotten anything, preferably don't leave these in your commits.
|
||||||
|
|
||||||
|
#### Licence headers
|
||||||
|
|
||||||
|
You should add your name to the comma-space separated list of contributors if there's a license header.
|
||||||
|
|
||||||
|
### License
|
||||||
|
|
||||||
|
By contributing you agree to licence your code under the repository's general license (which is currently GPL-v3+).
|
14
README.md
14
README.md
@ -34,14 +34,18 @@ As of now, here is the list of achievements of this project:
|
|||||||
- Time synchronization via BLE
|
- Time synchronization via BLE
|
||||||
- Notification via BLE
|
- Notification via BLE
|
||||||
- Multiple 'apps' :
|
- Multiple 'apps' :
|
||||||
* Clock (displays the date, time, battery level, BLE connection status, heart rate and step count)
|
* Clock (displays the date, time, battery level, ble connection status, heart rate)
|
||||||
* Heart rate
|
|
||||||
* Motion
|
|
||||||
* System info (displays various info : BLE MAC, build date/time, uptime, version,...)
|
* System info (displays various info : BLE MAC, build date/time, uptime, version,...)
|
||||||
* Brightness (allows the user to configure the brightness of the display)
|
* Brightess (allows the user to configure the brightness of the display)
|
||||||
|
* Music (control the playback of the music on your phone)
|
||||||
|
* Heart rate (controls the heart rate sensor and display current heartbeat)
|
||||||
|
* Navigation (displays navigation instructions coming from the companion app)
|
||||||
|
* Notification (displays the last notification received)
|
||||||
|
* Paddle (single player pong-like game)
|
||||||
|
* Two (2048 clone game)
|
||||||
- Supported by 2 companion apps (development is in progress):
|
- Supported by 2 companion apps (development is in progress):
|
||||||
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/) (on Android)
|
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/) (on Android)
|
||||||
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS)
|
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux)
|
||||||
- **[Experimental]** OTA (Over-the-air) update via BLE
|
- **[Experimental]** OTA (Over-the-air) update via BLE
|
||||||
- **[Experimental]** Bootloader based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
|
- **[Experimental]** Bootloader based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ main() {
|
|||||||
|
|
||||||
CmakeGenerate
|
CmakeGenerate
|
||||||
CmakeBuild $target
|
CmakeBuild $target
|
||||||
|
BUILD_RESULT=$?
|
||||||
if [[ "$DISABLE_POSTBUILD" != "true" ]]; then
|
if [ "$DISABLE_POSTBUILD" != "true" -a "$BUILD_RESULT" == 0 ]; then
|
||||||
source "$BUILD_DIR/post_build.sh"
|
source "$BUILD_DIR/post_build.sh"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -70,7 +70,9 @@ CmakeGenerate() {
|
|||||||
CmakeBuild() {
|
CmakeBuild() {
|
||||||
local target="$1"
|
local target="$1"
|
||||||
[[ -n "$target" ]] && target="--target $target"
|
[[ -n "$target" ]] && target="--target $target"
|
||||||
cmake --build "$BUILD_DIR" --config $BUILD_TYPE $target -- -j$(nproc)
|
if cmake --build "$BUILD_DIR" --config $BUILD_TYPE $target -- -j$(nproc)
|
||||||
|
then return 0; else return 1;
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $SOURCED == "false" ]] && main "$@" || echo "Sourced!"
|
[[ $SOURCED == "false" ]] && main "$@" || echo "Sourced!"
|
@ -610,7 +610,7 @@ include_directories(
|
|||||||
"${NRF5_SDK_PATH}/modules/nrfx/drivers/include"
|
"${NRF5_SDK_PATH}/modules/nrfx/drivers/include"
|
||||||
"${NRF5_SDK_PATH}/modules/nrfx/hal"
|
"${NRF5_SDK_PATH}/modules/nrfx/hal"
|
||||||
"${NRF5_SDK_PATH}/modules/nrfx/mdk"
|
"${NRF5_SDK_PATH}/modules/nrfx/mdk"
|
||||||
${NRF5_SDK_PATH}/external/freertos/source/include
|
"${NRF5_SDK_PATH}/external/freertos/source/include"
|
||||||
"${NRF5_SDK_PATH}/components/toolchain/cmsis/include"
|
"${NRF5_SDK_PATH}/components/toolchain/cmsis/include"
|
||||||
"${NRF5_SDK_PATH}/components/libraries/atomic"
|
"${NRF5_SDK_PATH}/components/libraries/atomic"
|
||||||
"${NRF5_SDK_PATH}/components/libraries/atomic_fifo"
|
"${NRF5_SDK_PATH}/components/libraries/atomic_fifo"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <nrf_log.h>
|
||||||
#include "BatteryInformationService.h"
|
#include "BatteryInformationService.h"
|
||||||
#include "components/battery/BatteryController.h"
|
#include "components/battery/BatteryController.h"
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "CurrentTimeClient.h"
|
#include "CurrentTimeClient.h"
|
||||||
#include <hal/nrf_rtc.h>
|
#include <hal/nrf_rtc.h>
|
||||||
|
#include <nrf_log.h>
|
||||||
#include "components/datetime/DateTimeController.h"
|
#include "components/datetime/DateTimeController.h"
|
||||||
|
|
||||||
using namespace Pinetime::Controllers;
|
using namespace Pinetime::Controllers;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "CurrentTimeService.h"
|
#include "CurrentTimeService.h"
|
||||||
#include <hal/nrf_rtc.h>
|
#include <hal/nrf_rtc.h>
|
||||||
|
#include <nrf_log.h>
|
||||||
|
|
||||||
using namespace Pinetime::Controllers;
|
using namespace Pinetime::Controllers;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ namespace Pinetime {
|
|||||||
ColumnAddressSet = 0x2a,
|
ColumnAddressSet = 0x2a,
|
||||||
RowAddressSet = 0x2b,
|
RowAddressSet = 0x2b,
|
||||||
WriteToRam = 0x2c,
|
WriteToRam = 0x2c,
|
||||||
MemoryDataAccessControl = 036,
|
MemoryDataAccessControl = 0x36,
|
||||||
VerticalScrollDefinition = 0x33,
|
VerticalScrollDefinition = 0x33,
|
||||||
VerticalScrollStartAddress = 0x37,
|
VerticalScrollStartAddress = 0x37,
|
||||||
ColMod = 0x3a,
|
ColMod = 0x3a,
|
||||||
|
@ -14,8 +14,8 @@ HeartRateTask::HeartRateTask(Drivers::Hrs3300 &heartRateSensor, Controllers::Hea
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HeartRateTask::Start() {
|
void HeartRateTask::Start() {
|
||||||
if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle))
|
//if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle))
|
||||||
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
|
// APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeartRateTask::Process(void *instance) {
|
void HeartRateTask::Process(void *instance) {
|
||||||
|
54
src/libs/mynewt-nimble/apps/README.md
Normal file
54
src/libs/mynewt-nimble/apps/README.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<!--
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Sample applications
|
||||||
|
|
||||||
|
## advertiser
|
||||||
|
|
||||||
|
This is the simplest example of advertising. Application sets NRPA, configures
|
||||||
|
advertisement parameters: general discoverable and not connectable and fills
|
||||||
|
advertisement fields. Transmited data contains only flags, tx power level and
|
||||||
|
device name, which fits in 31B limit of single package. With this data set,
|
||||||
|
device advertises for 10 seconds, terminates advertisement and repeats process
|
||||||
|
again infinitely.
|
||||||
|
|
||||||
|
## scanner
|
||||||
|
|
||||||
|
This application shows how to perform simple scan. Device performs discovery
|
||||||
|
procedure, during which receives advertising reports (if any devices are
|
||||||
|
advertising nearby). These reports are being parsed and results are printed to
|
||||||
|
serial port. Applicaton starts new discovery every second.
|
||||||
|
|
||||||
|
## peripheral
|
||||||
|
|
||||||
|
Peripheral application is based on advertiser, but has added capability of
|
||||||
|
connecting with other devices. As peripheral, device doesn't initiate any
|
||||||
|
connection by itself; instead, advertises infinitely and accepts any connection
|
||||||
|
request it receives. Because we cannot use any 16 or 32 bit UUIDs, as these are
|
||||||
|
reserved by Bluetooth SIG, we are forced to use 128-bit one. Including such
|
||||||
|
long UUID in advertising data consumes large part of available payload, so this
|
||||||
|
data is split in advertising data and response data.
|
||||||
|
|
||||||
|
## central
|
||||||
|
|
||||||
|
This application works in pair with peripheral. It's based on scanner
|
||||||
|
application - the difference is, that if there was detected device with UUID
|
||||||
|
fitting to the one predefined in central application, connection is initiated.
|
@ -42,26 +42,6 @@ static int recent_test_id = STANDARD_TEST_ID;
|
|||||||
|
|
||||||
static bool has_reg_fault = true;
|
static bool has_reg_fault = true;
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv cfg_srv = {
|
|
||||||
.relay = BT_MESH_RELAY_DISABLED,
|
|
||||||
.beacon = BT_MESH_BEACON_ENABLED,
|
|
||||||
#if MYNEWT_VAL(BLE_MESH_FRIEND)
|
|
||||||
.frnd = BT_MESH_FRIEND_ENABLED,
|
|
||||||
#else
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
#if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
|
|
||||||
#else
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
.default_ttl = 7,
|
|
||||||
|
|
||||||
/* 3 transmissions with 20ms interval */
|
|
||||||
.net_transmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fault_get_cur(struct bt_mesh_model *model,
|
fault_get_cur(struct bt_mesh_model *model,
|
||||||
uint8_t *test_id,
|
uint8_t *test_id,
|
||||||
@ -327,7 +307,7 @@ static const struct bt_mesh_model_op gen_level_op[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct bt_mesh_model root_models[] = {
|
static struct bt_mesh_model root_models[] = {
|
||||||
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
|
BT_MESH_MODEL_CFG_SRV,
|
||||||
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
||||||
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
|
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_op,
|
||||||
&gen_onoff_pub, NULL),
|
&gen_onoff_pub, NULL),
|
||||||
@ -385,7 +365,7 @@ static int output_number(bt_mesh_output_action_t action, uint32_t number)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
static void prov_complete(uint16_t net_idx, uint16_t addr)
|
||||||
{
|
{
|
||||||
console_printf("Local node provisioned, primary address 0x%04x\n", addr);
|
console_printf("Local node provisioned, primary address 0x%04x\n", addr);
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,10 @@ static uint16_t top_val;
|
|||||||
static uint32_t neopixel[WS2812_NUM_LED];
|
static uint32_t neopixel[WS2812_NUM_LED];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static u8_t gen_onoff_state;
|
static uint8_t gen_onoff_state;
|
||||||
static s16_t gen_level_state;
|
static int16_t gen_level_state;
|
||||||
|
|
||||||
static void light_set_lightness(u8_t percentage)
|
static void light_set_lightness(uint8_t percentage)
|
||||||
{
|
{
|
||||||
#if (!MYNEWT_VAL(USE_NEOPIXEL))
|
#if (!MYNEWT_VAL(USE_NEOPIXEL))
|
||||||
int rc;
|
int rc;
|
||||||
@ -76,10 +76,10 @@ static void light_set_lightness(u8_t percentage)
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
u32_t lightness;
|
uint32_t lightness;
|
||||||
u8_t max_lightness = 0x1f;
|
uint8_t max_lightness = 0x1f;
|
||||||
|
|
||||||
lightness = (u8_t) (percentage * max_lightness / 100);
|
lightness = (uint8_t) (percentage * max_lightness / 100);
|
||||||
|
|
||||||
for (i = 0; i < WS2812_NUM_LED; i++) {
|
for (i = 0; i < WS2812_NUM_LED; i++) {
|
||||||
neopixel[i] = (lightness | lightness << 8 | lightness << 16);
|
neopixel[i] = (lightness | lightness << 8 | lightness << 16);
|
||||||
@ -90,7 +90,7 @@ static void light_set_lightness(u8_t percentage)
|
|||||||
|
|
||||||
static void update_light_state(void)
|
static void update_light_state(void)
|
||||||
{
|
{
|
||||||
u16_t level = (u16_t)gen_level_state;
|
uint16_t level = (uint16_t)gen_level_state;
|
||||||
int percent = 100 * level / 0xffff;
|
int percent = 100 * level / 0xffff;
|
||||||
|
|
||||||
if (gen_onoff_state == 0) {
|
if (gen_onoff_state == 0) {
|
||||||
@ -99,44 +99,44 @@ static void update_light_state(void)
|
|||||||
light_set_lightness((uint8_t) percent);
|
light_set_lightness((uint8_t) percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state)
|
int light_model_gen_onoff_get(struct bt_mesh_model *model, uint8_t *state)
|
||||||
{
|
{
|
||||||
*state = gen_onoff_state;
|
*state = gen_onoff_state;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state)
|
int light_model_gen_onoff_set(struct bt_mesh_model *model, uint8_t state)
|
||||||
{
|
{
|
||||||
gen_onoff_state = state;
|
gen_onoff_state = state;
|
||||||
update_light_state();
|
update_light_state();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level)
|
int light_model_gen_level_get(struct bt_mesh_model *model, int16_t *level)
|
||||||
{
|
{
|
||||||
*level = gen_level_state;
|
*level = gen_level_state;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level)
|
int light_model_gen_level_set(struct bt_mesh_model *model, int16_t level)
|
||||||
{
|
{
|
||||||
gen_level_state = level;
|
gen_level_state = level;
|
||||||
if ((u16_t)gen_level_state > 0x0000) {
|
if ((uint16_t)gen_level_state > 0x0000) {
|
||||||
gen_onoff_state = 1;
|
gen_onoff_state = 1;
|
||||||
}
|
}
|
||||||
if ((u16_t)gen_level_state == 0x0000) {
|
if ((uint16_t)gen_level_state == 0x0000) {
|
||||||
gen_onoff_state = 0;
|
gen_onoff_state = 0;
|
||||||
}
|
}
|
||||||
update_light_state();
|
update_light_state();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness)
|
int light_model_light_lightness_get(struct bt_mesh_model *model, int16_t *lightness)
|
||||||
{
|
{
|
||||||
return light_model_gen_level_get(model, lightness);
|
return light_model_gen_level_get(model, lightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness)
|
int light_model_light_lightness_set(struct bt_mesh_model *model, int16_t lightness)
|
||||||
{
|
{
|
||||||
return light_model_gen_level_set(model, lightness);
|
return light_model_gen_level_set(model, lightness);
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
#include "syscfg/syscfg.h"
|
#include "syscfg/syscfg.h"
|
||||||
#include "mesh/mesh.h"
|
#include "mesh/mesh.h"
|
||||||
|
|
||||||
int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state);
|
int light_model_gen_onoff_get(struct bt_mesh_model *model, uint8_t *state);
|
||||||
int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state);
|
int light_model_gen_onoff_set(struct bt_mesh_model *model, uint8_t state);
|
||||||
int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level);
|
int light_model_gen_level_get(struct bt_mesh_model *model, int16_t *level);
|
||||||
int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level);
|
int light_model_gen_level_set(struct bt_mesh_model *model, int16_t level);
|
||||||
int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness);
|
int light_model_light_lightness_get(struct bt_mesh_model *model, int16_t *lightness);
|
||||||
int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness);
|
int light_model_light_lightness_set(struct bt_mesh_model *model, int16_t lightness);
|
||||||
int light_model_init(void);
|
int light_model_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include "light_model.h"
|
#include "light_model.h"
|
||||||
|
|
||||||
|
|
||||||
static void model_bound_cb(u16_t addr, struct bt_mesh_model *model,
|
static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model,
|
||||||
u16_t key_idx)
|
uint16_t key_idx)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -84,30 +84,6 @@ static void gen_onoff_status(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf);
|
struct os_mbuf *buf);
|
||||||
|
|
||||||
/*
|
|
||||||
* Server Configuration Declaration
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv cfg_srv = {
|
|
||||||
.relay = BT_MESH_RELAY_DISABLED,
|
|
||||||
.beacon = BT_MESH_BEACON_ENABLED,
|
|
||||||
#if defined(CONFIG_BT_MESH_FRIEND)
|
|
||||||
.frnd = BT_MESH_FRIEND_ENABLED,
|
|
||||||
#else
|
|
||||||
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_BT_MESH_GATT_PROXY)
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
|
|
||||||
#else
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
.default_ttl = 7,
|
|
||||||
|
|
||||||
/* 3 transmissions with 20ms interval */
|
|
||||||
.net_transmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Client Configuration Declaration
|
* Client Configuration Declaration
|
||||||
*/
|
*/
|
||||||
@ -213,9 +189,9 @@ static const struct bt_mesh_model_op gen_onoff_cli_op[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct onoff_state {
|
struct onoff_state {
|
||||||
u8_t current;
|
uint8_t current;
|
||||||
u8_t previous;
|
uint8_t previous;
|
||||||
u8_t led_gpio_pin;
|
uint8_t led_gpio_pin;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -238,7 +214,7 @@ static struct onoff_state onoff_state_arr[] = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static struct bt_mesh_model root_models[] = {
|
static struct bt_mesh_model root_models[] = {
|
||||||
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
|
BT_MESH_MODEL_CFG_SRV,
|
||||||
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
|
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
|
||||||
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
||||||
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op,
|
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_op,
|
||||||
@ -320,20 +296,20 @@ static const struct bt_mesh_comp comp = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sw {
|
struct sw {
|
||||||
u8_t sw_num;
|
uint8_t sw_num;
|
||||||
u8_t onoff_state;
|
uint8_t onoff_state;
|
||||||
struct os_callout button_work;
|
struct os_callout button_work;
|
||||||
struct os_callout button_timer;
|
struct os_callout button_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static u8_t button_press_cnt;
|
static uint8_t button_press_cnt;
|
||||||
static struct sw sw;
|
static struct sw sw;
|
||||||
|
|
||||||
static u8_t trans_id;
|
static uint8_t trans_id;
|
||||||
static u32_t time, last_time;
|
static uint32_t time, last_time;
|
||||||
static u16_t primary_addr;
|
static uint16_t primary_addr;
|
||||||
static u16_t primary_net_idx;
|
static uint16_t primary_net_idx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic OnOff Model Server Message Handlers
|
* Generic OnOff Model Server Message Handlers
|
||||||
@ -416,7 +392,7 @@ static void gen_onoff_status(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t state;
|
uint8_t state;
|
||||||
|
|
||||||
state = net_buf_simple_pull_u8(buf);
|
state = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
@ -424,7 +400,7 @@ static void gen_onoff_status(struct bt_mesh_model *model,
|
|||||||
bt_mesh_model_elem(model)->addr, ctx->addr, state);
|
bt_mesh_model_elem(model)->addr, ctx->addr, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int output_number(bt_mesh_output_action_t action, u32_t number)
|
static int output_number(bt_mesh_output_action_t action, uint32_t number)
|
||||||
{
|
{
|
||||||
BT_INFO("OOB Number %u", number);
|
BT_INFO("OOB Number %u", number);
|
||||||
return 0;
|
return 0;
|
||||||
@ -436,7 +412,7 @@ static int output_string(const char *str)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
static void prov_complete(uint16_t net_idx, uint16_t addr)
|
||||||
{
|
{
|
||||||
BT_INFO("provisioning complete for net_idx 0x%04x addr 0x%04x",
|
BT_INFO("provisioning complete for net_idx 0x%04x addr 0x%04x",
|
||||||
net_idx, addr);
|
net_idx, addr);
|
||||||
@ -449,7 +425,7 @@ static void prov_reset(void)
|
|||||||
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
|
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
static uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
||||||
|
|
||||||
#define BUTTON_DEBOUNCE_DELAY_MS 250
|
#define BUTTON_DEBOUNCE_DELAY_MS 250
|
||||||
|
|
||||||
@ -528,7 +504,7 @@ static void button_pressed_worker(struct os_event *work)
|
|||||||
struct bt_mesh_model *mod_cli, *mod_srv;
|
struct bt_mesh_model *mod_cli, *mod_srv;
|
||||||
struct bt_mesh_model_pub *pub_cli, *pub_srv;
|
struct bt_mesh_model_pub *pub_cli, *pub_srv;
|
||||||
struct sw *sw = work->ev_arg;
|
struct sw *sw = work->ev_arg;
|
||||||
u8_t sw_idx = sw->sw_num;
|
uint8_t sw_idx = sw->sw_num;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mod_cli = mod_cli_sw[sw_idx];
|
mod_cli = mod_cli_sw[sw_idx];
|
||||||
@ -599,7 +575,7 @@ static const struct bt_mesh_prov prov = {
|
|||||||
.reset = prov_reset,
|
.reset = prov_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_led(u8_t dev)
|
void init_led(uint8_t dev)
|
||||||
{
|
{
|
||||||
hal_gpio_init_out(onoff_state_arr[dev].led_gpio_pin, 1);
|
hal_gpio_init_out(onoff_state_arr[dev].led_gpio_pin, 1);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#ifdef OOB_AUTH_ENABLE
|
#ifdef OOB_AUTH_ENABLE
|
||||||
|
|
||||||
static int output_number(bt_mesh_output_action_t action, u32_t number)
|
static int output_number(bt_mesh_output_action_t action, uint32_t number)
|
||||||
{
|
{
|
||||||
printk("OOB Number: %lu\n", number);
|
printk("OOB Number: %lu\n", number);
|
||||||
return 0;
|
return 0;
|
||||||
@ -48,7 +48,7 @@ static int output_string(const char *str)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
static void prov_complete(uint16_t net_idx, uint16_t addr)
|
||||||
{
|
{
|
||||||
printk("Local node provisioned, primary address 0x%04x\n", addr);
|
printk("Local node provisioned, primary address 0x%04x\n", addr);
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ static void prov_reset(void)
|
|||||||
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
|
bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
static uint8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID);
|
||||||
|
|
||||||
static const struct bt_mesh_prov prov = {
|
static const struct bt_mesh_prov prov = {
|
||||||
.uuid = dev_uuid,
|
.uuid = dev_uuid,
|
||||||
|
@ -36,31 +36,6 @@
|
|||||||
#include "state_binding.h"
|
#include "state_binding.h"
|
||||||
#include "transition.h"
|
#include "transition.h"
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv cfg_srv = {
|
|
||||||
.relay = BT_MESH_RELAY_ENABLED,
|
|
||||||
.beacon = BT_MESH_BEACON_ENABLED,
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_MESH_FRIEND)
|
|
||||||
.frnd = BT_MESH_FRIEND_ENABLED,
|
|
||||||
#else
|
|
||||||
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_MESH_GATT_PROXY)
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
|
|
||||||
#else
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.default_ttl = 7,
|
|
||||||
|
|
||||||
/* 2 transmissions with 20ms interval */
|
|
||||||
.net_transmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
|
|
||||||
/* 3 transmissions with 20ms interval */
|
|
||||||
.relay_retransmit = BT_MESH_TRANSMIT(3, 20),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct bt_mesh_health_srv health_srv = {
|
static struct bt_mesh_health_srv health_srv = {
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -224,8 +199,8 @@ static void gen_onoff_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, onoff, tt, delay;
|
uint8_t tid, onoff, tt, delay;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_onoff_state *state = model->user_data;
|
struct generic_onoff_state *state = model->user_data;
|
||||||
|
|
||||||
onoff = net_buf_simple_pull_u8(buf);
|
onoff = net_buf_simple_pull_u8(buf);
|
||||||
@ -290,8 +265,8 @@ static void gen_onoff_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, onoff, tt, delay;
|
uint8_t tid, onoff, tt, delay;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_onoff_state *state = model->user_data;
|
struct generic_onoff_state *state = model->user_data;
|
||||||
|
|
||||||
onoff = net_buf_simple_pull_u8(buf);
|
onoff = net_buf_simple_pull_u8(buf);
|
||||||
@ -422,12 +397,12 @@ static void gen_level_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t level;
|
int16_t level;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
level = (s16_t) net_buf_simple_pull_le16(buf);
|
level = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -494,12 +469,12 @@ static void gen_level_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t level;
|
int16_t level;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
level = (s16_t) net_buf_simple_pull_le16(buf);
|
level = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -569,12 +544,12 @@ static void gen_delta_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s32_t tmp32, delta;
|
int32_t tmp32, delta;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
delta = (s32_t) net_buf_simple_pull_le32(buf);
|
delta = (int32_t) net_buf_simple_pull_le32(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -658,12 +633,12 @@ static void gen_delta_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s32_t tmp32, delta;
|
int32_t tmp32, delta;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
delta = (s32_t) net_buf_simple_pull_le32(buf);
|
delta = (int32_t) net_buf_simple_pull_le32(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -805,13 +780,13 @@ static void gen_move_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta;
|
int16_t delta;
|
||||||
s32_t tmp32;
|
int32_t tmp32;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
delta = (s16_t) net_buf_simple_pull_le16(buf);
|
delta = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -886,13 +861,13 @@ static void gen_move_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta;
|
int16_t delta;
|
||||||
s32_t tmp32;
|
int32_t tmp32;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct generic_level_state *state = model->user_data;
|
struct generic_level_state *state = model->user_data;
|
||||||
|
|
||||||
delta = (s16_t) net_buf_simple_pull_le16(buf);
|
delta = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
now = k_uptime_get();
|
now = k_uptime_get();
|
||||||
@ -1021,7 +996,7 @@ static bool gen_def_trans_time_setunack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tt;
|
uint8_t tt;
|
||||||
struct gen_def_trans_time_state *state = model->user_data;
|
struct gen_def_trans_time_state *state = model->user_data;
|
||||||
|
|
||||||
tt = net_buf_simple_pull_u8(buf);
|
tt = net_buf_simple_pull_u8(buf);
|
||||||
@ -1122,7 +1097,7 @@ static bool gen_onpowerup_setunack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t onpowerup;
|
uint8_t onpowerup;
|
||||||
struct generic_onpowerup_state *state = model->user_data;
|
struct generic_onpowerup_state *state = model->user_data;
|
||||||
|
|
||||||
onpowerup = net_buf_simple_pull_u8(buf);
|
onpowerup = net_buf_simple_pull_u8(buf);
|
||||||
@ -1187,9 +1162,9 @@ static void vnd_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid;
|
uint8_t tid;
|
||||||
int current;
|
int current;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct vendor_state *state = model->user_data;
|
struct vendor_state *state = model->user_data;
|
||||||
|
|
||||||
current = net_buf_simple_pull_le16(buf);
|
current = net_buf_simple_pull_le16(buf);
|
||||||
@ -1290,9 +1265,9 @@ static void light_lightness_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
u16_t actual;
|
uint16_t actual;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
actual = net_buf_simple_pull_le16(buf);
|
actual = net_buf_simple_pull_le16(buf);
|
||||||
@ -1360,9 +1335,9 @@ static void light_lightness_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
u16_t actual;
|
uint16_t actual;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
actual = net_buf_simple_pull_le16(buf);
|
actual = net_buf_simple_pull_le16(buf);
|
||||||
@ -1483,9 +1458,9 @@ static void light_lightness_linear_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
u16_t linear;
|
uint16_t linear;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
linear = net_buf_simple_pull_le16(buf);
|
linear = net_buf_simple_pull_le16(buf);
|
||||||
@ -1546,9 +1521,9 @@ static void light_lightness_linear_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
u16_t linear;
|
uint16_t linear;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
linear = net_buf_simple_pull_le16(buf);
|
linear = net_buf_simple_pull_le16(buf);
|
||||||
@ -1690,7 +1665,7 @@ static void light_lightness_default_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u16_t lightness;
|
uint16_t lightness;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
lightness = net_buf_simple_pull_le16(buf);
|
lightness = net_buf_simple_pull_le16(buf);
|
||||||
@ -1741,7 +1716,7 @@ static bool light_lightness_range_setunack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u16_t min, max;
|
uint16_t min, max;
|
||||||
struct light_lightness_state *state = model->user_data;
|
struct light_lightness_state *state = model->user_data;
|
||||||
|
|
||||||
min = net_buf_simple_pull_le16(buf);
|
min = net_buf_simple_pull_le16(buf);
|
||||||
@ -1908,15 +1883,15 @@ static void light_ctl_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
u16_t lightness, temp;
|
uint16_t lightness, temp;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
lightness = net_buf_simple_pull_le16(buf);
|
lightness = net_buf_simple_pull_le16(buf);
|
||||||
temp = net_buf_simple_pull_le16(buf);
|
temp = net_buf_simple_pull_le16(buf);
|
||||||
delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
|
delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
||||||
@ -1991,15 +1966,15 @@ static void light_ctl_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
u16_t lightness, temp;
|
uint16_t lightness, temp;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
lightness = net_buf_simple_pull_le16(buf);
|
lightness = net_buf_simple_pull_le16(buf);
|
||||||
temp = net_buf_simple_pull_le16(buf);
|
temp = net_buf_simple_pull_le16(buf);
|
||||||
delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
|
delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
||||||
@ -2140,13 +2115,13 @@ static bool light_ctl_default_setunack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u16_t lightness, temp;
|
uint16_t lightness, temp;
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
lightness = net_buf_simple_pull_le16(buf);
|
lightness = net_buf_simple_pull_le16(buf);
|
||||||
temp = net_buf_simple_pull_le16(buf);
|
temp = net_buf_simple_pull_le16(buf);
|
||||||
delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
|
delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
|
|
||||||
/* Here, Model specification is silent about tid implementation */
|
/* Here, Model specification is silent about tid implementation */
|
||||||
|
|
||||||
@ -2216,7 +2191,7 @@ static bool light_ctl_temp_range_setunack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u16_t min, max;
|
uint16_t min, max;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
min = net_buf_simple_pull_le16(buf);
|
min = net_buf_simple_pull_le16(buf);
|
||||||
@ -2384,14 +2359,14 @@ static void light_ctl_temp_set_unack(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
u16_t temp;
|
uint16_t temp;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
temp = net_buf_simple_pull_le16(buf);
|
temp = net_buf_simple_pull_le16(buf);
|
||||||
delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
|
delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
||||||
@ -2463,14 +2438,14 @@ static void light_ctl_temp_set(struct bt_mesh_model *model,
|
|||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct os_mbuf *buf)
|
struct os_mbuf *buf)
|
||||||
{
|
{
|
||||||
u8_t tid, tt, delay;
|
uint8_t tid, tt, delay;
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
u16_t temp;
|
uint16_t temp;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
struct light_ctl_state *state = model->user_data;
|
struct light_ctl_state *state = model->user_data;
|
||||||
|
|
||||||
temp = net_buf_simple_pull_le16(buf);
|
temp = net_buf_simple_pull_le16(buf);
|
||||||
delta_uv = (s16_t) net_buf_simple_pull_le16(buf);
|
delta_uv = (int16_t) net_buf_simple_pull_le16(buf);
|
||||||
tid = net_buf_simple_pull_u8(buf);
|
tid = net_buf_simple_pull_u8(buf);
|
||||||
|
|
||||||
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
if (temp < TEMP_MIN || temp > TEMP_MAX) {
|
||||||
@ -2689,7 +2664,7 @@ static const struct bt_mesh_model_op vnd_ops[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct bt_mesh_model root_models[] = {
|
struct bt_mesh_model root_models[] = {
|
||||||
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
|
BT_MESH_MODEL_CFG_SRV,
|
||||||
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
||||||
|
|
||||||
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,
|
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV,
|
||||||
|
@ -46,109 +46,109 @@
|
|||||||
#define CANNOT_SET_RANGE_MAX 0x02
|
#define CANNOT_SET_RANGE_MAX 0x02
|
||||||
|
|
||||||
struct generic_onoff_state {
|
struct generic_onoff_state {
|
||||||
u8_t onoff;
|
uint8_t onoff;
|
||||||
u8_t target_onoff;
|
uint8_t target_onoff;
|
||||||
|
|
||||||
u8_t last_tid;
|
uint8_t last_tid;
|
||||||
u16_t last_src_addr;
|
uint16_t last_src_addr;
|
||||||
u16_t last_dst_addr;
|
uint16_t last_dst_addr;
|
||||||
s64_t last_msg_timestamp;
|
int64_t last_msg_timestamp;
|
||||||
|
|
||||||
s32_t tt_delta;
|
int32_t tt_delta;
|
||||||
|
|
||||||
struct transition *transition;
|
struct transition *transition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct generic_level_state {
|
struct generic_level_state {
|
||||||
s16_t level;
|
int16_t level;
|
||||||
s16_t target_level;
|
int16_t target_level;
|
||||||
|
|
||||||
s16_t last_level;
|
int16_t last_level;
|
||||||
s32_t last_delta;
|
int32_t last_delta;
|
||||||
|
|
||||||
u8_t last_tid;
|
uint8_t last_tid;
|
||||||
u16_t last_src_addr;
|
uint16_t last_src_addr;
|
||||||
u16_t last_dst_addr;
|
uint16_t last_dst_addr;
|
||||||
s64_t last_msg_timestamp;
|
int64_t last_msg_timestamp;
|
||||||
|
|
||||||
s32_t tt_delta;
|
int32_t tt_delta;
|
||||||
|
|
||||||
struct transition *transition;
|
struct transition *transition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct generic_onpowerup_state {
|
struct generic_onpowerup_state {
|
||||||
u8_t onpowerup;
|
uint8_t onpowerup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gen_def_trans_time_state {
|
struct gen_def_trans_time_state {
|
||||||
u8_t tt;
|
uint8_t tt;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vendor_state {
|
struct vendor_state {
|
||||||
int current;
|
int current;
|
||||||
u32_t response;
|
uint32_t response;
|
||||||
u8_t last_tid;
|
uint8_t last_tid;
|
||||||
u16_t last_src_addr;
|
uint16_t last_src_addr;
|
||||||
u16_t last_dst_addr;
|
uint16_t last_dst_addr;
|
||||||
s64_t last_msg_timestamp;
|
int64_t last_msg_timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct light_lightness_state {
|
struct light_lightness_state {
|
||||||
u16_t linear;
|
uint16_t linear;
|
||||||
u16_t target_linear;
|
uint16_t target_linear;
|
||||||
|
|
||||||
u16_t actual;
|
uint16_t actual;
|
||||||
u16_t target_actual;
|
uint16_t target_actual;
|
||||||
|
|
||||||
u16_t last;
|
uint16_t last;
|
||||||
u16_t def;
|
uint16_t def;
|
||||||
|
|
||||||
u8_t status_code;
|
uint8_t status_code;
|
||||||
u16_t light_range_min;
|
uint16_t light_range_min;
|
||||||
u16_t light_range_max;
|
uint16_t light_range_max;
|
||||||
u32_t lightness_range;
|
uint32_t lightness_range;
|
||||||
|
|
||||||
u8_t last_tid;
|
uint8_t last_tid;
|
||||||
u16_t last_src_addr;
|
uint16_t last_src_addr;
|
||||||
u16_t last_dst_addr;
|
uint16_t last_dst_addr;
|
||||||
s64_t last_msg_timestamp;
|
int64_t last_msg_timestamp;
|
||||||
|
|
||||||
s32_t tt_delta_actual;
|
int32_t tt_delta_actual;
|
||||||
s32_t tt_delta_linear;
|
int32_t tt_delta_linear;
|
||||||
|
|
||||||
struct transition *transition;
|
struct transition *transition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct light_ctl_state {
|
struct light_ctl_state {
|
||||||
u16_t lightness;
|
uint16_t lightness;
|
||||||
u16_t target_lightness;
|
uint16_t target_lightness;
|
||||||
|
|
||||||
u16_t temp;
|
uint16_t temp;
|
||||||
u16_t target_temp;
|
uint16_t target_temp;
|
||||||
|
|
||||||
s16_t delta_uv;
|
int16_t delta_uv;
|
||||||
s16_t target_delta_uv;
|
int16_t target_delta_uv;
|
||||||
|
|
||||||
u8_t status_code;
|
uint8_t status_code;
|
||||||
u16_t temp_range_min;
|
uint16_t temp_range_min;
|
||||||
u16_t temp_range_max;
|
uint16_t temp_range_max;
|
||||||
u32_t temperature_range;
|
uint32_t temperature_range;
|
||||||
|
|
||||||
u16_t lightness_def;
|
uint16_t lightness_def;
|
||||||
u16_t temp_def;
|
uint16_t temp_def;
|
||||||
u32_t lightness_temp_def;
|
uint32_t lightness_temp_def;
|
||||||
s16_t delta_uv_def;
|
int16_t delta_uv_def;
|
||||||
|
|
||||||
u32_t lightness_temp_last;
|
uint32_t lightness_temp_last;
|
||||||
|
|
||||||
u8_t last_tid;
|
uint8_t last_tid;
|
||||||
u16_t last_src_addr;
|
uint16_t last_src_addr;
|
||||||
u16_t last_dst_addr;
|
uint16_t last_dst_addr;
|
||||||
s64_t last_msg_timestamp;
|
int64_t last_msg_timestamp;
|
||||||
|
|
||||||
s32_t tt_delta_lightness;
|
int32_t tt_delta_lightness;
|
||||||
s32_t tt_delta_temp;
|
int32_t tt_delta_temp;
|
||||||
s32_t tt_delta_duv;
|
int32_t tt_delta_duv;
|
||||||
|
|
||||||
struct transition *transition;
|
struct transition *transition;
|
||||||
};
|
};
|
||||||
|
@ -59,14 +59,14 @@ static void light_default_var_init(void)
|
|||||||
light_ctl_srv_user_data.temp_def = TEMP_MIN;
|
light_ctl_srv_user_data.temp_def = TEMP_MIN;
|
||||||
|
|
||||||
light_ctl_srv_user_data.lightness_temp_last =
|
light_ctl_srv_user_data.lightness_temp_last =
|
||||||
(u32_t) ((LIGHTNESS_MAX << 16) | TEMP_MIN);
|
(uint32_t) ((LIGHTNESS_MAX << 16) | TEMP_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void light_default_status_init(void)
|
static void light_default_status_init(void)
|
||||||
{
|
{
|
||||||
u16_t lightness;
|
uint16_t lightness;
|
||||||
|
|
||||||
lightness = (u16_t) (light_ctl_srv_user_data.lightness_temp_last >> 16);
|
lightness = (uint16_t) (light_ctl_srv_user_data.lightness_temp_last >> 16);
|
||||||
|
|
||||||
if (lightness) {
|
if (lightness) {
|
||||||
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
gen_onoff_srv_root_user_data.onoff = STATE_ON;
|
||||||
@ -77,10 +77,10 @@ static void light_default_status_init(void)
|
|||||||
/* Retrieve Default Lightness & Temperature Values */
|
/* Retrieve Default Lightness & Temperature Values */
|
||||||
|
|
||||||
if (light_ctl_srv_user_data.lightness_temp_def) {
|
if (light_ctl_srv_user_data.lightness_temp_def) {
|
||||||
light_ctl_srv_user_data.lightness_def = (u16_t)
|
light_ctl_srv_user_data.lightness_def = (uint16_t)
|
||||||
(light_ctl_srv_user_data.lightness_temp_def >> 16);
|
(light_ctl_srv_user_data.lightness_temp_def >> 16);
|
||||||
|
|
||||||
light_ctl_srv_user_data.temp_def = (u16_t)
|
light_ctl_srv_user_data.temp_def = (uint16_t)
|
||||||
(light_ctl_srv_user_data.lightness_temp_def);
|
(light_ctl_srv_user_data.lightness_temp_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,18 +92,18 @@ static void light_default_status_init(void)
|
|||||||
/* Retrieve Range of Lightness & Temperature */
|
/* Retrieve Range of Lightness & Temperature */
|
||||||
|
|
||||||
if (light_lightness_srv_user_data.lightness_range) {
|
if (light_lightness_srv_user_data.lightness_range) {
|
||||||
light_lightness_srv_user_data.light_range_max = (u16_t)
|
light_lightness_srv_user_data.light_range_max = (uint16_t)
|
||||||
(light_lightness_srv_user_data.lightness_range >> 16);
|
(light_lightness_srv_user_data.lightness_range >> 16);
|
||||||
|
|
||||||
light_lightness_srv_user_data.light_range_min = (u16_t)
|
light_lightness_srv_user_data.light_range_min = (uint16_t)
|
||||||
(light_lightness_srv_user_data.lightness_range);
|
(light_lightness_srv_user_data.lightness_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (light_ctl_srv_user_data.temperature_range) {
|
if (light_ctl_srv_user_data.temperature_range) {
|
||||||
light_ctl_srv_user_data.temp_range_max = (u16_t)
|
light_ctl_srv_user_data.temp_range_max = (uint16_t)
|
||||||
(light_ctl_srv_user_data.temperature_range >> 16);
|
(light_ctl_srv_user_data.temperature_range >> 16);
|
||||||
|
|
||||||
light_ctl_srv_user_data.temp_range_min = (u16_t)
|
light_ctl_srv_user_data.temp_range_min = (uint16_t)
|
||||||
(light_ctl_srv_user_data.temperature_range);
|
(light_ctl_srv_user_data.temperature_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,11 +117,11 @@ static void light_default_status_init(void)
|
|||||||
state_binding(ONOFF, ONOFF_TEMP);
|
state_binding(ONOFF, ONOFF_TEMP);
|
||||||
break;
|
break;
|
||||||
case STATE_RESTORE:
|
case STATE_RESTORE:
|
||||||
light_lightness_srv_user_data.last = (u16_t)
|
light_lightness_srv_user_data.last = (uint16_t)
|
||||||
(light_ctl_srv_user_data.lightness_temp_last >> 16);
|
(light_ctl_srv_user_data.lightness_temp_last >> 16);
|
||||||
|
|
||||||
light_ctl_srv_user_data.temp =
|
light_ctl_srv_user_data.temp =
|
||||||
(u16_t) (light_ctl_srv_user_data.lightness_temp_last);
|
(uint16_t) (light_ctl_srv_user_data.lightness_temp_last);
|
||||||
|
|
||||||
state_binding(ONPOWERUP, ONOFF_TEMP);
|
state_binding(ONPOWERUP, ONOFF_TEMP);
|
||||||
break;
|
break;
|
||||||
@ -132,7 +132,7 @@ static void light_default_status_init(void)
|
|||||||
|
|
||||||
void update_light_state(void)
|
void update_light_state(void)
|
||||||
{
|
{
|
||||||
u8_t power, color;
|
uint8_t power, color;
|
||||||
|
|
||||||
power = 100 * ((float) lightness / 65535);
|
power = 100 * ((float) lightness / 65535);
|
||||||
color = 100 * ((float) (temperature + 32768) / 65535);
|
color = 100 * ((float) (temperature + 32768) / 65535);
|
||||||
|
@ -41,12 +41,12 @@
|
|||||||
static bool is_randomization_of_TIDs_done;
|
static bool is_randomization_of_TIDs_done;
|
||||||
|
|
||||||
#if (defined(ONOFF) || defined(ONOFF_TT))
|
#if (defined(ONOFF) || defined(ONOFF_TT))
|
||||||
static u8_t tid_onoff;
|
static uint8_t tid_onoff;
|
||||||
#elif defined(VND_MODEL_TEST)
|
#elif defined(VND_MODEL_TEST)
|
||||||
static u8_t tid_vnd;
|
static uint8_t tid_vnd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static u8_t tid_level;
|
static uint8_t tid_level;
|
||||||
|
|
||||||
void randomize_publishers_TID(void)
|
void randomize_publishers_TID(void)
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ void randomize_publishers_TID(void)
|
|||||||
is_randomization_of_TIDs_done = true;
|
is_randomization_of_TIDs_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32_t button_read(int button)
|
static uint32_t button_read(int button)
|
||||||
{
|
{
|
||||||
return (uint32_t) hal_gpio_read(button);
|
return (uint32_t) hal_gpio_read(button);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@
|
|||||||
#include "transition.h"
|
#include "transition.h"
|
||||||
|
|
||||||
|
|
||||||
u16_t lightness, target_lightness;
|
uint16_t lightness, target_lightness;
|
||||||
s16_t temperature, target_temperature;
|
int16_t temperature, target_temperature;
|
||||||
|
|
||||||
static s32_t ceiling(float num)
|
static int32_t ceiling(float num)
|
||||||
{
|
{
|
||||||
s32_t inum;
|
int32_t inum;
|
||||||
|
|
||||||
inum = (s32_t) num;
|
inum = (int32_t) num;
|
||||||
if (num == (float) inum) {
|
if (num == (float) inum) {
|
||||||
return inum;
|
return inum;
|
||||||
}
|
}
|
||||||
@ -47,21 +47,21 @@ static s32_t ceiling(float num)
|
|||||||
return inum + 1;
|
return inum + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16_t actual_to_linear(u16_t val)
|
uint16_t actual_to_linear(uint16_t val)
|
||||||
{
|
{
|
||||||
float tmp;
|
float tmp;
|
||||||
|
|
||||||
tmp = ((float) val / 65535);
|
tmp = ((float) val / 65535);
|
||||||
|
|
||||||
return (u16_t) ceiling(65535 * tmp * tmp);
|
return (uint16_t) ceiling(65535 * tmp * tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16_t linear_to_actual(u16_t val)
|
uint16_t linear_to_actual(uint16_t val)
|
||||||
{
|
{
|
||||||
return (u16_t) (65535 * sqrt(((float) val / 65535)));
|
return (uint16_t) (65535 * sqrt(((float) val / 65535)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void constrain_lightness(u16_t var)
|
static void constrain_lightness(uint16_t var)
|
||||||
{
|
{
|
||||||
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
||||||
var = light_lightness_srv_user_data.light_range_min;
|
var = light_lightness_srv_user_data.light_range_min;
|
||||||
@ -72,7 +72,7 @@ static void constrain_lightness(u16_t var)
|
|||||||
lightness = var;
|
lightness = var;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void constrain_lightness2(u16_t var)
|
static void constrain_lightness2(uint16_t var)
|
||||||
{
|
{
|
||||||
/* This is as per Mesh Model Specification 3.3.2.2.3 */
|
/* This is as per Mesh Model Specification 3.3.2.2.3 */
|
||||||
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
if (var > 0 && var < light_lightness_srv_user_data.light_range_min) {
|
||||||
@ -88,7 +88,7 @@ static void constrain_lightness2(u16_t var)
|
|||||||
lightness = var;
|
lightness = var;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void constrain_target_lightness(u16_t var)
|
static void constrain_target_lightness(uint16_t var)
|
||||||
{
|
{
|
||||||
if (var > 0 &&
|
if (var > 0 &&
|
||||||
var < light_lightness_srv_user_data.light_range_min) {
|
var < light_lightness_srv_user_data.light_range_min) {
|
||||||
@ -100,7 +100,7 @@ static void constrain_target_lightness(u16_t var)
|
|||||||
target_lightness = var;
|
target_lightness = var;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s16_t light_ctl_temp_to_level(u16_t temp)
|
static int16_t light_ctl_temp_to_level(uint16_t temp)
|
||||||
{
|
{
|
||||||
float tmp;
|
float tmp;
|
||||||
|
|
||||||
@ -111,14 +111,14 @@ static s16_t light_ctl_temp_to_level(u16_t temp)
|
|||||||
tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
|
tmp = tmp / (light_ctl_srv_user_data.temp_range_max -
|
||||||
light_ctl_srv_user_data.temp_range_min);
|
light_ctl_srv_user_data.temp_range_min);
|
||||||
|
|
||||||
return (s16_t) (tmp - 32768);
|
return (int16_t) (tmp - 32768);
|
||||||
|
|
||||||
/* 6.1.3.1.1 2nd formula end */
|
/* 6.1.3.1.1 2nd formula end */
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16_t level_to_light_ctl_temp(s16_t level)
|
static uint16_t level_to_light_ctl_temp(int16_t level)
|
||||||
{
|
{
|
||||||
u16_t tmp;
|
uint16_t tmp;
|
||||||
float diff;
|
float diff;
|
||||||
|
|
||||||
/* Mesh Model Specification 6.1.3.1.1 1st formula start */
|
/* Mesh Model Specification 6.1.3.1.1 1st formula start */
|
||||||
@ -126,14 +126,14 @@ static u16_t level_to_light_ctl_temp(s16_t level)
|
|||||||
light_ctl_srv_user_data.temp_range_min) / 65535;
|
light_ctl_srv_user_data.temp_range_min) / 65535;
|
||||||
|
|
||||||
|
|
||||||
tmp = (u16_t) ((level + 32768) * diff);
|
tmp = (uint16_t) ((level + 32768) * diff);
|
||||||
|
|
||||||
return (light_ctl_srv_user_data.temp_range_min + tmp);
|
return (light_ctl_srv_user_data.temp_range_min + tmp);
|
||||||
|
|
||||||
/* 6.1.3.1.1 1st formula end */
|
/* 6.1.3.1.1 1st formula end */
|
||||||
}
|
}
|
||||||
|
|
||||||
void state_binding(u8_t light, u8_t temp)
|
void state_binding(uint8_t light, uint8_t temp)
|
||||||
{
|
{
|
||||||
switch (temp) {
|
switch (temp) {
|
||||||
case ONOFF_TEMP:
|
case ONOFF_TEMP:
|
||||||
@ -211,10 +211,10 @@ jump:
|
|||||||
light_ctl_srv_user_data.lightness = lightness;
|
light_ctl_srv_user_data.lightness = lightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculate_lightness_target_values(u8_t type)
|
void calculate_lightness_target_values(uint8_t type)
|
||||||
{
|
{
|
||||||
bool set_light_ctl_temp_target_value;
|
bool set_light_ctl_temp_target_value;
|
||||||
u16_t tmp;
|
uint16_t tmp;
|
||||||
|
|
||||||
set_light_ctl_temp_target_value = true;
|
set_light_ctl_temp_target_value = true;
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ void calculate_lightness_target_values(u8_t type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculate_temp_target_values(u8_t type)
|
void calculate_temp_target_values(uint8_t type)
|
||||||
{
|
{
|
||||||
bool set_light_ctl_delta_uv_target_value;
|
bool set_light_ctl_delta_uv_target_value;
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ enum state_binding {
|
|||||||
IGNORE_TEMP
|
IGNORE_TEMP
|
||||||
};
|
};
|
||||||
|
|
||||||
extern u16_t lightness, target_lightness;
|
extern uint16_t lightness, target_lightness;
|
||||||
extern s16_t temperature, target_temperature;
|
extern int16_t temperature, target_temperature;
|
||||||
|
|
||||||
void state_binding(u8_t lightness, u8_t temperature);
|
void state_binding(uint8_t lightness, uint8_t temperature);
|
||||||
void calculate_lightness_target_values(u8_t type);
|
void calculate_lightness_target_values(uint8_t type);
|
||||||
void calculate_temp_target_values(u8_t type);
|
void calculate_temp_target_values(uint8_t type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#include "device_composition.h"
|
#include "device_composition.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
static u8_t storage_id;
|
static uint8_t storage_id;
|
||||||
u8_t reset_counter;
|
uint8_t reset_counter;
|
||||||
|
|
||||||
static void save_reset_counter(void)
|
static void save_reset_counter(void)
|
||||||
{
|
{
|
||||||
@ -76,7 +76,7 @@ static void save_lightness_temp_def_state(void)
|
|||||||
char buf[12];
|
char buf[12];
|
||||||
|
|
||||||
light_ctl_srv_user_data.lightness_temp_def =
|
light_ctl_srv_user_data.lightness_temp_def =
|
||||||
(u32_t) ((light_ctl_srv_user_data.lightness_def << 16) |
|
(uint32_t) ((light_ctl_srv_user_data.lightness_def << 16) |
|
||||||
light_ctl_srv_user_data.temp_def);
|
light_ctl_srv_user_data.temp_def);
|
||||||
|
|
||||||
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_def,
|
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_def,
|
||||||
@ -91,7 +91,7 @@ static void save_lightness_temp_last_state(void)
|
|||||||
char buf[12];
|
char buf[12];
|
||||||
|
|
||||||
light_ctl_srv_user_data.lightness_temp_last =
|
light_ctl_srv_user_data.lightness_temp_last =
|
||||||
(u32_t) ((light_ctl_srv_user_data.lightness << 16) |
|
(uint32_t) ((light_ctl_srv_user_data.lightness << 16) |
|
||||||
light_ctl_srv_user_data.temp);
|
light_ctl_srv_user_data.temp);
|
||||||
|
|
||||||
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_last,
|
settings_str_from_bytes(&light_ctl_srv_user_data.lightness_temp_last,
|
||||||
@ -108,7 +108,7 @@ static void save_lightness_range(void)
|
|||||||
char buf[12];
|
char buf[12];
|
||||||
|
|
||||||
light_lightness_srv_user_data.lightness_range =
|
light_lightness_srv_user_data.lightness_range =
|
||||||
(u32_t) ((light_lightness_srv_user_data.light_range_max << 16) |
|
(uint32_t) ((light_lightness_srv_user_data.light_range_max << 16) |
|
||||||
light_lightness_srv_user_data.light_range_min);
|
light_lightness_srv_user_data.light_range_min);
|
||||||
|
|
||||||
settings_str_from_bytes(&light_lightness_srv_user_data.lightness_range,
|
settings_str_from_bytes(&light_lightness_srv_user_data.lightness_range,
|
||||||
@ -123,7 +123,7 @@ static void save_temperature_range(void)
|
|||||||
char buf[12];
|
char buf[12];
|
||||||
|
|
||||||
light_ctl_srv_user_data.temperature_range =
|
light_ctl_srv_user_data.temperature_range =
|
||||||
(u32_t) ((light_ctl_srv_user_data.temp_range_max << 16) |
|
(uint32_t) ((light_ctl_srv_user_data.temp_range_max << 16) |
|
||||||
light_ctl_srv_user_data.temp_range_min);
|
light_ctl_srv_user_data.temp_range_min);
|
||||||
|
|
||||||
settings_str_from_bytes(&light_ctl_srv_user_data.temperature_range,
|
settings_str_from_bytes(&light_ctl_srv_user_data.temperature_range,
|
||||||
@ -162,7 +162,7 @@ static void storage_work_handler(struct os_event *work)
|
|||||||
|
|
||||||
struct os_callout storage_work;
|
struct os_callout storage_work;
|
||||||
|
|
||||||
void save_on_flash(u8_t id)
|
void save_on_flash(uint8_t id)
|
||||||
{
|
{
|
||||||
storage_id = id;
|
storage_id = id;
|
||||||
os_callout_reset(&storage_work, 0);
|
os_callout_reset(&storage_work, 0);
|
||||||
|
@ -37,11 +37,11 @@ enum ps_variables_id {
|
|||||||
TEMPERATURE_RANGE
|
TEMPERATURE_RANGE
|
||||||
};
|
};
|
||||||
|
|
||||||
extern u8_t reset_counter;
|
extern uint8_t reset_counter;
|
||||||
|
|
||||||
extern struct os_callout storage_work;
|
extern struct os_callout storage_work;
|
||||||
|
|
||||||
int ps_settings_init(void);
|
int ps_settings_init(void);
|
||||||
void save_on_flash(u8_t id);
|
void save_on_flash(uint8_t id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,8 +40,8 @@ struct os_callout light_ctl_temp_work;
|
|||||||
|
|
||||||
struct os_callout dummy_timer;
|
struct os_callout dummy_timer;
|
||||||
|
|
||||||
u8_t transition_type, default_tt;
|
uint8_t transition_type, default_tt;
|
||||||
u32_t *ptr_counter;
|
uint32_t *ptr_counter;
|
||||||
struct os_callout *ptr_timer = &dummy_timer;
|
struct os_callout *ptr_timer = &dummy_timer;
|
||||||
|
|
||||||
struct transition lightness_transition, temp_transition;
|
struct transition lightness_transition, temp_transition;
|
||||||
@ -50,9 +50,9 @@ struct transition lightness_transition, temp_transition;
|
|||||||
|
|
||||||
void calculate_rt(struct transition *transition)
|
void calculate_rt(struct transition *transition)
|
||||||
{
|
{
|
||||||
u8_t steps, resolution;
|
uint8_t steps, resolution;
|
||||||
s32_t duration_remainder;
|
int32_t duration_remainder;
|
||||||
s64_t now;
|
int64_t now;
|
||||||
|
|
||||||
if (transition->just_started) {
|
if (transition->just_started) {
|
||||||
transition->rt = transition->tt;
|
transition->rt = transition->tt;
|
||||||
@ -88,7 +88,7 @@ void calculate_rt(struct transition *transition)
|
|||||||
|
|
||||||
/* Function to calculate Remaining Time (End) */
|
/* Function to calculate Remaining Time (End) */
|
||||||
|
|
||||||
static void bound_states_transition_type_reassignment(u8_t type)
|
static void bound_states_transition_type_reassignment(uint8_t type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ONOFF:
|
case ONOFF:
|
||||||
@ -113,7 +113,7 @@ static void bound_states_transition_type_reassignment(u8_t type)
|
|||||||
|
|
||||||
static void tt_values_calculator(struct transition *transition)
|
static void tt_values_calculator(struct transition *transition)
|
||||||
{
|
{
|
||||||
u8_t steps_multiplier, resolution;
|
uint8_t steps_multiplier, resolution;
|
||||||
|
|
||||||
resolution = (transition->tt >> 6);
|
resolution = (transition->tt >> 6);
|
||||||
steps_multiplier = (transition->tt & 0x3F);
|
steps_multiplier = (transition->tt & 0x3F);
|
||||||
@ -142,7 +142,7 @@ static void tt_values_calculator(struct transition *transition)
|
|||||||
ptr_counter = &transition->counter;
|
ptr_counter = &transition->counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onoff_tt_values(struct generic_onoff_state *state, u8_t tt, u8_t delay)
|
void onoff_tt_values(struct generic_onoff_state *state, uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
bound_states_transition_type_reassignment(ONOFF);
|
bound_states_transition_type_reassignment(ONOFF);
|
||||||
calculate_lightness_target_values(ONOFF);
|
calculate_lightness_target_values(ONOFF);
|
||||||
@ -162,7 +162,7 @@ void onoff_tt_values(struct generic_onoff_state *state, u8_t tt, u8_t delay)
|
|||||||
state->transition->counter);
|
state->transition->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void level_tt_values(struct generic_level_state *state, u8_t tt, u8_t delay)
|
void level_tt_values(struct generic_level_state *state, uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
if (state == &gen_level_srv_root_user_data) {
|
if (state == &gen_level_srv_root_user_data) {
|
||||||
bound_states_transition_type_reassignment(LEVEL);
|
bound_states_transition_type_reassignment(LEVEL);
|
||||||
@ -188,7 +188,7 @@ void level_tt_values(struct generic_level_state *state, u8_t tt, u8_t delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
||||||
u8_t tt, u8_t delay)
|
uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
bound_states_transition_type_reassignment(ACTUAL);
|
bound_states_transition_type_reassignment(ACTUAL);
|
||||||
calculate_lightness_target_values(ACTUAL);
|
calculate_lightness_target_values(ACTUAL);
|
||||||
@ -210,7 +210,7 @@ void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
||||||
u8_t tt, u8_t delay)
|
uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
bound_states_transition_type_reassignment(LINEAR);
|
bound_states_transition_type_reassignment(LINEAR);
|
||||||
calculate_lightness_target_values(LINEAR);
|
calculate_lightness_target_values(LINEAR);
|
||||||
@ -231,7 +231,7 @@ void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
|||||||
state->transition->counter);
|
state->transition->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void light_ctl_tt_values(struct light_ctl_state *state, u8_t tt, u8_t delay)
|
void light_ctl_tt_values(struct light_ctl_state *state, uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
bound_states_transition_type_reassignment(CTL);
|
bound_states_transition_type_reassignment(CTL);
|
||||||
calculate_lightness_target_values(CTL);
|
calculate_lightness_target_values(CTL);
|
||||||
@ -261,7 +261,7 @@ void light_ctl_tt_values(struct light_ctl_state *state, u8_t tt, u8_t delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void light_ctl_temp_tt_values(struct light_ctl_state *state,
|
void light_ctl_temp_tt_values(struct light_ctl_state *state,
|
||||||
u8_t tt, u8_t delay)
|
uint8_t tt, uint8_t delay)
|
||||||
{
|
{
|
||||||
bound_states_transition_type_reassignment(CTL_TEMP);
|
bound_states_transition_type_reassignment(CTL_TEMP);
|
||||||
calculate_temp_target_values(CTL_TEMP);
|
calculate_temp_target_values(CTL_TEMP);
|
||||||
@ -331,7 +331,7 @@ static void onoff_work_handler(struct os_event *work)
|
|||||||
|
|
||||||
static void level_lightness_work_handler(struct os_event *work)
|
static void level_lightness_work_handler(struct os_event *work)
|
||||||
{
|
{
|
||||||
u8_t level;
|
uint8_t level;
|
||||||
struct generic_level_state *state = &gen_level_srv_root_user_data;
|
struct generic_level_state *state = &gen_level_srv_root_user_data;
|
||||||
|
|
||||||
switch (transition_type) {
|
switch (transition_type) {
|
||||||
|
@ -42,19 +42,19 @@ enum level_transition_types {
|
|||||||
|
|
||||||
struct transition {
|
struct transition {
|
||||||
bool just_started;
|
bool just_started;
|
||||||
u8_t tt;
|
uint8_t tt;
|
||||||
u8_t rt;
|
uint8_t rt;
|
||||||
u8_t delay;
|
uint8_t delay;
|
||||||
u32_t quo_tt;
|
uint32_t quo_tt;
|
||||||
u32_t counter;
|
uint32_t counter;
|
||||||
u32_t total_duration;
|
uint32_t total_duration;
|
||||||
s64_t start_timestamp;
|
int64_t start_timestamp;
|
||||||
|
|
||||||
struct os_callout timer;
|
struct os_callout timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern u8_t transition_type, default_tt;
|
extern uint8_t transition_type, default_tt;
|
||||||
extern u32_t *ptr_counter;
|
extern uint32_t *ptr_counter;
|
||||||
extern struct os_callout *ptr_timer;
|
extern struct os_callout *ptr_timer;
|
||||||
|
|
||||||
extern struct transition lightness_transition, temp_transition;
|
extern struct transition lightness_transition, temp_transition;
|
||||||
@ -64,15 +64,15 @@ extern struct os_callout dummy_timer;
|
|||||||
void calculate_rt(struct transition *transition);
|
void calculate_rt(struct transition *transition);
|
||||||
|
|
||||||
|
|
||||||
void onoff_tt_values(struct generic_onoff_state *state, u8_t tt, u8_t delay);
|
void onoff_tt_values(struct generic_onoff_state *state, uint8_t tt, uint8_t delay);
|
||||||
void level_tt_values(struct generic_level_state *state, u8_t tt, u8_t delay);
|
void level_tt_values(struct generic_level_state *state, uint8_t tt, uint8_t delay);
|
||||||
void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
void light_lightness_actual_tt_values(struct light_lightness_state *state,
|
||||||
u8_t tt, u8_t delay);
|
uint8_t tt, uint8_t delay);
|
||||||
void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
void light_lightness_linear_tt_values(struct light_lightness_state *state,
|
||||||
u8_t tt, u8_t delay);
|
uint8_t tt, uint8_t delay);
|
||||||
void light_ctl_tt_values(struct light_ctl_state *state, u8_t tt, u8_t delay);
|
void light_ctl_tt_values(struct light_ctl_state *state, uint8_t tt, uint8_t delay);
|
||||||
void light_ctl_temp_tt_values(struct light_ctl_state *state,
|
void light_ctl_temp_tt_values(struct light_ctl_state *state,
|
||||||
u8_t tt, u8_t delay);
|
uint8_t tt, uint8_t delay);
|
||||||
|
|
||||||
void onoff_handler(struct generic_onoff_state *state);
|
void onoff_handler(struct generic_onoff_state *state);
|
||||||
void level_lightness_handler(struct generic_level_state *state);
|
void level_lightness_handler(struct generic_level_state *state);
|
||||||
|
@ -44,21 +44,21 @@ void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst,
|
|||||||
payload_len);
|
payload_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void model_bound_cb(u16_t addr, struct bt_mesh_model *model,
|
static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model,
|
||||||
u16_t key_idx)
|
uint16_t key_idx)
|
||||||
{
|
{
|
||||||
console_printf("Model bound: remote addr 0x%04x key_idx 0x%04x model %p\n",
|
console_printf("Model bound: remote addr 0x%04x key_idx 0x%04x model %p\n",
|
||||||
addr, key_idx, model);
|
addr, key_idx, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void model_unbound_cb(u16_t addr, struct bt_mesh_model *model,
|
static void model_unbound_cb(uint16_t addr, struct bt_mesh_model *model,
|
||||||
u16_t key_idx)
|
uint16_t key_idx)
|
||||||
{
|
{
|
||||||
console_printf("Model unbound: remote addr 0x%04x key_idx 0x%04x "
|
console_printf("Model unbound: remote addr 0x%04x key_idx 0x%04x "
|
||||||
"model %p\n", addr, key_idx, model);
|
"model %p\n", addr, key_idx, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invalid_bearer_cb(u8_t opcode)
|
static void invalid_bearer_cb(uint8_t opcode)
|
||||||
{
|
{
|
||||||
console_printf("Invalid bearer: opcode 0x%02x\n", opcode);
|
console_printf("Invalid bearer: opcode 0x%02x\n", opcode);
|
||||||
}
|
}
|
||||||
|
@ -837,14 +837,6 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
|||||||
MODLOG_DFLT(INFO, "Data buf %s\n", data_buf ? "OK" : "NOK");
|
MODLOG_DFLT(INFO, "Data buf %s\n", data_buf ? "OK" : "NOK");
|
||||||
assert(data_buf != NULL);
|
assert(data_buf != NULL);
|
||||||
|
|
||||||
/* The first 2 bytes of data is the size of appended pattern data. */
|
|
||||||
rc = os_mbuf_append(data_buf, (uint8_t[]) {data_len >> 8, data_len},
|
|
||||||
2);
|
|
||||||
if (rc) {
|
|
||||||
os_mbuf_free_chain(data_buf);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill mbuf with the pattern */
|
/* Fill mbuf with the pattern */
|
||||||
stress_fill_mbuf_with_pattern(data_buf, data_len);
|
stress_fill_mbuf_with_pattern(data_buf, data_len);
|
||||||
|
|
||||||
@ -852,8 +844,13 @@ rx_stress_10_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
|||||||
rc = ble_l2cap_send(rx_stress_ctx->chan, data_buf);
|
rc = ble_l2cap_send(rx_stress_ctx->chan, data_buf);
|
||||||
MODLOG_DFLT(INFO, "Return code=%d\n", rc);
|
MODLOG_DFLT(INFO, "Return code=%d\n", rc);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
if (rc == BLE_HS_ESTALLED) {
|
||||||
MODLOG_DFLT(INFO, "L2CAP stalled - waiting\n");
|
MODLOG_DFLT(INFO, "L2CAP stalled - waiting\n");
|
||||||
stalled = true;
|
stalled = true;
|
||||||
|
} else {
|
||||||
|
MODLOG_DFLT(INFO, "Sending data via L2CAP failed with error "
|
||||||
|
"code %d\n", rc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MODLOG_DFLT(INFO, " %d, %d\n", ++send_cnt, data_len);
|
MODLOG_DFLT(INFO, " %d, %d\n", ++send_cnt, data_len);
|
||||||
@ -1365,7 +1362,7 @@ rx_stress_start(int test_num)
|
|||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
console_printf("Stress L2CAP send\033[0m\n");
|
console_printf("Stress L2CAP send\033[0m\n");
|
||||||
rc = ble_l2cap_create_server(1, STRESS_COC_MTU,
|
rc = ble_l2cap_create_server(TEST_PSM, STRESS_COC_MTU,
|
||||||
rx_stress_10_l2cap_event, NULL);
|
rx_stress_10_l2cap_event, NULL);
|
||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
rx_stress_simple_adv(&rx_stress_adv_sets[10]);
|
rx_stress_simple_adv(&rx_stress_adv_sets[10]);
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "stress.h"
|
#include "stress.h"
|
||||||
|
|
||||||
|
static struct os_callout stress_timer_callout;
|
||||||
|
|
||||||
void
|
void
|
||||||
com_stress_print_report(const struct com_stress_test_ctx *test_ctxs)
|
com_stress_print_report(const struct com_stress_test_ctx *test_ctxs)
|
||||||
{
|
{
|
||||||
@ -119,7 +121,7 @@ stress_fill_mbuf_with_pattern(struct os_mbuf *om, uint16_t len)
|
|||||||
rest = len % STRESS_PAT_LEN;
|
rest = len % STRESS_PAT_LEN;
|
||||||
|
|
||||||
for (i = 0; i < mul; ++i) {
|
for (i = 0; i < mul; ++i) {
|
||||||
rc = os_mbuf_append(om, &test_6_pattern[29], STRESS_PAT_LEN);
|
rc = os_mbuf_append(om, &test_6_pattern[0], STRESS_PAT_LEN);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
os_mbuf_free_chain(om);
|
os_mbuf_free_chain(om);
|
||||||
@ -127,7 +129,7 @@ stress_fill_mbuf_with_pattern(struct os_mbuf *om, uint16_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = os_mbuf_append(om, &test_6_pattern[29], rest);
|
rc = os_mbuf_append(om, &test_6_pattern[0], rest);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
os_mbuf_free_chain(om);
|
os_mbuf_free_chain(om);
|
||||||
@ -176,6 +178,7 @@ void
|
|||||||
stress_start_timer(uint32_t timeout_ms, os_event_fn *ev_cb)
|
stress_start_timer(uint32_t timeout_ms, os_event_fn *ev_cb)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
os_callout_stop(&stress_timer_callout);
|
os_callout_stop(&stress_timer_callout);
|
||||||
|
|
||||||
os_callout_init(&stress_timer_callout, os_eventq_dflt_get(), ev_cb, NULL);
|
os_callout_init(&stress_timer_callout, os_eventq_dflt_get(), ev_cb, NULL);
|
||||||
|
@ -44,8 +44,9 @@ extern "C" {
|
|||||||
#define STRESS_FIND_SRV 1
|
#define STRESS_FIND_SRV 1
|
||||||
#define STRESS_FIND_CHR 2
|
#define STRESS_FIND_CHR 2
|
||||||
#define STRESS_FIND_DSC 3
|
#define STRESS_FIND_DSC 3
|
||||||
|
/* L2CAP PSM */
|
||||||
|
#define TEST_PSM 0x80
|
||||||
|
|
||||||
struct os_callout stress_timer_callout;
|
|
||||||
struct stress_gatt_search_ctx;
|
struct stress_gatt_search_ctx;
|
||||||
typedef void stress_gatt_disc_end_fn(struct stress_gatt_search_ctx *search_ctx);
|
typedef void stress_gatt_disc_end_fn(struct stress_gatt_search_ctx *search_ctx);
|
||||||
|
|
||||||
|
@ -1127,7 +1127,7 @@ tx_stress_10_gap_event(struct ble_gap_event *event, void *arg)
|
|||||||
assert(sdu_rx != NULL);
|
assert(sdu_rx != NULL);
|
||||||
|
|
||||||
tx_stress_ctx->conn_handle = event->connect.conn_handle;
|
tx_stress_ctx->conn_handle = event->connect.conn_handle;
|
||||||
rc = ble_l2cap_connect(event->connect.conn_handle, 1,
|
rc = ble_l2cap_connect(event->connect.conn_handle, TEST_PSM,
|
||||||
STRESS_COC_MTU, sdu_rx,
|
STRESS_COC_MTU, sdu_rx,
|
||||||
tx_stress_10_l2cap_event, NULL);
|
tx_stress_10_l2cap_event, NULL);
|
||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
@ -1301,8 +1301,7 @@ tx_stress_14_subs_cb(uint16_t conn_handle, const struct ble_gatt_error *error,
|
|||||||
/* Enable notifications */
|
/* Enable notifications */
|
||||||
if (*sub == 0) {
|
if (*sub == 0) {
|
||||||
*sub = true;
|
*sub = true;
|
||||||
om = ble_hs_mbuf_from_flat(
|
om = ble_hs_mbuf_from_flat((uint8_t[]) {0x01, 0x00}, 2);
|
||||||
(uint8_t[]) {0x01, 0x00}, 2);
|
|
||||||
|
|
||||||
tx_stress_ctx->begin_us = tx_stress_ctx->end_us;
|
tx_stress_ctx->begin_us = tx_stress_ctx->end_us;
|
||||||
|
|
||||||
@ -1607,7 +1606,8 @@ tx_stress_test_perform(int test_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tx_stress_read_command_cb(void) {
|
tx_stress_read_command_cb(void)
|
||||||
|
{
|
||||||
console_printf("Start testing\n");
|
console_printf("Start testing\n");
|
||||||
os_sem_release(&tx_stress_main_sem);
|
os_sem_release(&tx_stress_main_sem);
|
||||||
}
|
}
|
||||||
|
@ -2691,15 +2691,28 @@ cmd_security_unpair(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
ble_addr_t peer;
|
ble_addr_t peer;
|
||||||
int rc;
|
int rc;
|
||||||
|
int oldest;
|
||||||
|
|
||||||
rc = parse_arg_all(argc - 1, argv + 1);
|
rc = parse_arg_all(argc - 1, argv + 1);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = parse_arg_bool_dflt("oldest", 0, &oldest);
|
||||||
|
if (rc != 0) {
|
||||||
|
console_printf("invalid 'oldest' parameter\n");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldest) {
|
||||||
|
rc = ble_gap_unpair_oldest_peer();
|
||||||
|
console_printf("Unpair oldest status: 0x%02x\n", rc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
rc = parse_dev_addr("peer_", cmd_peer_addr_types, &peer);
|
rc = parse_dev_addr("peer_", cmd_peer_addr_types, &peer);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
console_printf("invalid 'peer_addr' parameter\n");
|
console_printf("invalid peer address\n");
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2714,6 +2727,7 @@ cmd_security_unpair(int argc, char **argv)
|
|||||||
|
|
||||||
#if MYNEWT_VAL(SHELL_CMD_HELP)
|
#if MYNEWT_VAL(SHELL_CMD_HELP)
|
||||||
static const struct shell_param security_unpair_params[] = {
|
static const struct shell_param security_unpair_params[] = {
|
||||||
|
{"oldest", "usage: =[true|false], default: false"},
|
||||||
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
|
{"peer_addr_type", "usage: =[public|random|public_id|random_id], default: public"},
|
||||||
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
|
{"peer_addr", "usage: =[XX:XX:XX:XX:XX:XX]"},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
@ -37,7 +37,7 @@ pkg.deps:
|
|||||||
- "@apache-mynewt-nimble/nimble/host/services/gap"
|
- "@apache-mynewt-nimble/nimble/host/services/gap"
|
||||||
- "@apache-mynewt-nimble/nimble/host/services/gatt"
|
- "@apache-mynewt-nimble/nimble/host/services/gatt"
|
||||||
- "@apache-mynewt-nimble/nimble/host/services/dis"
|
- "@apache-mynewt-nimble/nimble/host/services/dis"
|
||||||
- "@apache-mynewt-nimble/nimble/host/store/ram"
|
- "@apache-mynewt-nimble/nimble/host/store/config"
|
||||||
- "@apache-mynewt-nimble/nimble/transport/ram"
|
- "@apache-mynewt-nimble/nimble/transport/ram"
|
||||||
- "@apache-mynewt-core/hw/drivers/uart"
|
- "@apache-mynewt-core/hw/drivers/uart"
|
||||||
- "@apache-mynewt-core/hw/drivers/rtt"
|
- "@apache-mynewt-core/hw/drivers/rtt"
|
||||||
|
@ -44,16 +44,16 @@ static struct os_event bttester_ev[CMD_QUEUED];
|
|||||||
struct btp_buf {
|
struct btp_buf {
|
||||||
struct os_event *ev;
|
struct os_event *ev;
|
||||||
union {
|
union {
|
||||||
u8_t data[BTP_MTU];
|
uint8_t data[BTP_MTU];
|
||||||
struct btp_hdr hdr;
|
struct btp_hdr hdr;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct btp_buf cmd_buf[CMD_QUEUED];
|
static struct btp_buf cmd_buf[CMD_QUEUED];
|
||||||
|
|
||||||
static void supported_commands(u8_t *data, u16_t len)
|
static void supported_commands(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t buf[1];
|
uint8_t buf[1];
|
||||||
struct core_read_supported_commands_rp *rp = (void *) buf;
|
struct core_read_supported_commands_rp *rp = (void *) buf;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
@ -64,12 +64,12 @@ static void supported_commands(u8_t *data, u16_t len)
|
|||||||
tester_set_bit(buf, CORE_UNREGISTER_SERVICE);
|
tester_set_bit(buf, CORE_UNREGISTER_SERVICE);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS,
|
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_COMMANDS,
|
||||||
BTP_INDEX_NONE, (u8_t *) rp, sizeof(buf));
|
BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void supported_services(u8_t *data, u16_t len)
|
static void supported_services(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t buf[1];
|
uint8_t buf[1];
|
||||||
struct core_read_supported_services_rp *rp = (void *) buf;
|
struct core_read_supported_services_rp *rp = (void *) buf;
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
@ -85,13 +85,13 @@ static void supported_services(u8_t *data, u16_t len)
|
|||||||
#endif /* MYNEWT_VAL(BLE_MESH) */
|
#endif /* MYNEWT_VAL(BLE_MESH) */
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES,
|
tester_send(BTP_SERVICE_ID_CORE, CORE_READ_SUPPORTED_SERVICES,
|
||||||
BTP_INDEX_NONE, (u8_t *) rp, sizeof(buf));
|
BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_service(u8_t *data, u16_t len)
|
static void register_service(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct core_register_service_cmd *cmd = (void *) data;
|
struct core_register_service_cmd *cmd = (void *) data;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
switch (cmd->id) {
|
switch (cmd->id) {
|
||||||
case BTP_SERVICE_ID_GAP:
|
case BTP_SERVICE_ID_GAP:
|
||||||
@ -124,10 +124,10 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unregister_service(u8_t *data, u16_t len)
|
static void unregister_service(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct core_unregister_service_cmd *cmd = (void *) data;
|
struct core_unregister_service_cmd *cmd = (void *) data;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
switch (cmd->id) {
|
switch (cmd->id) {
|
||||||
case BTP_SERVICE_ID_GAP:
|
case BTP_SERVICE_ID_GAP:
|
||||||
@ -155,8 +155,8 @@ static void unregister_service(u8_t *data, u16_t len)
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_core(u8_t opcode, u8_t index, u8_t *data,
|
static void handle_core(uint8_t opcode, uint8_t index, uint8_t *data,
|
||||||
u16_t len)
|
uint16_t len)
|
||||||
{
|
{
|
||||||
if (index != BTP_INDEX_NONE) {
|
if (index != BTP_INDEX_NONE) {
|
||||||
tester_rsp(BTP_SERVICE_ID_CORE, opcode, index,
|
tester_rsp(BTP_SERVICE_ID_CORE, opcode, index,
|
||||||
@ -186,7 +186,7 @@ static void handle_core(u8_t opcode, u8_t index, u8_t *data,
|
|||||||
|
|
||||||
static void cmd_handler(struct os_event *ev)
|
static void cmd_handler(struct os_event *ev)
|
||||||
{
|
{
|
||||||
u16_t len;
|
uint16_t len;
|
||||||
struct btp_buf *cmd;
|
struct btp_buf *cmd;
|
||||||
|
|
||||||
if (!ev || !ev->ev_arg) {
|
if (!ev || !ev->ev_arg) {
|
||||||
@ -241,12 +241,12 @@ static void cmd_handler(struct os_event *ev)
|
|||||||
os_eventq_put(&avail_queue, ev);
|
os_eventq_put(&avail_queue, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t *recv_cb(u8_t *buf, size_t *off)
|
static uint8_t *recv_cb(uint8_t *buf, size_t *off)
|
||||||
{
|
{
|
||||||
struct btp_hdr *cmd = (void *) buf;
|
struct btp_hdr *cmd = (void *) buf;
|
||||||
struct os_event *new_ev;
|
struct os_event *new_ev;
|
||||||
struct btp_buf *new_buf, *old_buf;
|
struct btp_buf *new_buf, *old_buf;
|
||||||
u16_t len;
|
uint16_t len;
|
||||||
|
|
||||||
if (*off < sizeof(*cmd)) {
|
if (*off < sizeof(*cmd)) {
|
||||||
return buf;
|
return buf;
|
||||||
@ -319,7 +319,7 @@ void tester_init(void)
|
|||||||
NULL, 0);
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_send(u8_t service, u8_t opcode, u8_t index, u8_t *data,
|
void tester_send(uint8_t service, uint8_t opcode, uint8_t index, uint8_t *data,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct btp_hdr msg;
|
struct btp_hdr msg;
|
||||||
@ -329,7 +329,7 @@ void tester_send(u8_t service, u8_t opcode, u8_t index, u8_t *data,
|
|||||||
msg.index = index;
|
msg.index = index;
|
||||||
msg.len = len;
|
msg.len = len;
|
||||||
|
|
||||||
bttester_pipe_send((u8_t *)&msg, sizeof(msg));
|
bttester_pipe_send((uint8_t *)&msg, sizeof(msg));
|
||||||
if (data && len) {
|
if (data && len) {
|
||||||
bttester_pipe_send(data, len);
|
bttester_pipe_send(data, len);
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ void tester_send(u8_t service, u8_t opcode, u8_t index, u8_t *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_send_buf(u8_t service, u8_t opcode, u8_t index,
|
void tester_send_buf(uint8_t service, uint8_t opcode, uint8_t index,
|
||||||
struct os_mbuf *data)
|
struct os_mbuf *data)
|
||||||
{
|
{
|
||||||
struct btp_hdr msg;
|
struct btp_hdr msg;
|
||||||
@ -354,13 +354,13 @@ void tester_send_buf(u8_t service, u8_t opcode, u8_t index,
|
|||||||
msg.index = index;
|
msg.index = index;
|
||||||
msg.len = os_mbuf_len(data);
|
msg.len = os_mbuf_len(data);
|
||||||
|
|
||||||
bttester_pipe_send((u8_t *)&msg, sizeof(msg));
|
bttester_pipe_send((uint8_t *)&msg, sizeof(msg));
|
||||||
if (data && msg.len) {
|
if (data && msg.len) {
|
||||||
bttester_pipe_send_buf(data);
|
bttester_pipe_send_buf(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_rsp(u8_t service, u8_t opcode, u8_t index, u8_t status)
|
void tester_rsp(uint8_t service, uint8_t opcode, uint8_t index, uint8_t status)
|
||||||
{
|
{
|
||||||
struct btp_status s;
|
struct btp_status s;
|
||||||
|
|
||||||
@ -370,5 +370,5 @@ void tester_rsp(u8_t service, u8_t opcode, u8_t index, u8_t status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.code = status;
|
s.code = status;
|
||||||
tester_send(service, BTP_STATUS, index, (u8_t *) &s, sizeof(s));
|
tester_send(service, BTP_STATUS, index, (uint8_t *) &s, sizeof(s));
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -27,9 +27,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef u8_t *(*bttester_pipe_recv_cb)(u8_t *buf, size_t *off);
|
typedef uint8_t *(*bttester_pipe_recv_cb)(uint8_t *buf, size_t *off);
|
||||||
void bttester_pipe_register(u8_t *buf, size_t len, bttester_pipe_recv_cb cb);
|
void bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb);
|
||||||
int bttester_pipe_send(const u8_t *data, int len);
|
int bttester_pipe_send(const uint8_t *data, int len);
|
||||||
int bttester_pipe_send_buf(struct os_mbuf *buf);
|
int bttester_pipe_send_buf(struct os_mbuf *buf);
|
||||||
int bttester_pipe_init(void);
|
int bttester_pipe_init(void);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ static struct ble_sm_sc_oob_data oob_data_local;
|
|||||||
static struct ble_sm_sc_oob_data oob_data_remote;
|
static struct ble_sm_sc_oob_data oob_data_remote;
|
||||||
|
|
||||||
static uint16_t current_settings;
|
static uint16_t current_settings;
|
||||||
u8_t own_addr_type;
|
uint8_t own_addr_type;
|
||||||
static ble_addr_t peer_id_addr;
|
static ble_addr_t peer_id_addr;
|
||||||
static ble_addr_t peer_ota_addr;
|
static ble_addr_t peer_ota_addr;
|
||||||
static bool encrypted = false;
|
static bool encrypted = false;
|
||||||
@ -109,9 +109,9 @@ static int gap_conn_find_by_addr(const ble_addr_t *dev_addr,
|
|||||||
|
|
||||||
static int gap_event_cb(struct ble_gap_event *event, void *arg);
|
static int gap_event_cb(struct ble_gap_event *event, void *arg);
|
||||||
|
|
||||||
static void supported_commands(u8_t *data, u16_t len)
|
static void supported_commands(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t cmds[3];
|
uint8_t cmds[3];
|
||||||
struct gap_read_supported_commands_rp *rp = (void *) &cmds;
|
struct gap_read_supported_commands_rp *rp = (void *) &cmds;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -143,13 +143,13 @@ static void supported_commands(u8_t *data, u16_t len)
|
|||||||
tester_set_bit(cmds, GAP_SET_MITM);
|
tester_set_bit(cmds, GAP_SET_MITM);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_SUPPORTED_COMMANDS,
|
||||||
CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
|
CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void controller_index_list(u8_t *data, u16_t len)
|
static void controller_index_list(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct gap_read_controller_index_list_rp *rp;
|
struct gap_read_controller_index_list_rp *rp;
|
||||||
u8_t buf[sizeof(*rp) + 1];
|
uint8_t buf[sizeof(*rp) + 1];
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ static void controller_index_list(u8_t *data, u16_t len)
|
|||||||
rp->index[0] = CONTROLLER_INDEX;
|
rp->index[0] = CONTROLLER_INDEX;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INDEX_LIST,
|
||||||
BTP_INDEX_NONE, (u8_t *) rp, sizeof(buf));
|
BTP_INDEX_NONE, (uint8_t *) rp, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_pub_addr_unassigned(void)
|
static int check_pub_addr_unassigned(void)
|
||||||
@ -174,10 +174,10 @@ static int check_pub_addr_unassigned(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void controller_info(u8_t *data, u16_t len)
|
static void controller_info(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct gap_read_controller_info_rp rp;
|
struct gap_read_controller_info_rp rp;
|
||||||
u32_t supported_settings = 0;
|
uint32_t supported_settings = 0;
|
||||||
ble_addr_t addr;
|
ble_addr_t addr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ static void controller_info(u8_t *data, u16_t len)
|
|||||||
memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME));
|
memcpy(rp.name, CONTROLLER_NAME, sizeof(CONTROLLER_NAME));
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_READ_CONTROLLER_INFO,
|
||||||
CONTROLLER_INDEX, (u8_t *) &rp, sizeof(rp));
|
CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ble_gap_adv_params adv_params = {
|
static struct ble_gap_adv_params adv_params = {
|
||||||
@ -248,7 +248,7 @@ static struct ble_gap_adv_params adv_params = {
|
|||||||
.disc_mode = BLE_GAP_DISC_MODE_NON,
|
.disc_mode = BLE_GAP_DISC_MODE_NON,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_connectable(u8_t *data, u16_t len)
|
static void set_connectable(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_set_connectable_cmd *cmd = (void *) data;
|
const struct gap_set_connectable_cmd *cmd = (void *) data;
|
||||||
struct gap_set_connectable_rp rp;
|
struct gap_set_connectable_rp rp;
|
||||||
@ -266,12 +266,12 @@ static void set_connectable(u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_CONNECTABLE, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP;
|
static uint8_t ad_flags = BLE_HS_ADV_F_BREDR_UNSUP;
|
||||||
|
|
||||||
static void set_discoverable(u8_t *data, u16_t len)
|
static void set_discoverable(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_set_discoverable_cmd *cmd = (void *) data;
|
const struct gap_set_discoverable_cmd *cmd = (void *) data;
|
||||||
struct gap_set_discoverable_rp rp;
|
struct gap_set_discoverable_rp rp;
|
||||||
@ -305,10 +305,10 @@ static void set_discoverable(u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_DISCOVERABLE, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_bondable(const u8_t *data, u16_t len)
|
static void set_bondable(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_set_bondable_cmd *cmd = (void *) data;
|
const struct gap_set_bondable_cmd *cmd = (void *) data;
|
||||||
struct gap_set_bondable_rp rp;
|
struct gap_set_bondable_rp rp;
|
||||||
@ -325,7 +325,7 @@ static void set_bondable(const u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_SET_BONDABLE, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bt_data ad[10] = {
|
static struct bt_data ad[10] = {
|
||||||
@ -334,7 +334,7 @@ static struct bt_data ad[10] = {
|
|||||||
static struct bt_data sd[10];
|
static struct bt_data sd[10];
|
||||||
|
|
||||||
static int set_ad(const struct bt_data *ad, size_t ad_len,
|
static int set_ad(const struct bt_data *ad, size_t ad_len,
|
||||||
u8_t *buf, u8_t *buf_len)
|
uint8_t *buf, uint8_t *buf_len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -350,14 +350,14 @@ static int set_ad(const struct bt_data *ad, size_t ad_len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_advertising(const u8_t *data, u16_t len)
|
static void start_advertising(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_start_advertising_cmd *cmd = (void *) data;
|
const struct gap_start_advertising_cmd *cmd = (void *) data;
|
||||||
struct gap_start_advertising_rp rp;
|
struct gap_start_advertising_rp rp;
|
||||||
int32_t duration_ms = BLE_HS_FOREVER;
|
int32_t duration_ms = BLE_HS_FOREVER;
|
||||||
uint8_t buf[BLE_HS_ADV_MAX_SZ];
|
uint8_t buf[BLE_HS_ADV_MAX_SZ];
|
||||||
uint8_t buf_len = 0;
|
uint8_t buf_len = 0;
|
||||||
u8_t adv_len, sd_len;
|
uint8_t adv_len, sd_len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@ -429,14 +429,14 @@ static void start_advertising(const u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
return;
|
return;
|
||||||
fail:
|
fail:
|
||||||
tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
|
tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_ADVERTISING, CONTROLLER_INDEX,
|
||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_advertising(const u8_t *data, u16_t len)
|
static void stop_advertising(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct gap_stop_advertising_rp rp;
|
struct gap_stop_advertising_rp rp;
|
||||||
|
|
||||||
@ -452,12 +452,12 @@ static void stop_advertising(const u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_STOP_ADVERTISING, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t get_ad_flags(const u8_t *data, u8_t data_len)
|
static uint8_t get_ad_flags(const uint8_t *data, uint8_t data_len)
|
||||||
{
|
{
|
||||||
u8_t len, i;
|
uint8_t len, i;
|
||||||
|
|
||||||
/* Parse advertisement to get flags */
|
/* Parse advertisement to get flags */
|
||||||
for (i = 0; i < data_len; i += len - 1) {
|
for (i = 0; i < data_len; i += len - 1) {
|
||||||
@ -482,11 +482,11 @@ static u8_t get_ad_flags(const u8_t *data, u8_t data_len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t discovery_flags;
|
static uint8_t discovery_flags;
|
||||||
static struct os_mbuf *adv_buf;
|
static struct os_mbuf *adv_buf;
|
||||||
|
|
||||||
static void store_adv(const ble_addr_t *addr, s8_t rssi,
|
static void store_adv(const ble_addr_t *addr, int8_t rssi,
|
||||||
const u8_t *data, u8_t len)
|
const uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
struct gap_device_found_ev *ev;
|
struct gap_device_found_ev *ev;
|
||||||
|
|
||||||
@ -503,8 +503,8 @@ static void store_adv(const ble_addr_t *addr, s8_t rssi,
|
|||||||
memcpy(net_buf_simple_add(adv_buf, len), data, len);
|
memcpy(net_buf_simple_add(adv_buf, len), data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_found(ble_addr_t *addr, s8_t rssi, u8_t evtype,
|
static void device_found(ble_addr_t *addr, int8_t rssi, uint8_t evtype,
|
||||||
const u8_t *data, u8_t len)
|
const uint8_t *data, uint8_t len)
|
||||||
{
|
{
|
||||||
struct gap_device_found_ev *ev;
|
struct gap_device_found_ev *ev;
|
||||||
ble_addr_t a;
|
ble_addr_t a;
|
||||||
@ -512,7 +512,7 @@ static void device_found(ble_addr_t *addr, s8_t rssi, u8_t evtype,
|
|||||||
/* if General/Limited Discovery - parse Advertising data to get flags */
|
/* if General/Limited Discovery - parse Advertising data to get flags */
|
||||||
if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) &&
|
if (!(discovery_flags & GAP_DISCOVERY_FLAG_LE_OBSERVE) &&
|
||||||
(evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) {
|
(evtype != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP)) {
|
||||||
u8_t flags = get_ad_flags(data, len);
|
uint8_t flags = get_ad_flags(data, len);
|
||||||
|
|
||||||
/* ignore non-discoverable devices */
|
/* ignore non-discoverable devices */
|
||||||
if (!(flags & BLE_AD_DISCOV_MASK)) {
|
if (!(flags & BLE_AD_DISCOV_MASK)) {
|
||||||
@ -593,11 +593,11 @@ static int discovery_cb(struct ble_gap_event *event, void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_discovery(const u8_t *data, u16_t len)
|
static void start_discovery(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_start_discovery_cmd *cmd = (void *) data;
|
const struct gap_start_discovery_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_disc_params params = {0};
|
struct ble_gap_disc_params params = {0};
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -626,9 +626,9 @@ reply:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_discovery(const u8_t *data, u16_t len)
|
static void stop_discovery(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -680,13 +680,13 @@ static void device_connected_ev_send(struct os_event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &connected_ev,
|
CONTROLLER_INDEX, (uint8_t *) &connected_ev,
|
||||||
sizeof(connected_ev));
|
sizeof(connected_ev));
|
||||||
|
|
||||||
periph_privacy(desc);
|
periph_privacy(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_connected(u16_t conn_handle, int status)
|
static void le_connected(uint16_t conn_handle, int status)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
ble_addr_t *addr;
|
ble_addr_t *addr;
|
||||||
@ -720,7 +720,7 @@ static void le_connected(u16_t conn_handle, int status)
|
|||||||
CONNECTED_EV_DELAY_MS(desc.conn_itvl)));
|
CONNECTED_EV_DELAY_MS(desc.conn_itvl)));
|
||||||
#else
|
#else
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_CONNECTED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &connected_ev,
|
CONTROLLER_INDEX, (uint8_t *) &connected_ev,
|
||||||
sizeof(connected_ev));
|
sizeof(connected_ev));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -763,10 +763,10 @@ static void le_disconnected(struct ble_gap_conn_desc *conn, int reason)
|
|||||||
ev.address_type = addr->type;
|
ev.address_type = addr->type;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_DEVICE_DISCONNECTED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_passkey_oob(u16_t conn_handle)
|
static void auth_passkey_oob(uint16_t conn_handle)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct ble_sm_io pk;
|
struct ble_sm_io pk;
|
||||||
@ -786,7 +786,7 @@ static void auth_passkey_oob(u16_t conn_handle)
|
|||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_passkey_display(u16_t conn_handle, unsigned int passkey)
|
static void auth_passkey_display(uint16_t conn_handle, unsigned int passkey)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct gap_passkey_display_ev ev;
|
struct gap_passkey_display_ev ev;
|
||||||
@ -817,10 +817,10 @@ static void auth_passkey_display(u16_t conn_handle, unsigned int passkey)
|
|||||||
ev.passkey = sys_cpu_to_le32(pk.passkey);
|
ev.passkey = sys_cpu_to_le32(pk.passkey);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_DISPLAY,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_passkey_entry(u16_t conn_handle)
|
static void auth_passkey_entry(uint16_t conn_handle)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct gap_passkey_entry_req_ev ev;
|
struct gap_passkey_entry_req_ev ev;
|
||||||
@ -840,10 +840,10 @@ static void auth_passkey_entry(u16_t conn_handle)
|
|||||||
ev.address_type = addr->type;
|
ev.address_type = addr->type;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_ENTRY_REQ,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_passkey_numcmp(u16_t conn_handle, unsigned int passkey)
|
static void auth_passkey_numcmp(uint16_t conn_handle, unsigned int passkey)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct gap_passkey_confirm_req_ev ev;
|
struct gap_passkey_confirm_req_ev ev;
|
||||||
@ -864,10 +864,10 @@ static void auth_passkey_numcmp(u16_t conn_handle, unsigned int passkey)
|
|||||||
ev.passkey = sys_cpu_to_le32(passkey);
|
ev.passkey = sys_cpu_to_le32(passkey);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_PASSKEY_CONFIRM_REQ,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void auth_passkey_oob_sc(u16_t conn_handle)
|
static void auth_passkey_oob_sc(uint16_t conn_handle)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct ble_sm_io pk;
|
struct ble_sm_io pk;
|
||||||
@ -889,7 +889,7 @@ static void auth_passkey_oob_sc(u16_t conn_handle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_passkey_action(u16_t conn_handle,
|
static void le_passkey_action(uint16_t conn_handle,
|
||||||
struct ble_gap_passkey_params *params)
|
struct ble_gap_passkey_params *params)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -917,7 +917,7 @@ static void le_passkey_action(u16_t conn_handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_identity_resolved(u16_t conn_handle)
|
static void le_identity_resolved(uint16_t conn_handle)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct gap_identity_resolved_ev ev;
|
struct gap_identity_resolved_ev ev;
|
||||||
@ -941,7 +941,7 @@ static void le_identity_resolved(u16_t conn_handle)
|
|||||||
sizeof(ev.identity_address));
|
sizeof(ev.identity_address));
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_IDENTITY_RESOLVED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_conn_param_update(struct ble_gap_conn_desc *desc)
|
static void le_conn_param_update(struct ble_gap_conn_desc *desc)
|
||||||
@ -958,7 +958,7 @@ static void le_conn_param_update(struct ble_gap_conn_desc *desc)
|
|||||||
ev.supervision_timeout = desc->supervision_timeout;
|
ev.supervision_timeout = desc->supervision_timeout;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void le_encryption_changed(struct ble_gap_conn_desc *desc)
|
static void le_encryption_changed(struct ble_gap_conn_desc *desc)
|
||||||
@ -986,7 +986,7 @@ static void le_encryption_changed(struct ble_gap_conn_desc *desc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_SEC_LEVEL_CHANGED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_bytes(const uint8_t *bytes, int len)
|
static void print_bytes(const uint8_t *bytes, int len)
|
||||||
@ -1055,7 +1055,7 @@ static void adv_complete(void)
|
|||||||
ev.current_settings = sys_cpu_to_le32(current_settings);
|
ev.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_EV_NEW_SETTINGS, CONTROLLER_INDEX,
|
||||||
(u8_t *) &ev, sizeof(ev));
|
(uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||||
@ -1197,9 +1197,9 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connect(const u8_t *data, u16_t len)
|
static void connect(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1211,10 +1211,10 @@ static void connect(const u8_t *data, u16_t len)
|
|||||||
tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status);
|
tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONNECT, CONTROLLER_INDEX, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnect(const u8_t *data, u16_t len)
|
static void disconnect(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1236,10 +1236,10 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_io_cap(const u8_t *data, u16_t len)
|
static void set_io_cap(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_set_io_cap_cmd *cmd = (void *) data;
|
const struct gap_set_io_cap_cmd *cmd = (void *) data;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1276,10 +1276,10 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pair(const u8_t *data, u16_t len)
|
static void pair(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1301,9 +1301,9 @@ rsp:
|
|||||||
tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status);
|
tester_rsp(BTP_SERVICE_ID_GAP, GAP_PAIR, CONTROLLER_INDEX, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unpair(const u8_t *data, u16_t len)
|
static void unpair(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1313,12 +1313,12 @@ static void unpair(const u8_t *data, u16_t len)
|
|||||||
tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status);
|
tester_rsp(BTP_SERVICE_ID_GAP, GAP_UNPAIR, CONTROLLER_INDEX, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void passkey_entry(const u8_t *data, u16_t len)
|
static void passkey_entry(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_passkey_entry_cmd *cmd = (void *) data;
|
const struct gap_passkey_entry_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct ble_sm_io pk;
|
struct ble_sm_io pk;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1345,12 +1345,12 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void passkey_confirm(const u8_t *data, u16_t len)
|
static void passkey_confirm(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_passkey_confirm_cmd *cmd = (void *) data;
|
const struct gap_passkey_confirm_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct ble_sm_io pk;
|
struct ble_sm_io pk;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1378,7 +1378,7 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_direct_adv(const u8_t *data, u16_t len)
|
static void start_direct_adv(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_start_direct_adv_cmd *cmd = (void *) data;
|
const struct gap_start_direct_adv_cmd *cmd = (void *) data;
|
||||||
struct gap_start_advertising_rp rp;
|
struct gap_start_advertising_rp rp;
|
||||||
@ -1403,7 +1403,7 @@ static void start_direct_adv(const u8_t *data, u16_t len)
|
|||||||
rp.current_settings = sys_cpu_to_le32(current_settings);
|
rp.current_settings = sys_cpu_to_le32(current_settings);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
return;
|
return;
|
||||||
fail:
|
fail:
|
||||||
tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX,
|
tester_rsp(BTP_SERVICE_ID_GAP, GAP_START_DIRECT_ADV, CONTROLLER_INDEX,
|
||||||
@ -1416,7 +1416,7 @@ static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg)
|
|||||||
conn_handle, status);
|
conn_handle, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conn_param_update_slave(u16_t conn_handle,
|
static int conn_param_update_slave(uint16_t conn_handle,
|
||||||
const struct gap_conn_param_update_cmd *cmd)
|
const struct gap_conn_param_update_cmd *cmd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -1436,7 +1436,7 @@ static int conn_param_update_slave(u16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conn_param_update_master(u16_t conn_handle,
|
static int conn_param_update_master(uint16_t conn_handle,
|
||||||
const struct gap_conn_param_update_cmd *cmd)
|
const struct gap_conn_param_update_cmd *cmd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@ -1489,7 +1489,7 @@ rsp:
|
|||||||
SYS_LOG_ERR("Conn param update fail; rc=%d", rc);
|
SYS_LOG_ERR("Conn param update fail; rc=%d", rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_param_update_async(const u8_t *data, u16_t len)
|
static void conn_param_update_async(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_conn_param_update_cmd *cmd = (void *) data;
|
const struct gap_conn_param_update_cmd *cmd = (void *) data;
|
||||||
update_params = *cmd;
|
update_params = *cmd;
|
||||||
@ -1500,7 +1500,7 @@ static void conn_param_update_async(const u8_t *data, u16_t len)
|
|||||||
BTP_STATUS_SUCCESS);
|
BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oob_legacy_set_data(const u8_t *data, u16_t len)
|
static void oob_legacy_set_data(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data;
|
const struct gap_oob_legacy_set_data_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -1511,7 +1511,7 @@ static void oob_legacy_set_data(const u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oob_sc_get_local_data(const u8_t *data, u16_t len)
|
static void oob_sc_get_local_data(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct gap_oob_sc_get_local_data_rp rp;
|
struct gap_oob_sc_get_local_data_rp rp;
|
||||||
|
|
||||||
@ -1519,10 +1519,10 @@ static void oob_sc_get_local_data(const u8_t *data, u16_t len)
|
|||||||
memcpy(rp.c, oob_data_local.c, 16);
|
memcpy(rp.c, oob_data_local.c, 16);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA,
|
tester_send(BTP_SERVICE_ID_GAP, GAP_OOB_SC_GET_LOCAL_DATA,
|
||||||
CONTROLLER_INDEX, (u8_t *) &rp, sizeof(rp));
|
CONTROLLER_INDEX, (uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void oob_sc_set_remote_data(const u8_t *data, u16_t len)
|
static void oob_sc_set_remote_data(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data;
|
const struct gap_oob_sc_set_remote_data_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -1534,7 +1534,7 @@ static void oob_sc_set_remote_data(const u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mitm(const u8_t *data, u16_t len)
|
static void set_mitm(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gap_set_mitm_cmd *cmd = (void *) data;
|
const struct gap_set_mitm_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -1544,8 +1544,8 @@ static void set_mitm(const u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_handle_gap(u8_t opcode, u8_t index, u8_t *data,
|
void tester_handle_gap(uint8_t opcode, uint8_t index, uint8_t *data,
|
||||||
u16_t len)
|
uint16_t len)
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case GAP_READ_SUPPORTED_COMMANDS:
|
case GAP_READ_SUPPORTED_COMMANDS:
|
||||||
@ -1664,7 +1664,7 @@ static void tester_init_gap_cb(int err)
|
|||||||
BTP_STATUS_SUCCESS);
|
BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_init_gap(void)
|
uint8_t tester_init_gap(void)
|
||||||
{
|
{
|
||||||
#if MYNEWT_VAL(BLE_SM_SC)
|
#if MYNEWT_VAL(BLE_SM_SC)
|
||||||
int rc;
|
int rc;
|
||||||
@ -1682,7 +1682,7 @@ u8_t tester_init_gap(void)
|
|||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_unregister_gap(void)
|
uint8_t tester_unregister_gap(void)
|
||||||
{
|
{
|
||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,8 @@
|
|||||||
static uint8_t gatt_svr_pts_static_long_val[300];
|
static uint8_t gatt_svr_pts_static_long_val[300];
|
||||||
static uint8_t gatt_svr_pts_static_val[30];
|
static uint8_t gatt_svr_pts_static_val[30];
|
||||||
static uint8_t gatt_svr_pts_static_short_val;
|
static uint8_t gatt_svr_pts_static_short_val;
|
||||||
static u8_t notify_state;
|
static uint8_t notify_state;
|
||||||
static u8_t indicate_state;
|
static uint8_t indicate_state;
|
||||||
static uint16_t myconn_handle;
|
static uint16_t myconn_handle;
|
||||||
static struct os_callout notify_tx_timer;
|
static struct os_callout notify_tx_timer;
|
||||||
uint16_t notify_handle;
|
uint16_t notify_handle;
|
||||||
@ -253,7 +253,7 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void attr_value_changed_ev(u16_t handle, struct os_mbuf *data)
|
static void attr_value_changed_ev(uint16_t handle, struct os_mbuf *data)
|
||||||
{
|
{
|
||||||
struct gatt_attr_value_changed_ev *ev;
|
struct gatt_attr_value_changed_ev *ev;
|
||||||
struct os_mbuf *buf = os_msys_get(0, 0);
|
struct os_mbuf *buf = os_msys_get(0, 0);
|
||||||
@ -569,7 +569,7 @@ gatt_svr_rel_write_test(uint16_t conn_handle, uint16_t attr_handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_server(u8_t *data, u16_t len)
|
static void start_server(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct gatt_start_server_rp rp;
|
struct gatt_start_server_rp rp;
|
||||||
|
|
||||||
@ -583,14 +583,14 @@ static void start_server(u8_t *data, u16_t len)
|
|||||||
rp.db_attr_cnt = 0;
|
rp.db_attr_cnt = 0;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GATT, GATT_START_SERVER, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_GATT, GATT_START_SERVER, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) &rp, sizeof(rp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert UUID from BTP command to bt_uuid */
|
/* Convert UUID from BTP command to bt_uuid */
|
||||||
static u8_t btp2bt_uuid(const u8_t *uuid, u8_t len,
|
static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len,
|
||||||
ble_uuid_any_t *bt_uuid)
|
ble_uuid_any_t *bt_uuid)
|
||||||
{
|
{
|
||||||
u16_t le16;
|
uint16_t le16;
|
||||||
|
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 0x02: /* UUID 16 */
|
case 0x02: /* UUID 16 */
|
||||||
@ -614,8 +614,8 @@ static u8_t btp2bt_uuid(const u8_t *uuid, u8_t len,
|
|||||||
* It is not intended to be used by client and server at the same time.
|
* It is not intended to be used by client and server at the same time.
|
||||||
*/
|
*/
|
||||||
static struct {
|
static struct {
|
||||||
u16_t len;
|
uint16_t len;
|
||||||
u8_t buf[MAX_BUFFER_SIZE];
|
uint8_t buf[MAX_BUFFER_SIZE];
|
||||||
} gatt_buf;
|
} gatt_buf;
|
||||||
|
|
||||||
static void *gatt_buf_add(const void *data, size_t len)
|
static void *gatt_buf_add(const void *data, size_t len)
|
||||||
@ -665,7 +665,7 @@ static int read_cb(uint16_t conn_handle,
|
|||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct gatt_read_rp *rp = (void *) gatt_buf.buf;
|
struct gatt_read_rp *rp = (void *) gatt_buf.buf;
|
||||||
u8_t btp_opcode = (uint8_t) (int) arg;
|
uint8_t btp_opcode = (uint8_t) (int) arg;
|
||||||
|
|
||||||
SYS_LOG_DBG("status=%d", error->status);
|
SYS_LOG_DBG("status=%d", error->status);
|
||||||
|
|
||||||
@ -692,7 +692,7 @@ static int read_cb(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read(u8_t *data, u16_t len)
|
static void read(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_read_cmd *cmd = (void *) data;
|
const struct gatt_read_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -731,7 +731,7 @@ static int read_long_cb(uint16_t conn_handle,
|
|||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
struct gatt_read_rp *rp = (void *) gatt_buf.buf;
|
struct gatt_read_rp *rp = (void *) gatt_buf.buf;
|
||||||
u8_t btp_opcode = (uint8_t) (int) arg;
|
uint8_t btp_opcode = (uint8_t) (int) arg;
|
||||||
|
|
||||||
SYS_LOG_DBG("status=%d", error->status);
|
SYS_LOG_DBG("status=%d", error->status);
|
||||||
|
|
||||||
@ -762,7 +762,7 @@ static int read_long_cb(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_long(u8_t *data, u16_t len)
|
static void read_long(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_read_long_cmd *cmd = (void *) data;
|
const struct gatt_read_long_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -797,10 +797,10 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_multiple(u8_t *data, u16_t len)
|
static void read_multiple(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_read_multiple_cmd *cmd = (void *) data;
|
const struct gatt_read_multiple_cmd *cmd = (void *) data;
|
||||||
u16_t handles[cmd->handles_count];
|
uint16_t handles[cmd->handles_count];
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
|
||||||
@ -836,11 +836,11 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_without_rsp(u8_t *data, u16_t len, u8_t op, bool sign)
|
static void write_without_rsp(uint8_t *data, uint16_t len, uint8_t op, bool sign)
|
||||||
{
|
{
|
||||||
const struct gatt_write_without_rsp_cmd *cmd = (void *) data;
|
const struct gatt_write_without_rsp_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -866,7 +866,7 @@ static int write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error,
|
|||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
uint8_t err = (uint8_t) error->status;
|
uint8_t err = (uint8_t) error->status;
|
||||||
u8_t btp_opcode = (uint8_t) (int) arg;
|
uint8_t btp_opcode = (uint8_t) (int) arg;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -875,7 +875,7 @@ static int write_rsp(uint16_t conn_handle, const struct ble_gatt_error *error,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write(u8_t *data, u16_t len)
|
static void write(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_write_cmd *cmd = (void *) data;
|
const struct gatt_write_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -901,7 +901,7 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_long(u8_t *data, u16_t len)
|
static void write_long(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_write_long_cmd *cmd = (void *) data;
|
const struct gatt_write_long_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -952,7 +952,7 @@ static int reliable_write_rsp(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reliable_write(u8_t *data, u16_t len)
|
static void reliable_write(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_reliable_write_cmd *cmd = (void *) data;
|
const struct gatt_reliable_write_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -994,12 +994,12 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct bt_gatt_subscribe_params {
|
static struct bt_gatt_subscribe_params {
|
||||||
u16_t ccc_handle;
|
uint16_t ccc_handle;
|
||||||
u16_t value;
|
uint16_t value;
|
||||||
u16_t value_handle;
|
uint16_t value_handle;
|
||||||
} subscribe_params;
|
} subscribe_params;
|
||||||
|
|
||||||
static void read_uuid(u8_t *data, u16_t len)
|
static void read_uuid(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_read_uuid_cmd *cmd = (void *) data;
|
const struct gatt_read_uuid_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1046,8 +1046,8 @@ static int disc_prim_uuid_cb(uint16_t conn_handle,
|
|||||||
struct gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf;
|
struct gatt_disc_prim_uuid_rp *rp = (void *) gatt_buf.buf;
|
||||||
struct gatt_service *service;
|
struct gatt_service *service;
|
||||||
const ble_uuid_any_t *uuid;
|
const ble_uuid_any_t *uuid;
|
||||||
u8_t uuid_length;
|
uint8_t uuid_length;
|
||||||
u8_t opcode = (u8_t) (int) arg;
|
uint8_t opcode = (uint8_t) (int) arg;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1081,7 +1081,7 @@ static int disc_prim_uuid_cb(uint16_t conn_handle,
|
|||||||
service->uuid_length = uuid_length;
|
service->uuid_length = uuid_length;
|
||||||
|
|
||||||
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
||||||
u16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
||||||
memcpy(service->uuid, &u16, uuid_length);
|
memcpy(service->uuid, &u16, uuid_length);
|
||||||
} else {
|
} else {
|
||||||
memcpy(service->uuid, BLE_UUID128(uuid)->value,
|
memcpy(service->uuid, BLE_UUID128(uuid)->value,
|
||||||
@ -1102,7 +1102,7 @@ static int disc_all_desc_cb(uint16_t conn_handle,
|
|||||||
struct gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf;
|
struct gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf;
|
||||||
struct gatt_descriptor *dsc;
|
struct gatt_descriptor *dsc;
|
||||||
const ble_uuid_any_t *uuid;
|
const ble_uuid_any_t *uuid;
|
||||||
u8_t uuid_length;
|
uint8_t uuid_length;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1135,7 +1135,7 @@ static int disc_all_desc_cb(uint16_t conn_handle,
|
|||||||
dsc->uuid_length = uuid_length;
|
dsc->uuid_length = uuid_length;
|
||||||
|
|
||||||
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
||||||
u16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
||||||
memcpy(dsc->uuid, &u16, uuid_length);
|
memcpy(dsc->uuid, &u16, uuid_length);
|
||||||
} else {
|
} else {
|
||||||
memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length);
|
memcpy(dsc->uuid, BLE_UUID128(uuid)->value, uuid_length);
|
||||||
@ -1146,7 +1146,7 @@ static int disc_all_desc_cb(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disc_all_prim_svcs(u8_t *data, u16_t len)
|
static void disc_all_prim_svcs(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
int rc;
|
int rc;
|
||||||
@ -1175,7 +1175,7 @@ fail:
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disc_all_desc(u8_t *data, u16_t len)
|
static void disc_all_desc(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_disc_all_desc_cmd *cmd = (void *) data;
|
const struct gatt_disc_all_desc_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1221,7 +1221,7 @@ static int find_included_cb(uint16_t conn_handle,
|
|||||||
struct gatt_included *included;
|
struct gatt_included *included;
|
||||||
const ble_uuid_any_t *uuid;
|
const ble_uuid_any_t *uuid;
|
||||||
int service_handle = (int) arg;
|
int service_handle = (int) arg;
|
||||||
u8_t uuid_length;
|
uint8_t uuid_length;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1259,7 +1259,7 @@ static int find_included_cb(uint16_t conn_handle,
|
|||||||
included->service.uuid_length = uuid_length;
|
included->service.uuid_length = uuid_length;
|
||||||
|
|
||||||
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
||||||
u16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
||||||
memcpy(included->service.uuid, &u16, uuid_length);
|
memcpy(included->service.uuid, &u16, uuid_length);
|
||||||
} else {
|
} else {
|
||||||
memcpy(included->service.uuid, BLE_UUID128(uuid)->value,
|
memcpy(included->service.uuid, BLE_UUID128(uuid)->value,
|
||||||
@ -1278,8 +1278,8 @@ static int disc_chrc_cb(uint16_t conn_handle,
|
|||||||
struct gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf;
|
struct gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf;
|
||||||
struct gatt_characteristic *chrc;
|
struct gatt_characteristic *chrc;
|
||||||
const ble_uuid_any_t *uuid;
|
const ble_uuid_any_t *uuid;
|
||||||
u8_t btp_opcode = (uint8_t) (int) arg;
|
uint8_t btp_opcode = (uint8_t) (int) arg;
|
||||||
u8_t uuid_length;
|
uint8_t uuid_length;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1314,7 +1314,7 @@ static int disc_chrc_cb(uint16_t conn_handle,
|
|||||||
chrc->uuid_length = uuid_length;
|
chrc->uuid_length = uuid_length;
|
||||||
|
|
||||||
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
if (uuid->u.type == BLE_UUID_TYPE_16) {
|
||||||
u16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
uint16_t u16 = sys_cpu_to_le16(BLE_UUID16(uuid)->value);
|
||||||
memcpy(chrc->uuid, &u16, uuid_length);
|
memcpy(chrc->uuid, &u16, uuid_length);
|
||||||
} else {
|
} else {
|
||||||
memcpy(chrc->uuid, BLE_UUID128(uuid)->value,
|
memcpy(chrc->uuid, BLE_UUID128(uuid)->value,
|
||||||
@ -1326,7 +1326,7 @@ static int disc_chrc_cb(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disc_chrc_uuid(u8_t *data, u16_t len)
|
static void disc_chrc_uuid(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data;
|
const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1366,7 +1366,7 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disc_prim_uuid(u8_t *data, u16_t len)
|
static void disc_prim_uuid(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data;
|
const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1402,7 +1402,7 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disc_all_chrc(u8_t *data, u16_t len)
|
static void disc_all_chrc(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_disc_all_chrc_cmd *cmd = (void *) data;
|
const struct gatt_disc_all_chrc_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1439,7 +1439,7 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_included(u8_t *data, u16_t len)
|
static void find_included(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_find_included_cmd *cmd = (void *) data;
|
const struct gatt_find_included_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1495,7 +1495,7 @@ static int exchange_func(uint16_t conn_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exchange_mtu(u8_t *data, u16_t len)
|
static void exchange_mtu(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
int rc;
|
int rc;
|
||||||
@ -1517,10 +1517,10 @@ fail:
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
CONTROLLER_INDEX, BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enable_subscription(u16_t conn_handle, u16_t ccc_handle,
|
static int enable_subscription(uint16_t conn_handle, uint16_t ccc_handle,
|
||||||
u16_t value)
|
uint16_t value)
|
||||||
{
|
{
|
||||||
u8_t op;
|
uint8_t op;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1538,9 +1538,9 @@ static int enable_subscription(u16_t conn_handle, u16_t ccc_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int disable_subscription(u16_t conn_handle, u16_t ccc_handle)
|
static int disable_subscription(uint16_t conn_handle, uint16_t ccc_handle)
|
||||||
{
|
{
|
||||||
u16_t value = 0x00;
|
uint16_t value = 0x00;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -1559,12 +1559,12 @@ static int disable_subscription(u16_t conn_handle, u16_t ccc_handle)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_subscription(u8_t *data, u16_t len, u8_t op)
|
static void config_subscription(uint8_t *data, uint16_t len, uint8_t op)
|
||||||
{
|
{
|
||||||
const struct gatt_cfg_notify_cmd *cmd = (void *) data;
|
const struct gatt_cfg_notify_cmd *cmd = (void *) data;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
u16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle);
|
uint16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle);
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1577,7 +1577,7 @@ static void config_subscription(u8_t *data, u16_t len, u8_t op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->enable) {
|
if (cmd->enable) {
|
||||||
u16_t value;
|
uint16_t value;
|
||||||
|
|
||||||
if (op == GATT_CFG_NOTIFY) {
|
if (op == GATT_CFG_NOTIFY) {
|
||||||
value = 0x0001;
|
value = 0x0001;
|
||||||
@ -1625,10 +1625,10 @@ static int flags_hs2btp_map[] = {
|
|||||||
BTP_PERM_F_WRITE_AUTHOR,
|
BTP_PERM_F_WRITE_AUTHOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static u8_t flags_hs2btp(u8_t flags)
|
static uint8_t flags_hs2btp(uint8_t flags)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
if (flags & BIT(i)) {
|
if (flags & BIT(i)) {
|
||||||
@ -1639,17 +1639,17 @@ static u8_t flags_hs2btp(u8_t flags)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_attrs(u8_t *data, u16_t len)
|
static void get_attrs(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_get_attributes_cmd *cmd = (void *) data;
|
const struct gatt_get_attributes_cmd *cmd = (void *) data;
|
||||||
struct gatt_get_attributes_rp *rp;
|
struct gatt_get_attributes_rp *rp;
|
||||||
struct gatt_attr *gatt_attr;
|
struct gatt_attr *gatt_attr;
|
||||||
struct os_mbuf *buf = os_msys_get(0, 0);
|
struct os_mbuf *buf = os_msys_get(0, 0);
|
||||||
u16_t start_handle, end_handle;
|
uint16_t start_handle, end_handle;
|
||||||
struct ble_att_svr_entry *entry = NULL;
|
struct ble_att_svr_entry *entry = NULL;
|
||||||
ble_uuid_any_t uuid;
|
ble_uuid_any_t uuid;
|
||||||
ble_uuid_t *uuid_ptr = NULL;
|
ble_uuid_t *uuid_ptr = NULL;
|
||||||
u8_t count = 0;
|
uint8_t count = 0;
|
||||||
char str[BLE_UUID_STR_LEN];
|
char str[BLE_UUID_STR_LEN];
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1718,13 +1718,13 @@ free:
|
|||||||
os_mbuf_free_chain(buf);
|
os_mbuf_free_chain(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_attr_val(u8_t *data, u16_t len)
|
static void get_attr_val(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_get_attribute_value_cmd *cmd = (void *) data;
|
const struct gatt_get_attribute_value_cmd *cmd = (void *) data;
|
||||||
struct gatt_get_attribute_value_rp *rp;
|
struct gatt_get_attribute_value_rp *rp;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
struct os_mbuf *buf = os_msys_get(0, 0);
|
struct os_mbuf *buf = os_msys_get(0, 0);
|
||||||
u16_t handle = sys_cpu_to_le16(cmd->handle);
|
uint16_t handle = sys_cpu_to_le16(cmd->handle);
|
||||||
uint8_t out_att_err;
|
uint8_t out_att_err;
|
||||||
int conn_status;
|
int conn_status;
|
||||||
|
|
||||||
@ -1766,7 +1766,7 @@ free:
|
|||||||
os_mbuf_free_chain(buf);
|
os_mbuf_free_chain(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void change_database(u8_t *data, u16_t len)
|
static void change_database(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct gatt_change_database *cmd = (void *) data;
|
const struct gatt_change_database *cmd = (void *) data;
|
||||||
|
|
||||||
@ -1782,9 +1782,9 @@ static void change_database(u8_t *data, u16_t len)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void supported_commands(u8_t *data, u16_t len)
|
static void supported_commands(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t cmds[4];
|
uint8_t cmds[4];
|
||||||
struct gatt_read_supported_commands_rp *rp = (void *) cmds;
|
struct gatt_read_supported_commands_rp *rp = (void *) cmds;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -1816,7 +1816,7 @@ static void supported_commands(u8_t *data, u16_t len)
|
|||||||
tester_set_bit(cmds, GATT_CHANGE_DATABASE);
|
tester_set_bit(cmds, GATT_CHANGE_DATABASE);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS,
|
tester_send(BTP_SERVICE_ID_GATT, GATT_READ_SUPPORTED_COMMANDS,
|
||||||
CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
|
CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum attr_type {
|
enum attr_type {
|
||||||
@ -1825,8 +1825,8 @@ enum attr_type {
|
|||||||
BLE_GATT_ATTR_DSC,
|
BLE_GATT_ATTR_DSC,
|
||||||
};
|
};
|
||||||
|
|
||||||
void tester_handle_gatt(u8_t opcode, u8_t index, u8_t *data,
|
void tester_handle_gatt(uint8_t opcode, uint8_t index, uint8_t *data,
|
||||||
u16_t len)
|
uint16_t len)
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case GATT_READ_SUPPORTED_COMMANDS:
|
case GATT_READ_SUPPORTED_COMMANDS:
|
||||||
@ -1905,8 +1905,8 @@ void tester_handle_gatt(u8_t opcode, u8_t index, u8_t *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tester_gatt_notify_rx_ev(u16_t conn_handle, u16_t attr_handle,
|
int tester_gatt_notify_rx_ev(uint16_t conn_handle, uint16_t attr_handle,
|
||||||
u8_t indication, struct os_mbuf *om)
|
uint8_t indication, struct os_mbuf *om)
|
||||||
{
|
{
|
||||||
struct gatt_notification_ev *ev;
|
struct gatt_notification_ev *ev;
|
||||||
struct ble_gap_conn_desc conn;
|
struct ble_gap_conn_desc conn;
|
||||||
@ -1930,7 +1930,7 @@ int tester_gatt_notify_rx_ev(u16_t conn_handle, u16_t attr_handle,
|
|||||||
|
|
||||||
ev->address_type = addr->type;
|
ev->address_type = addr->type;
|
||||||
memcpy(ev->address, addr->val, sizeof(ev->address));
|
memcpy(ev->address, addr->val, sizeof(ev->address));
|
||||||
ev->type = (u8_t) (indication ? 0x02 : 0x01);
|
ev->type = (uint8_t) (indication ? 0x02 : 0x01);
|
||||||
ev->handle = sys_cpu_to_le16(attr_handle);
|
ev->handle = sys_cpu_to_le16(attr_handle);
|
||||||
ev->data_length = sys_cpu_to_le16(os_mbuf_len(om));
|
ev->data_length = sys_cpu_to_le16(os_mbuf_len(om));
|
||||||
os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om));
|
os_mbuf_appendfrom(buf, om, 0, os_mbuf_len(om));
|
||||||
@ -1988,9 +1988,9 @@ void notify_test(struct os_event *ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tester_gatt_subscribe_ev(u16_t conn_handle, u16_t attr_handle, u8_t reason,
|
int tester_gatt_subscribe_ev(uint16_t conn_handle, uint16_t attr_handle, uint8_t reason,
|
||||||
u8_t prev_notify, u8_t cur_notify,
|
uint8_t prev_notify, uint8_t cur_notify,
|
||||||
u8_t prev_indicate, u8_t cur_indicate)
|
uint8_t prev_indicate, uint8_t cur_indicate)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
myconn_handle = conn_handle;
|
myconn_handle = conn_handle;
|
||||||
@ -2084,7 +2084,7 @@ int gatt_svr_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_init_gatt(void)
|
uint8_t tester_init_gatt(void)
|
||||||
{
|
{
|
||||||
os_callout_init(¬ify_tx_timer, os_eventq_dflt_get(),
|
os_callout_init(¬ify_tx_timer, os_eventq_dflt_get(),
|
||||||
notify_test, NULL);
|
notify_test, NULL);
|
||||||
@ -2092,7 +2092,7 @@ u8_t tester_init_gatt(void)
|
|||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_unregister_gatt(void)
|
uint8_t tester_unregister_gatt(void)
|
||||||
{
|
{
|
||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ const char *bt_hex(const void *buf, size_t len)
|
|||||||
{
|
{
|
||||||
static const char hex[] = "0123456789abcdef";
|
static const char hex[] = "0123456789abcdef";
|
||||||
static char hexbufs[4][137];
|
static char hexbufs[4][137];
|
||||||
static u8_t curbuf;
|
static uint8_t curbuf;
|
||||||
const u8_t *b = buf;
|
const uint8_t *b = buf;
|
||||||
char *str;
|
char *str;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
#include "os/endian.h"
|
#include "os/endian.h"
|
||||||
|
|
||||||
#define u8_t uint8_t
|
#define uint8_t uint8_t
|
||||||
#define s8_t int8_t
|
#define int8_t int8_t
|
||||||
#define u16_t uint16_t
|
#define uint16_t uint16_t
|
||||||
#define u32_t uint32_t
|
#define uint32_t uint32_t
|
||||||
#define s32_t int32_t
|
#define int32_t int32_t
|
||||||
|
|
||||||
#ifndef BIT
|
#ifndef BIT
|
||||||
#define BIT(n) (1UL << (n))
|
#define BIT(n) (1UL << (n))
|
||||||
@ -37,16 +37,16 @@
|
|||||||
#define sys_le16_to_cpu le16toh
|
#define sys_le16_to_cpu le16toh
|
||||||
|
|
||||||
struct bt_data {
|
struct bt_data {
|
||||||
u8_t type;
|
uint8_t type;
|
||||||
u8_t data_len;
|
uint8_t data_len;
|
||||||
const u8_t *data;
|
const uint8_t *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BT_DATA(_type, _data, _data_len) \
|
#define BT_DATA(_type, _data, _data_len) \
|
||||||
{ \
|
{ \
|
||||||
.type = (_type), \
|
.type = (_type), \
|
||||||
.data_len = (_data_len), \
|
.data_len = (_data_len), \
|
||||||
.data = (const u8_t *)(_data), \
|
.data = (const uint8_t *)(_data), \
|
||||||
}
|
}
|
||||||
|
|
||||||
struct os_mbuf * NET_BUF_SIMPLE(uint16_t size);
|
struct os_mbuf * NET_BUF_SIMPLE(uint16_t size);
|
||||||
|
@ -33,11 +33,13 @@
|
|||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
#include "host/ble_l2cap.h"
|
#include "host/ble_l2cap.h"
|
||||||
|
|
||||||
|
#include "../../../nimble/host/src/ble_l2cap_priv.h"
|
||||||
|
|
||||||
#include "bttester.h"
|
#include "bttester.h"
|
||||||
|
|
||||||
#define CONTROLLER_INDEX 0
|
#define CONTROLLER_INDEX 0
|
||||||
#define CHANNELS MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
|
#define CHANNELS MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
|
||||||
#define TESTER_COC_MTU (230)
|
#define TESTER_COC_MTU MYNEWT_VAL(BTTESTER_L2CAP_COC_MTU)
|
||||||
#define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
|
#define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
|
||||||
|
|
||||||
static os_membuf_t tester_sdu_coc_mem[
|
static os_membuf_t tester_sdu_coc_mem[
|
||||||
@ -48,14 +50,34 @@ struct os_mbuf_pool sdu_os_mbuf_pool;
|
|||||||
static struct os_mempool sdu_coc_mbuf_mempool;
|
static struct os_mempool sdu_coc_mbuf_mempool;
|
||||||
|
|
||||||
static struct channel {
|
static struct channel {
|
||||||
u8_t chan_id; /* Internal number that identifies L2CAP channel. */
|
uint8_t chan_id; /* Internal number that identifies L2CAP channel. */
|
||||||
u8_t state;
|
uint8_t state;
|
||||||
struct ble_l2cap_chan *chan;
|
struct ble_l2cap_chan *chan;
|
||||||
} channels[CHANNELS];
|
} channels[CHANNELS];
|
||||||
|
|
||||||
static u8_t recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)];
|
static uint8_t recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)];
|
||||||
|
|
||||||
struct channel *find_channel(struct ble_l2cap_chan *chan) {
|
static struct channel *get_free_channel(void)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
struct channel *chan;
|
||||||
|
|
||||||
|
for (i = 0; i < CHANNELS; i++) {
|
||||||
|
if (channels[i].state) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan = &channels[i];
|
||||||
|
chan->chan_id = i;
|
||||||
|
|
||||||
|
return chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct channel *find_channel(struct ble_l2cap_chan *chan)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < CHANNELS; ++i) {
|
for (i = 0; i < CHANNELS; ++i) {
|
||||||
@ -67,6 +89,15 @@ struct channel *find_channel(struct ble_l2cap_chan *chan) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct channel *get_channel(uint8_t chan_id)
|
||||||
|
{
|
||||||
|
if (chan_id >= CHANNELS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &channels[chan_id];
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
|
tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
|
||||||
{
|
{
|
||||||
@ -84,14 +115,20 @@ static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
|||||||
struct os_mbuf *buf, void *arg)
|
struct os_mbuf *buf, void *arg)
|
||||||
{
|
{
|
||||||
struct l2cap_data_received_ev *ev = (void *) recv_cb_buf;
|
struct l2cap_data_received_ev *ev = (void *) recv_cb_buf;
|
||||||
struct channel *channel = arg;
|
struct channel *channel = find_channel(chan);
|
||||||
|
assert(channel != NULL);
|
||||||
|
|
||||||
ev->chan_id = channel->chan_id;
|
ev->chan_id = channel->chan_id;
|
||||||
ev->data_length = buf->om_len;
|
ev->data_length = OS_MBUF_PKTLEN(buf);
|
||||||
memcpy(ev->data, buf->om_data, buf->om_len);
|
|
||||||
|
if (ev->data_length > TESTER_COC_MTU) {
|
||||||
|
SYS_LOG_ERR("Too large sdu received, truncating data");
|
||||||
|
ev->data_length = TESTER_COC_MTU;
|
||||||
|
}
|
||||||
|
os_mbuf_copydata(buf, 0, ev->data_length, ev->data);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED,
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED,
|
||||||
CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + buf->om_len);
|
CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length);
|
||||||
|
|
||||||
tester_l2cap_coc_recv(chan, buf);
|
tester_l2cap_coc_recv(chan, buf);
|
||||||
}
|
}
|
||||||
@ -108,44 +145,49 @@ static void unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct channel *get_free_channel(void)
|
static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
||||||
|
struct ble_l2cap_chan_info *chan_info,
|
||||||
|
int status)
|
||||||
{
|
{
|
||||||
u8_t i;
|
struct l2cap_reconfigured_ev ev;
|
||||||
struct channel *chan;
|
struct channel *channel;
|
||||||
|
|
||||||
for (i = 0; i < CHANNELS; i++) {
|
if (status != 0) {
|
||||||
if (channels[i].state) {
|
return;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chan = &channels[i];
|
channel = find_channel(chan);
|
||||||
chan->chan_id = i;
|
assert(channel != NULL);
|
||||||
|
|
||||||
return chan;
|
ev.chan_id = channel->chan_id;
|
||||||
}
|
ev.peer_mtu = chan_info->peer_coc_mtu;
|
||||||
|
ev.peer_mps = chan_info->peer_l2cap_mtu;
|
||||||
|
ev.our_mtu = chan_info->our_coc_mtu;
|
||||||
|
ev.our_mps = chan_info->our_l2cap_mtu;
|
||||||
|
|
||||||
return NULL;
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED,
|
||||||
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
||||||
void *arg)
|
struct ble_l2cap_chan_info *chan_info, void *arg)
|
||||||
{
|
{
|
||||||
struct l2cap_connected_ev ev;
|
struct l2cap_connected_ev ev;
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct channel *channel;
|
struct channel *channel = find_channel(chan);
|
||||||
|
|
||||||
|
if (channel == NULL) {
|
||||||
channel = get_free_channel();
|
channel = get_free_channel();
|
||||||
if (!channel) {
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->chan = chan;
|
|
||||||
channel->state = 0;
|
|
||||||
|
|
||||||
ev.chan_id = channel->chan_id;
|
ev.chan_id = channel->chan_id;
|
||||||
|
ev.psm = chan_info->psm;
|
||||||
|
ev.peer_mtu = chan_info->peer_coc_mtu;
|
||||||
|
ev.peer_mps = chan_info->peer_l2cap_mtu;
|
||||||
|
ev.our_mtu = chan_info->our_coc_mtu;
|
||||||
|
ev.our_mps = chan_info->our_l2cap_mtu;
|
||||||
channel->state = 1;
|
channel->state = 1;
|
||||||
channel->chan = chan;
|
channel->chan = chan;
|
||||||
/* TODO: ev.psm */
|
|
||||||
|
|
||||||
if (!ble_gap_conn_find(conn_handle, &desc)) {
|
if (!ble_gap_conn_find(conn_handle, &desc)) {
|
||||||
ev.address_type = desc.peer_ota_addr.type;
|
ev.address_type = desc.peer_ota_addr.type;
|
||||||
@ -154,11 +196,11 @@ static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX,
|
||||||
(u8_t *) &ev, sizeof(ev));
|
(uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
||||||
void *arg)
|
struct ble_l2cap_chan_info *chan_info, void *arg)
|
||||||
{
|
{
|
||||||
struct l2cap_disconnected_ev ev;
|
struct l2cap_disconnected_ev ev;
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
@ -167,14 +209,12 @@ static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
|||||||
memset(&ev, 0, sizeof(struct l2cap_disconnected_ev));
|
memset(&ev, 0, sizeof(struct l2cap_disconnected_ev));
|
||||||
|
|
||||||
channel = find_channel(chan);
|
channel = find_channel(chan);
|
||||||
if (channel != NULL) {
|
assert(channel != NULL);
|
||||||
|
|
||||||
channel->state = 0;
|
channel->state = 0;
|
||||||
channel->chan = chan;
|
channel->chan = chan;
|
||||||
|
|
||||||
ev.chan_id = channel->chan_id;
|
ev.chan_id = channel->chan_id;
|
||||||
/* TODO: ev.result */
|
ev.psm = chan_info->psm;
|
||||||
/* TODO: ev.psm */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ble_gap_conn_find(conn_handle, &desc)) {
|
if (!ble_gap_conn_find(conn_handle, &desc)) {
|
||||||
ev.address_type = desc.peer_ota_addr.type;
|
ev.address_type = desc.peer_ota_addr.type;
|
||||||
@ -183,7 +223,7 @@ static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED,
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int accept_cb(uint16_t conn_handle, uint16_t peer_mtu,
|
static int accept_cb(uint16_t conn_handle, uint16_t peer_mtu,
|
||||||
@ -208,39 +248,51 @@ static int
|
|||||||
tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
||||||
{
|
{
|
||||||
struct ble_l2cap_chan_info chan_info;
|
struct ble_l2cap_chan_info chan_info;
|
||||||
|
int accept_response;
|
||||||
|
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case BLE_L2CAP_EVENT_COC_CONNECTED:
|
case BLE_L2CAP_EVENT_COC_CONNECTED:
|
||||||
|
if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (event->connect.status) {
|
if (event->connect.status) {
|
||||||
console_printf("LE COC error: %d\n", event->connect.status);
|
console_printf("LE COC error: %d\n", event->connect.status);
|
||||||
disconnected_cb(event->connect.conn_handle,
|
disconnected_cb(event->connect.conn_handle,
|
||||||
event->connect.chan, arg);
|
event->connect.chan, &chan_info, arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_l2cap_get_chan_info(event->connect.chan, &chan_info);
|
console_printf("LE COC connected, conn: %d, chan: 0x%08lx, "
|
||||||
|
"psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, "
|
||||||
console_printf("LE COC connected, conn: %d, chan: 0x%08lx, scid: 0x%04x, "
|
"our_mps: %d, our_mtu: %d, peer_mps: %d, "
|
||||||
"dcid: 0x%04x, our_mtu: 0x%04x, peer_mtu: 0x%04x\n",
|
"peer_mtu: %d\n", event->connect.conn_handle,
|
||||||
event->connect.conn_handle,
|
(uint32_t) event->connect.chan, chan_info.psm,
|
||||||
(uint32_t) event->connect.chan,
|
chan_info.scid, chan_info.dcid,
|
||||||
chan_info.scid,
|
chan_info.our_l2cap_mtu, chan_info.our_coc_mtu,
|
||||||
chan_info.dcid,
|
chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
|
||||||
chan_info.our_l2cap_mtu,
|
|
||||||
chan_info.peer_l2cap_mtu);
|
|
||||||
|
|
||||||
connected_cb(event->connect.conn_handle,
|
connected_cb(event->connect.conn_handle,
|
||||||
event->connect.chan, arg);
|
event->connect.chan, &chan_info, arg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
|
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
|
||||||
|
if (ble_l2cap_get_chan_info(event->disconnect.chan,
|
||||||
|
&chan_info)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
console_printf("LE CoC disconnected, chan: 0x%08lx\n",
|
console_printf("LE CoC disconnected, chan: 0x%08lx\n",
|
||||||
(uint32_t) event->disconnect.chan);
|
(uint32_t) event->disconnect.chan);
|
||||||
|
|
||||||
disconnected_cb(event->disconnect.conn_handle,
|
disconnected_cb(event->disconnect.conn_handle,
|
||||||
event->disconnect.chan, arg);
|
event->disconnect.chan, &chan_info, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case BLE_L2CAP_EVENT_COC_ACCEPT:
|
case BLE_L2CAP_EVENT_COC_ACCEPT:
|
||||||
|
accept_response = POINTER_TO_INT(arg);
|
||||||
|
if (accept_response) {
|
||||||
|
return accept_response;
|
||||||
|
}
|
||||||
|
|
||||||
console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n",
|
console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n",
|
||||||
(uint32_t) event->accept.chan,
|
(uint32_t) event->accept.chan,
|
||||||
event->accept.conn_handle,
|
event->accept.conn_handle,
|
||||||
@ -254,7 +306,8 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
|||||||
console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n",
|
console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n",
|
||||||
(uint32_t) event->receive.chan,
|
(uint32_t) event->receive.chan,
|
||||||
event->receive.conn_handle,
|
event->receive.conn_handle,
|
||||||
event->receive.sdu_rx->om_len);
|
OS_MBUF_PKTLEN(event->receive.sdu_rx));
|
||||||
|
|
||||||
recv_cb(event->receive.conn_handle, event->receive.chan,
|
recv_cb(event->receive.conn_handle, event->receive.chan,
|
||||||
event->receive.sdu_rx, arg);
|
event->receive.sdu_rx, arg);
|
||||||
return 0;
|
return 0;
|
||||||
@ -263,57 +316,118 @@ tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
|
|||||||
(uint32_t) event->tx_unstalled.chan,
|
(uint32_t) event->tx_unstalled.chan,
|
||||||
event->tx_unstalled.conn_handle,
|
event->tx_unstalled.conn_handle,
|
||||||
event->tx_unstalled.status);
|
event->tx_unstalled.status);
|
||||||
|
|
||||||
unstalled_cb(event->tx_unstalled.conn_handle,
|
unstalled_cb(event->tx_unstalled.conn_handle,
|
||||||
event->tx_unstalled.chan,
|
event->tx_unstalled.chan,
|
||||||
event->tx_unstalled.status, arg);
|
event->tx_unstalled.status, arg);
|
||||||
return 0;
|
return 0;
|
||||||
|
case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED:
|
||||||
|
if (ble_l2cap_get_chan_info(event->reconfigured.chan,
|
||||||
|
&chan_info)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
console_printf("LE CoC reconfigure completed status 0x%02x, "
|
||||||
|
"chan: 0x%08lx\n", event->reconfigured.status,
|
||||||
|
(uint32_t) event->reconfigured.chan);
|
||||||
|
|
||||||
|
if (event->reconfigured.status == 0) {
|
||||||
|
console_printf("\t our_mps: %d our_mtu %d\n",
|
||||||
|
chan_info.our_l2cap_mtu, chan_info.our_coc_mtu);
|
||||||
|
}
|
||||||
|
|
||||||
|
reconfigured_ev(event->reconfigured.conn_handle,
|
||||||
|
event->reconfigured.chan,
|
||||||
|
&chan_info,
|
||||||
|
event->reconfigured.status);
|
||||||
|
return 0;
|
||||||
|
case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED:
|
||||||
|
if (ble_l2cap_get_chan_info(event->reconfigured.chan,
|
||||||
|
&chan_info)) {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
console_printf("LE CoC peer reconfigured status 0x%02x, "
|
||||||
|
"chan: 0x%08lx\n", event->reconfigured.status,
|
||||||
|
(uint32_t) event->reconfigured.chan);
|
||||||
|
|
||||||
|
if (event->reconfigured.status == 0) {
|
||||||
|
console_printf("\t peer_mps: %d peer_mtu %d\n",
|
||||||
|
chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
|
||||||
|
}
|
||||||
|
|
||||||
|
reconfigured_ev(event->reconfigured.conn_handle,
|
||||||
|
event->reconfigured.chan,
|
||||||
|
&chan_info,
|
||||||
|
event->reconfigured.status);
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void connect(u8_t *data, u16_t len)
|
static void connect(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct l2cap_connect_cmd *cmd = (void *) data;
|
const struct l2cap_connect_cmd *cmd = (void *) data;
|
||||||
struct l2cap_connect_rp rp;
|
uint8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num];
|
||||||
|
struct l2cap_connect_rp *rp = (void *) rp_buf;
|
||||||
struct ble_gap_conn_desc desc;
|
struct ble_gap_conn_desc desc;
|
||||||
struct channel *chan;
|
struct channel *chan;
|
||||||
struct os_mbuf *sdu_rx;
|
struct os_mbuf *sdu_rx[cmd->num];
|
||||||
ble_addr_t *addr = (void *) data;
|
ble_addr_t *addr = (void *) data;
|
||||||
|
uint16_t mtu = htole16(cmd->mtu);
|
||||||
int rc;
|
int rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6));
|
SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6));
|
||||||
|
|
||||||
|
if (mtu == 0 || mtu > TESTER_COC_MTU) {
|
||||||
|
mtu = TESTER_COC_MTU;
|
||||||
|
}
|
||||||
|
|
||||||
rc = ble_gap_conn_find_by_addr(addr, &desc);
|
rc = ble_gap_conn_find_by_addr(addr, &desc);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SYS_LOG_ERR("GAP conn find failed");
|
SYS_LOG_ERR("GAP conn find failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rp->num = cmd->num;
|
||||||
|
|
||||||
|
for (i = 0; i < cmd->num; i++) {
|
||||||
chan = get_free_channel();
|
chan = get_free_channel();
|
||||||
if (!chan) {
|
if (!chan) {
|
||||||
SYS_LOG_ERR("No free channels");
|
SYS_LOG_ERR("No free channels");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
|
rp->chan_ids[i] = chan->chan_id;
|
||||||
if (sdu_rx == NULL) {
|
|
||||||
|
sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
|
||||||
|
if (sdu_rx[i] == NULL) {
|
||||||
SYS_LOG_ERR("Failed to alloc buf");
|
SYS_LOG_ERR("Failed to alloc buf");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->num == 1) {
|
||||||
rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm),
|
rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm),
|
||||||
TESTER_COC_MTU, sdu_rx,
|
mtu, sdu_rx[0],
|
||||||
tester_l2cap_event, chan);
|
tester_l2cap_event, NULL);
|
||||||
|
} else if (cmd->num > 1) {
|
||||||
|
rc = ble_l2cap_enhanced_connect(desc.conn_handle,
|
||||||
|
htole16(cmd->psm), mtu,
|
||||||
|
cmd->num, sdu_rx,
|
||||||
|
tester_l2cap_event, NULL);
|
||||||
|
} else {
|
||||||
|
SYS_LOG_ERR("Invalid 'num' parameter value");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SYS_LOG_ERR("L2CAP connect failed\n");
|
SYS_LOG_ERR("L2CAP connect failed\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.chan_id = chan->chan_id;
|
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
|
||||||
(u8_t *) &rp, sizeof(rp));
|
(uint8_t *) rp, sizeof(rp_buf));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -322,16 +436,17 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnect(u8_t *data, u16_t len)
|
static void disconnect(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct l2cap_disconnect_cmd *cmd = (void *) data;
|
const struct l2cap_disconnect_cmd *cmd = (void *) data;
|
||||||
struct channel *chan;
|
struct channel *chan;
|
||||||
u8_t status;
|
uint8_t status;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
chan = &channels[cmd->chan_id];
|
chan = get_channel(cmd->chan_id);
|
||||||
|
assert(chan != NULL);
|
||||||
|
|
||||||
err = ble_l2cap_disconnect(chan->chan);
|
err = ble_l2cap_disconnect(chan->chan);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -346,16 +461,21 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_data(u8_t *data, u16_t len)
|
static void send_data(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct l2cap_send_data_cmd *cmd = (void *) data;
|
const struct l2cap_send_data_cmd *cmd = (void *) data;
|
||||||
struct channel *chan = &channels[cmd->chan_id];
|
|
||||||
struct os_mbuf *sdu_tx = NULL;
|
struct os_mbuf *sdu_tx = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
u16_t data_len = sys_le16_to_cpu(cmd->data_len);
|
uint16_t data_len = sys_le16_to_cpu(cmd->data_len);
|
||||||
|
struct channel *chan = get_channel(cmd->chan_id);
|
||||||
|
|
||||||
SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id);
|
SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id);
|
||||||
|
|
||||||
|
if (!chan) {
|
||||||
|
SYS_LOG_ERR("Invalid channel\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: For now, fail if data length exceeds buffer length */
|
/* FIXME: For now, fail if data length exceeds buffer length */
|
||||||
if (data_len > TESTER_COC_MTU) {
|
if (data_len > TESTER_COC_MTU) {
|
||||||
SYS_LOG_ERR("Data length exceeds buffer length");
|
SYS_LOG_ERR("Data length exceeds buffer length");
|
||||||
@ -386,16 +506,48 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void listen(u8_t *data, u16_t len)
|
static int
|
||||||
|
l2cap_coc_err2hs_err(uint16_t coc_err)
|
||||||
|
{
|
||||||
|
switch (coc_err) {
|
||||||
|
case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM:
|
||||||
|
return BLE_HS_ENOTSUP;
|
||||||
|
case BLE_L2CAP_COC_ERR_NO_RESOURCES:
|
||||||
|
return BLE_HS_ENOMEM;
|
||||||
|
case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN:
|
||||||
|
return BLE_HS_EAUTHEN;
|
||||||
|
case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR:
|
||||||
|
return BLE_HS_EAUTHOR;
|
||||||
|
case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC:
|
||||||
|
return BLE_HS_EENCRYPT;
|
||||||
|
case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ:
|
||||||
|
return BLE_HS_EENCRYPT_KEY_SZ;
|
||||||
|
case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS:
|
||||||
|
return BLE_HS_EINVAL;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void listen(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct l2cap_listen_cmd *cmd = (void *) data;
|
const struct l2cap_listen_cmd *cmd = (void *) data;
|
||||||
|
uint16_t mtu = htole16(cmd->mtu);
|
||||||
|
uint16_t rsp = htole16(cmd->response);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
|
if (mtu == 0 || mtu > TESTER_COC_MTU) {
|
||||||
|
mtu = TESTER_COC_MTU;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsp = l2cap_coc_err2hs_err(rsp);
|
||||||
|
|
||||||
/* TODO: Handle cmd->transport flag */
|
/* TODO: Handle cmd->transport flag */
|
||||||
rc = ble_l2cap_create_server(cmd->psm, TESTER_COC_MTU,
|
rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event,
|
||||||
tester_l2cap_event, NULL);
|
INT_TO_POINTER(rsp));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -409,9 +561,54 @@ fail:
|
|||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void supported_commands(u8_t *data, u16_t len)
|
static void reconfigure(const uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t cmds[1];
|
const struct l2cap_reconfigure_cmd *cmd = (void *) data;
|
||||||
|
uint16_t mtu = htole16(cmd->mtu);
|
||||||
|
struct ble_gap_conn_desc desc;
|
||||||
|
ble_addr_t *addr = (void *) data;
|
||||||
|
struct ble_l2cap_chan *chans[cmd->num];
|
||||||
|
struct channel *channel;
|
||||||
|
int rc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
|
if (mtu == 0 || mtu > TESTER_COC_MTU) {
|
||||||
|
mtu = TESTER_COC_MTU;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ble_gap_conn_find_by_addr(addr, &desc);
|
||||||
|
if (rc) {
|
||||||
|
SYS_LOG_ERR("GAP conn find failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cmd->num; ++i) {
|
||||||
|
channel = get_channel(cmd->idxs[i]);
|
||||||
|
if (channel == NULL) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
chans[i] = channel->chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ble_l2cap_reconfig(chans, cmd->num, mtu);
|
||||||
|
if (rc) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
|
||||||
|
BTP_STATUS_SUCCESS);
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
|
||||||
|
BTP_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void supported_commands(uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
uint8_t cmds[1];
|
||||||
struct l2cap_read_supported_commands_rp *rp = (void *) cmds;
|
struct l2cap_read_supported_commands_rp *rp = (void *) cmds;
|
||||||
|
|
||||||
memset(cmds, 0, sizeof(cmds));
|
memset(cmds, 0, sizeof(cmds));
|
||||||
@ -421,13 +618,14 @@ static void supported_commands(u8_t *data, u16_t len)
|
|||||||
tester_set_bit(cmds, L2CAP_DISCONNECT);
|
tester_set_bit(cmds, L2CAP_DISCONNECT);
|
||||||
tester_set_bit(cmds, L2CAP_LISTEN);
|
tester_set_bit(cmds, L2CAP_LISTEN);
|
||||||
tester_set_bit(cmds, L2CAP_SEND_DATA);
|
tester_set_bit(cmds, L2CAP_SEND_DATA);
|
||||||
|
tester_set_bit(cmds, L2CAP_RECONFIGURE);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS,
|
tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS,
|
||||||
CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
|
CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
|
void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data,
|
||||||
u16_t len)
|
uint16_t len)
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case L2CAP_READ_SUPPORTED_COMMANDS:
|
case L2CAP_READ_SUPPORTED_COMMANDS:
|
||||||
@ -445,6 +643,9 @@ void tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
|
|||||||
case L2CAP_LISTEN:
|
case L2CAP_LISTEN:
|
||||||
listen(data, len);
|
listen(data, len);
|
||||||
return;
|
return;
|
||||||
|
case L2CAP_RECONFIGURE:
|
||||||
|
reconfigure(data, len);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index,
|
tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index,
|
||||||
BTP_STATUS_UNKNOWN_CMD);
|
BTP_STATUS_UNKNOWN_CMD);
|
||||||
@ -452,7 +653,7 @@ void tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_init_l2cap(void)
|
uint8_t tester_init_l2cap(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -469,7 +670,7 @@ u8_t tester_init_l2cap(void)
|
|||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_unregister_l2cap(void)
|
uint8_t tester_unregister_l2cap(void)
|
||||||
{
|
{
|
||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#include "bttester.h"
|
#include "bttester.h"
|
||||||
|
|
||||||
extern u8_t own_addr_type;
|
extern uint8_t own_addr_type;
|
||||||
|
|
||||||
#define CONTROLLER_INDEX 0
|
#define CONTROLLER_INDEX 0
|
||||||
#define CID_LOCAL 0xffff
|
#define CID_LOCAL 0xffff
|
||||||
@ -47,21 +47,21 @@ extern u8_t own_addr_type;
|
|||||||
#define CUR_FAULTS_MAX 4
|
#define CUR_FAULTS_MAX 4
|
||||||
#define HEALTH_TEST_ID 0x00
|
#define HEALTH_TEST_ID 0x00
|
||||||
|
|
||||||
static u8_t cur_faults[CUR_FAULTS_MAX];
|
static uint8_t cur_faults[CUR_FAULTS_MAX];
|
||||||
static u8_t reg_faults[CUR_FAULTS_MAX * 2];
|
static uint8_t reg_faults[CUR_FAULTS_MAX * 2];
|
||||||
|
|
||||||
/* Provision node data */
|
/* Provision node data */
|
||||||
static u8_t net_key[16];
|
static uint8_t net_key[16];
|
||||||
static u16_t net_key_idx;
|
static uint16_t net_key_idx;
|
||||||
static u8_t flags;
|
static uint8_t flags;
|
||||||
static u32_t iv_index;
|
static uint32_t iv_index;
|
||||||
static u16_t addr;
|
static uint16_t addr;
|
||||||
static u8_t dev_key[16];
|
static uint8_t dev_key[16];
|
||||||
static u8_t input_size;
|
static uint8_t input_size;
|
||||||
|
|
||||||
/* Configured provisioning data */
|
/* Configured provisioning data */
|
||||||
static u8_t dev_uuid[16];
|
static uint8_t dev_uuid[16];
|
||||||
static u8_t static_auth[16];
|
static uint8_t static_auth[16];
|
||||||
|
|
||||||
/* Vendor Model data */
|
/* Vendor Model data */
|
||||||
#define VND_MODEL_ID_1 0x1234
|
#define VND_MODEL_ID_1 0x1234
|
||||||
@ -71,20 +71,20 @@ static u8_t static_auth[16];
|
|||||||
|
|
||||||
static struct model_data {
|
static struct model_data {
|
||||||
struct bt_mesh_model *model;
|
struct bt_mesh_model *model;
|
||||||
u16_t addr;
|
uint16_t addr;
|
||||||
u16_t appkey_idx;
|
uint16_t appkey_idx;
|
||||||
} model_bound[MODEL_BOUNDS_MAX];
|
} model_bound[MODEL_BOUNDS_MAX];
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
u16_t local;
|
uint16_t local;
|
||||||
u16_t dst;
|
uint16_t dst;
|
||||||
u16_t net_idx;
|
uint16_t net_idx;
|
||||||
} net = {
|
} net = {
|
||||||
.local = BT_MESH_ADDR_UNASSIGNED,
|
.local = BT_MESH_ADDR_UNASSIGNED,
|
||||||
.dst = BT_MESH_ADDR_UNASSIGNED,
|
.dst = BT_MESH_ADDR_UNASSIGNED,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void supported_commands(u8_t *data, u16_t len)
|
static void supported_commands(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
|
struct os_mbuf *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
|
||||||
|
|
||||||
@ -121,29 +121,9 @@ static void supported_commands(u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, buf);
|
CONTROLLER_INDEX, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv cfg_srv = {
|
static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, uint8_t *count)
|
||||||
.relay = BT_MESH_RELAY_ENABLED,
|
|
||||||
.beacon = BT_MESH_BEACON_ENABLED,
|
|
||||||
#if MYNEWT_VAL(BLE_MESH_FRIEND)
|
|
||||||
.frnd = BT_MESH_FRIEND_ENABLED,
|
|
||||||
#else
|
|
||||||
.frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
#if MYNEWT_VAL(BLE_MESH_GATT_PROXY)
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
|
|
||||||
#else
|
|
||||||
.gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
|
|
||||||
#endif
|
|
||||||
.default_ttl = 7,
|
|
||||||
|
|
||||||
/* 3 transmissions with 20ms interval */
|
|
||||||
.net_transmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
.relay_retransmit = BT_MESH_TRANSMIT(2, 20),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void get_faults(u8_t *faults, u8_t faults_size, u8_t *dst, u8_t *count)
|
|
||||||
{
|
{
|
||||||
u8_t i, limit = *count;
|
uint8_t i, limit = *count;
|
||||||
|
|
||||||
for (i = 0, *count = 0; i < faults_size && *count < limit; i++) {
|
for (i = 0, *count = 0; i < faults_size && *count < limit; i++) {
|
||||||
if (faults[i]) {
|
if (faults[i]) {
|
||||||
@ -153,8 +133,8 @@ static void get_faults(u8_t *faults, u8_t faults_size, u8_t *dst, u8_t *count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id,
|
static int fault_get_cur(struct bt_mesh_model *model, uint8_t *test_id,
|
||||||
u16_t *company_id, u8_t *faults, u8_t *fault_count)
|
uint16_t *company_id, uint8_t *faults, uint8_t *fault_count)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -166,8 +146,8 @@ static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fault_get_reg(struct bt_mesh_model *model, u16_t company_id,
|
static int fault_get_reg(struct bt_mesh_model *model, uint16_t company_id,
|
||||||
u8_t *test_id, u8_t *faults, u8_t *fault_count)
|
uint8_t *test_id, uint8_t *faults, uint8_t *fault_count)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("company_id 0x%04x", company_id);
|
SYS_LOG_DBG("company_id 0x%04x", company_id);
|
||||||
|
|
||||||
@ -229,7 +209,7 @@ health_pub_init(void)
|
|||||||
static struct bt_mesh_cfg_cli cfg_cli = {
|
static struct bt_mesh_cfg_cli cfg_cli = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void show_faults(u8_t test_id, u16_t cid, u8_t *faults, size_t fault_count)
|
void show_faults(uint8_t test_id, uint16_t cid, uint8_t *faults, size_t fault_count)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -247,8 +227,8 @@ void show_faults(u8_t test_id, u16_t cid, u8_t *faults, size_t fault_count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void health_current_status(struct bt_mesh_health_cli *cli, u16_t addr,
|
static void health_current_status(struct bt_mesh_health_cli *cli, uint16_t addr,
|
||||||
u8_t test_id, u16_t cid, u8_t *faults,
|
uint8_t test_id, uint16_t cid, uint8_t *faults,
|
||||||
size_t fault_count)
|
size_t fault_count)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("Health Current Status from 0x%04x", addr);
|
SYS_LOG_DBG("Health Current Status from 0x%04x", addr);
|
||||||
@ -260,7 +240,7 @@ static struct bt_mesh_health_cli health_cli = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct bt_mesh_model root_models[] = {
|
static struct bt_mesh_model root_models[] = {
|
||||||
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
|
BT_MESH_MODEL_CFG_SRV,
|
||||||
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
|
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
|
||||||
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
||||||
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
|
BT_MESH_MODEL_HEALTH_CLI(&health_cli),
|
||||||
@ -295,7 +275,7 @@ static void link_open(bt_mesh_prov_bearer_t bearer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN,
|
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_OPEN,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void link_close(bt_mesh_prov_bearer_t bearer)
|
static void link_close(bt_mesh_prov_bearer_t bearer)
|
||||||
@ -318,10 +298,10 @@ static void link_close(bt_mesh_prov_bearer_t bearer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED,
|
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_PROV_LINK_CLOSED,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int output_number(bt_mesh_output_action_t action, u32_t number)
|
static int output_number(bt_mesh_output_action_t action, uint32_t number)
|
||||||
{
|
{
|
||||||
struct mesh_out_number_action_ev ev;
|
struct mesh_out_number_action_ev ev;
|
||||||
|
|
||||||
@ -331,7 +311,7 @@ static int output_number(bt_mesh_output_action_t action, u32_t number)
|
|||||||
ev.number = sys_cpu_to_le32(number);
|
ev.number = sys_cpu_to_le32(number);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION,
|
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_OUT_NUMBER_ACTION,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -357,7 +337,7 @@ static int output_string(const char *str)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int input(bt_mesh_input_action_t action, u8_t size)
|
static int input(bt_mesh_input_action_t action, uint8_t size)
|
||||||
{
|
{
|
||||||
struct mesh_in_action_ev ev;
|
struct mesh_in_action_ev ev;
|
||||||
|
|
||||||
@ -369,12 +349,15 @@ static int input(bt_mesh_input_action_t action, u8_t size)
|
|||||||
ev.size = size;
|
ev.size = size;
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX,
|
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_IN_ACTION, CONTROLLER_INDEX,
|
||||||
(u8_t *) &ev, sizeof(ev));
|
(uint8_t *) &ev, sizeof(ev));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prov_complete(u16_t net_idx, u16_t addr)
|
static uint8_t vnd_app_key[16];
|
||||||
|
static uint16_t vnd_app_key_idx = 0x000f;
|
||||||
|
|
||||||
|
static void prov_complete(uint16_t net_idx, uint16_t addr)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr);
|
SYS_LOG_DBG("net_idx 0x%04x addr 0x%04x", net_idx, addr);
|
||||||
|
|
||||||
@ -412,7 +395,7 @@ static struct bt_mesh_prov prov = {
|
|||||||
.reset = prov_reset,
|
.reset = prov_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void config_prov(u8_t *data, u16_t len)
|
static void config_prov(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct mesh_config_provisioning_cmd *cmd = (void *) data;
|
const struct mesh_config_provisioning_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -430,7 +413,7 @@ static void config_prov(u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void provision_node(u8_t *data, u16_t len)
|
static void provision_node(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct mesh_provision_node_cmd *cmd = (void *) data;
|
const struct mesh_provision_node_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -448,9 +431,9 @@ static void provision_node(u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init(u8_t *data, u16_t len)
|
static void init(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -475,15 +458,12 @@ static void init(u8_t *data, u16_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set device key for vendor model */
|
|
||||||
vnd_models[0].keys[0] = BT_MESH_KEY_DEV;
|
|
||||||
|
|
||||||
rsp:
|
rsp:
|
||||||
tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX,
|
tester_rsp(BTP_SERVICE_ID_MESH, MESH_INIT, CONTROLLER_INDEX,
|
||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset(u8_t *data, u16_t len)
|
static void reset(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -493,11 +473,11 @@ static void reset(u8_t *data, u16_t len)
|
|||||||
BTP_STATUS_SUCCESS);
|
BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_number(u8_t *data, u16_t len)
|
static void input_number(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct mesh_input_number_cmd *cmd = (void *) data;
|
const struct mesh_input_number_cmd *cmd = (void *) data;
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
u32_t number;
|
uint32_t number;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
number = sys_le32_to_cpu(cmd->number);
|
number = sys_le32_to_cpu(cmd->number);
|
||||||
@ -513,11 +493,11 @@ static void input_number(u8_t *data, u16_t len)
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_string(u8_t *data, u16_t len)
|
static void input_string(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct mesh_input_string_cmd *cmd = (void *) data;
|
const struct mesh_input_string_cmd *cmd = (void *) data;
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
uint8_t status = BTP_STATUS_SUCCESS;
|
||||||
u8_t str_auth[16];
|
uint8_t str_auth[16];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
@ -544,7 +524,7 @@ rsp:
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ivu_test_mode(u8_t *data, u16_t len)
|
static void ivu_test_mode(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
const struct mesh_ivu_test_mode_cmd *cmd = (void *) data;
|
const struct mesh_ivu_test_mode_cmd *cmd = (void *) data;
|
||||||
|
|
||||||
@ -556,7 +536,7 @@ static void ivu_test_mode(u8_t *data, u16_t len)
|
|||||||
BTP_STATUS_SUCCESS);
|
BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ivu_toggle_state(u8_t *data, u16_t len)
|
static void ivu_toggle_state(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
@ -571,7 +551,7 @@ static void ivu_toggle_state(u8_t *data, u16_t len)
|
|||||||
result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED);
|
result ? BTP_STATUS_SUCCESS : BTP_STATUS_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpn(u8_t *data, u16_t len)
|
static void lpn(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_lpn_set_cmd *cmd = (void *) data;
|
struct mesh_lpn_set_cmd *cmd = (void *) data;
|
||||||
bool enable;
|
bool enable;
|
||||||
@ -589,7 +569,7 @@ static void lpn(u8_t *data, u16_t len)
|
|||||||
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpn_poll(u8_t *data, u16_t len)
|
static void lpn_poll(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -604,13 +584,13 @@ static void lpn_poll(u8_t *data, u16_t len)
|
|||||||
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void net_send(u8_t *data, u16_t len)
|
static void net_send(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_net_send_cmd *cmd = (void *) data;
|
struct mesh_net_send_cmd *cmd = (void *) data;
|
||||||
struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX);
|
struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX);
|
||||||
struct bt_mesh_msg_ctx ctx = {
|
struct bt_mesh_msg_ctx ctx = {
|
||||||
.net_idx = net.net_idx,
|
.net_idx = net.net_idx,
|
||||||
.app_idx = BT_MESH_KEY_DEV,
|
.app_idx = vnd_app_key_idx,
|
||||||
.addr = sys_le16_to_cpu(cmd->dst),
|
.addr = sys_le16_to_cpu(cmd->dst),
|
||||||
.send_ttl = cmd->ttl,
|
.send_ttl = cmd->ttl,
|
||||||
};
|
};
|
||||||
@ -619,6 +599,12 @@ static void net_send(u8_t *data, u16_t len)
|
|||||||
SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl,
|
SYS_LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl,
|
||||||
ctx.addr, cmd->payload_len);
|
ctx.addr, cmd->payload_len);
|
||||||
|
|
||||||
|
if (!bt_mesh_app_key_get(vnd_app_key_idx)) {
|
||||||
|
(void)bt_mesh_app_key_add(vnd_app_key_idx, net.net_idx,
|
||||||
|
vnd_app_key);
|
||||||
|
vnd_models[0].keys[0] = vnd_app_key_idx;
|
||||||
|
}
|
||||||
|
|
||||||
net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len);
|
net_buf_simple_add_mem(msg, cmd->payload, cmd->payload_len);
|
||||||
|
|
||||||
err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL);
|
err = bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL);
|
||||||
@ -632,13 +618,13 @@ static void net_send(u8_t *data, u16_t len)
|
|||||||
os_mbuf_free_chain(msg);
|
os_mbuf_free_chain(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void health_generate_faults(u8_t *data, u16_t len)
|
static void health_generate_faults(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_health_generate_faults_rp *rp;
|
struct mesh_health_generate_faults_rp *rp;
|
||||||
struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) +
|
struct os_mbuf *buf = NET_BUF_SIMPLE(sizeof(*rp) + sizeof(cur_faults) +
|
||||||
sizeof(reg_faults));
|
sizeof(reg_faults));
|
||||||
u8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 };
|
uint8_t some_faults[] = { 0x01, 0x02, 0x03, 0xff, 0x06 };
|
||||||
u8_t cur_faults_count, reg_faults_count;
|
uint8_t cur_faults_count, reg_faults_count;
|
||||||
|
|
||||||
rp = net_buf_simple_add(buf, sizeof(*rp));
|
rp = net_buf_simple_add(buf, sizeof(*rp));
|
||||||
|
|
||||||
@ -658,7 +644,7 @@ static void health_generate_faults(u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, buf);
|
CONTROLLER_INDEX, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void health_clear_faults(u8_t *data, u16_t len)
|
static void health_clear_faults(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("");
|
SYS_LOG_DBG("");
|
||||||
|
|
||||||
@ -671,7 +657,7 @@ static void health_clear_faults(u8_t *data, u16_t len)
|
|||||||
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void model_send(u8_t *data, u16_t len)
|
static void model_send(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_model_send_cmd *cmd = (void *) data;
|
struct mesh_model_send_cmd *cmd = (void *) data;
|
||||||
struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX);
|
struct os_mbuf *msg = NET_BUF_SIMPLE(UINT8_MAX);
|
||||||
@ -683,7 +669,7 @@ static void model_send(u8_t *data, u16_t len)
|
|||||||
};
|
};
|
||||||
struct bt_mesh_model *model = NULL;
|
struct bt_mesh_model *model = NULL;
|
||||||
int err, i;
|
int err, i;
|
||||||
u16_t src = sys_le16_to_cpu(cmd->src);
|
uint16_t src = sys_le16_to_cpu(cmd->src);
|
||||||
|
|
||||||
/* Lookup source address */
|
/* Lookup source address */
|
||||||
for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
|
for (i = 0; i < ARRAY_SIZE(model_bound); i++) {
|
||||||
@ -720,10 +706,10 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_MESH_TESTING)
|
#if MYNEWT_VAL(BLE_MESH_TESTING)
|
||||||
static void lpn_subscribe(u8_t *data, u16_t len)
|
static void lpn_subscribe(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_lpn_subscribe_cmd *cmd = (void *) data;
|
struct mesh_lpn_subscribe_cmd *cmd = (void *) data;
|
||||||
u16_t address = sys_le16_to_cpu(cmd->address);
|
uint16_t address = sys_le16_to_cpu(cmd->address);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("address 0x%04x", address);
|
SYS_LOG_DBG("address 0x%04x", address);
|
||||||
@ -737,10 +723,10 @@ static void lpn_subscribe(u8_t *data, u16_t len)
|
|||||||
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpn_unsubscribe(u8_t *data, u16_t len)
|
static void lpn_unsubscribe(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data;
|
struct mesh_lpn_unsubscribe_cmd *cmd = (void *) data;
|
||||||
u16_t address = sys_le16_to_cpu(cmd->address);
|
uint16_t address = sys_le16_to_cpu(cmd->address);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
SYS_LOG_DBG("address 0x%04x", address);
|
SYS_LOG_DBG("address 0x%04x", address);
|
||||||
@ -754,7 +740,7 @@ static void lpn_unsubscribe(u8_t *data, u16_t len)
|
|||||||
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpl_clear(u8_t *data, u16_t len)
|
static void rpl_clear(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -770,7 +756,7 @@ static void rpl_clear(u8_t *data, u16_t len)
|
|||||||
}
|
}
|
||||||
#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */
|
#endif /* MYNEWT_VAL(BLE_MESH_TESTING) */
|
||||||
|
|
||||||
static void proxy_identity_enable(u8_t *data, u16_t len)
|
static void proxy_identity_enable(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -785,7 +771,7 @@ static void proxy_identity_enable(u8_t *data, u16_t len)
|
|||||||
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
err ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_handle_mesh(u8_t opcode, u8_t index, u8_t *data, u16_t len)
|
void tester_handle_mesh(uint8_t opcode, uint8_t index, uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case MESH_READ_SUPPORTED_COMMANDS:
|
case MESH_READ_SUPPORTED_COMMANDS:
|
||||||
@ -854,7 +840,7 @@ void tester_handle_mesh(u8_t opcode, u8_t index, u8_t *data, u16_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_recv_ev(u8_t ttl, u8_t ctl, u16_t src, u16_t dst, const void *payload,
|
void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload,
|
||||||
size_t payload_len)
|
size_t payload_len)
|
||||||
{
|
{
|
||||||
struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX);
|
struct os_mbuf *buf = NET_BUF_SIMPLE(UINT8_MAX);
|
||||||
@ -883,8 +869,8 @@ done:
|
|||||||
os_mbuf_free_chain(buf);
|
os_mbuf_free_chain(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void model_bound_cb(u16_t addr, struct bt_mesh_model *model,
|
static void model_bound_cb(uint16_t addr, struct bt_mesh_model *model,
|
||||||
u16_t key_idx)
|
uint16_t key_idx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -904,8 +890,8 @@ static void model_bound_cb(u16_t addr, struct bt_mesh_model *model,
|
|||||||
SYS_LOG_ERR("model_bound is full");
|
SYS_LOG_ERR("model_bound is full");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void model_unbound_cb(u16_t addr, struct bt_mesh_model *model,
|
static void model_unbound_cb(uint16_t addr, struct bt_mesh_model *model,
|
||||||
u16_t key_idx)
|
uint16_t key_idx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -925,7 +911,7 @@ static void model_unbound_cb(u16_t addr, struct bt_mesh_model *model,
|
|||||||
SYS_LOG_INF("model not found");
|
SYS_LOG_INF("model not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invalid_bearer_cb(u8_t opcode)
|
static void invalid_bearer_cb(uint8_t opcode)
|
||||||
{
|
{
|
||||||
struct mesh_invalid_bearer_ev ev = {
|
struct mesh_invalid_bearer_ev ev = {
|
||||||
.opcode = opcode,
|
.opcode = opcode,
|
||||||
@ -934,7 +920,7 @@ static void invalid_bearer_cb(u8_t opcode)
|
|||||||
SYS_LOG_DBG("opcode 0x%02x", opcode);
|
SYS_LOG_DBG("opcode 0x%02x", opcode);
|
||||||
|
|
||||||
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER,
|
tester_send(BTP_SERVICE_ID_MESH, MESH_EV_INVALID_BEARER,
|
||||||
CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
|
CONTROLLER_INDEX, (uint8_t *) &ev, sizeof(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void incomp_timer_exp_cb(void)
|
static void incomp_timer_exp_cb(void)
|
||||||
@ -951,7 +937,7 @@ static struct bt_test_cb bt_test_cb = {
|
|||||||
.mesh_trans_incomp_timer_exp = incomp_timer_exp_cb,
|
.mesh_trans_incomp_timer_exp = incomp_timer_exp_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
u8_t tester_init_mesh(void)
|
uint8_t tester_init_mesh(void)
|
||||||
{
|
{
|
||||||
health_pub_init();
|
health_pub_init();
|
||||||
|
|
||||||
@ -962,7 +948,7 @@ u8_t tester_init_mesh(void)
|
|||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8_t tester_unregister_mesh(void)
|
uint8_t tester_unregister_mesh(void)
|
||||||
{
|
{
|
||||||
return BTP_STATUS_SUCCESS;
|
return BTP_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ static struct hal_timer rtt_timer;
|
|||||||
|
|
||||||
static bttester_pipe_recv_cb app_cb;
|
static bttester_pipe_recv_cb app_cb;
|
||||||
|
|
||||||
static u8_t *recv_buf;
|
static uint8_t *recv_buf;
|
||||||
static size_t recv_buf_len;
|
static size_t recv_buf_len;
|
||||||
static size_t recv_off;
|
static size_t recv_off;
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ rtt_pipe_poll_func(void *arg)
|
|||||||
itvl_ms = min(itvl_ms, RTT_INPUT_POLL_INTERVAL_MAX);
|
itvl_ms = min(itvl_ms, RTT_INPUT_POLL_INTERVAL_MAX);
|
||||||
} else {
|
} else {
|
||||||
while (key >= 0 && avail > 0) {
|
while (key >= 0 && avail > 0) {
|
||||||
recv_buf[recv_off] = (u8_t) key;
|
recv_buf[recv_off] = (uint8_t) key;
|
||||||
recv_off++;
|
recv_off++;
|
||||||
avail = recv_buf_len - recv_off;
|
avail = recv_buf_len - recv_off;
|
||||||
key = rtt_pipe_get_char((unsigned int) rtt_index_down);
|
key = rtt_pipe_get_char((unsigned int) rtt_index_down);
|
||||||
@ -93,14 +93,14 @@ rtt_pipe_poll_func(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bttester_pipe_send(const u8_t *data, int len)
|
bttester_pipe_send(const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
SEGGER_RTT_Write((unsigned int) rtt_index_up, data, (unsigned int) len);
|
SEGGER_RTT_Write((unsigned int) rtt_index_up, data, (unsigned int) len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bttester_pipe_register(u8_t *buf, size_t len, bttester_pipe_recv_cb cb)
|
bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb)
|
||||||
{
|
{
|
||||||
recv_buf = buf;
|
recv_buf = buf;
|
||||||
recv_buf_len = len;
|
recv_buf_len = len;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "bttester_pipe.h"
|
#include "bttester_pipe.h"
|
||||||
|
|
||||||
static u8_t *recv_buf;
|
static uint8_t *recv_buf;
|
||||||
static size_t recv_buf_len;
|
static size_t recv_buf_len;
|
||||||
static bttester_pipe_recv_cb app_cb;
|
static bttester_pipe_recv_cb app_cb;
|
||||||
static size_t recv_off;
|
static size_t recv_off;
|
||||||
@ -144,7 +144,7 @@ uart_console_rx_char(void *arg, uint8_t byte)
|
|||||||
static int
|
static int
|
||||||
uart_pipe_handle_char(int key)
|
uart_pipe_handle_char(int key)
|
||||||
{
|
{
|
||||||
recv_buf[recv_off] = (u8_t) key;
|
recv_buf[recv_off] = (uint8_t) key;
|
||||||
recv_off++;
|
recv_off++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -194,7 +194,7 @@ uart_console_rx_char_event(struct os_event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
bttester_pipe_send(const u8_t *data, int len)
|
bttester_pipe_send(const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ bttester_pipe_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bttester_pipe_register(u8_t *buf, size_t len, bttester_pipe_recv_cb cb)
|
bttester_pipe_register(uint8_t *buf, size_t len, bttester_pipe_recv_cb cb)
|
||||||
{
|
{
|
||||||
recv_buf = buf;
|
recv_buf = buf;
|
||||||
recv_buf_len = len;
|
recv_buf_len = len;
|
||||||
|
@ -53,7 +53,7 @@ syscfg.defs:
|
|||||||
|
|
||||||
BTTESTER_CONN_RETRY:
|
BTTESTER_CONN_RETRY:
|
||||||
description: Retry connections when connection failed to be established
|
description: Retry connections when connection failed to be established
|
||||||
value: 3
|
value: 0
|
||||||
|
|
||||||
BTTESTER_BTP_DATA_SIZE_MAX:
|
BTTESTER_BTP_DATA_SIZE_MAX:
|
||||||
description: Maximum BTP payload
|
description: Maximum BTP payload
|
||||||
@ -71,12 +71,16 @@ syscfg.defs:
|
|||||||
description: Enable logging BTP traffic
|
description: Enable logging BTP traffic
|
||||||
value: 0
|
value: 0
|
||||||
|
|
||||||
|
BTTESTER_L2CAP_COC_MTU:
|
||||||
|
description: Maximum MTU size the application can handle
|
||||||
|
value: 230
|
||||||
|
|
||||||
syscfg.vals:
|
syscfg.vals:
|
||||||
OS_MAIN_STACK_SIZE: 512
|
OS_MAIN_STACK_SIZE: 512
|
||||||
SHELL_TASK: 0
|
SHELL_TASK: 0
|
||||||
SHELL_NEWTMGR: 0
|
SHELL_NEWTMGR: 0
|
||||||
LOG_LEVEL: 12
|
LOG_LEVEL: 12
|
||||||
MSYS_1_BLOCK_COUNT: 48
|
MSYS_1_BLOCK_COUNT: 80
|
||||||
|
|
||||||
BLE_MONITOR_RTT: 1
|
BLE_MONITOR_RTT: 1
|
||||||
CONSOLE_RTT: 0
|
CONSOLE_RTT: 0
|
||||||
@ -86,6 +90,8 @@ syscfg.vals:
|
|||||||
|
|
||||||
BLE_L2CAP_COC_MAX_NUM: 2
|
BLE_L2CAP_COC_MAX_NUM: 2
|
||||||
BLE_L2CAP_SIG_MAX_PROCS: 2
|
BLE_L2CAP_SIG_MAX_PROCS: 2
|
||||||
|
BLE_L2CAP_ENHANCED_COC: 1
|
||||||
|
BLE_VERSION: 52
|
||||||
# Some testcases require MPS < MTU
|
# Some testcases require MPS < MTU
|
||||||
BLE_L2CAP_COC_MPS: 100
|
BLE_L2CAP_COC_MPS: 100
|
||||||
BLE_RPA_TIMEOUT: 30
|
BLE_RPA_TIMEOUT: 30
|
||||||
@ -98,6 +104,9 @@ syscfg.vals:
|
|||||||
BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9
|
BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: 9
|
||||||
BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30
|
BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: 30
|
||||||
BLE_SVC_GAP_PPCP_SUPERVISION_TMO: 2000
|
BLE_SVC_GAP_PPCP_SUPERVISION_TMO: 2000
|
||||||
|
BLE_SVC_GAP_APPEARANCE_WRITE_PERM: 0
|
||||||
|
BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: 0
|
||||||
|
BLE_STORE_CONFIG_PERSIST: 0
|
||||||
|
|
||||||
BLE_MESH: 1
|
BLE_MESH: 1
|
||||||
BLE_MESH_SHELL: 0
|
BLE_MESH_SHELL: 0
|
||||||
@ -117,6 +126,11 @@ syscfg.vals:
|
|||||||
BLE_MESH_FRIEND: 1
|
BLE_MESH_FRIEND: 1
|
||||||
BLE_MESH_CFG_CLI: 1
|
BLE_MESH_CFG_CLI: 1
|
||||||
BLE_MESH_RX_SDU_MAX: 110
|
BLE_MESH_RX_SDU_MAX: 110
|
||||||
|
BLE_MESH_HEALTH_CLI: 1
|
||||||
|
BLE_MESH_FRIEND_QUEUE_SIZE: 32
|
||||||
|
BLE_MESH_RX_SEG_MAX: 13
|
||||||
|
BLE_MESH_TX_SEG_MSG_COUNT: 2
|
||||||
|
BLE_MAX_CONNECTIONS: 8
|
||||||
|
|
||||||
BLE_MESH_ADV_BUF_COUNT: 20
|
BLE_MESH_ADV_BUF_COUNT: 20
|
||||||
BLE_MESH_TX_SEG_MAX: 6
|
BLE_MESH_TX_SEG_MAX: 6
|
||||||
|
34
src/libs/mynewt-nimble/apps/central/pkg.yml
Executable file
34
src/libs/mynewt-nimble/apps/central/pkg.yml
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
pkg.name: "apps/central"
|
||||||
|
pkg.type: app
|
||||||
|
pkg.description: "Basic central application"
|
||||||
|
pkg.author: "Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>"
|
||||||
|
|
||||||
|
pkg.deps:
|
||||||
|
- "@apache-mynewt-core/kernel/os"
|
||||||
|
- "@apache-mynewt-core/sys/console/full"
|
||||||
|
- "@apache-mynewt-core/sys/log/full"
|
||||||
|
- "@apache-mynewt-core/sys/stats/full"
|
||||||
|
- "@apache-mynewt-core/sys/log/modlog"
|
||||||
|
- "@apache-mynewt-nimble/nimble/host"
|
||||||
|
- "@apache-mynewt-nimble/nimble/host/util/"
|
||||||
|
- "@apache-mynewt-nimble/nimble/host/store/config"
|
||||||
|
- "@apache-mynewt-nimble/nimble/transport"
|
186
src/libs/mynewt-nimble/apps/central/src/main.c
Executable file
186
src/libs/mynewt-nimble/apps/central/src/main.c
Executable file
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 "sysinit/sysinit.h"
|
||||||
|
#include "os/os.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "host/ble_hs.h"
|
||||||
|
#include "host/util/util.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "log/log.h"
|
||||||
|
|
||||||
|
static uint8_t g_own_addr_type;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_app_set_addr(void)
|
||||||
|
{
|
||||||
|
ble_addr_t addr;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* generate new non-resolvable private address */
|
||||||
|
rc = ble_hs_id_gen_rnd(0, &addr);
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
|
/* set generated address */
|
||||||
|
rc = ble_hs_id_set_rnd(addr.val);
|
||||||
|
assert(rc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scan_event() calls scan(), so forward declaration is required */
|
||||||
|
static void scan(void);
|
||||||
|
|
||||||
|
/* connection has separate event handler from scan */
|
||||||
|
static int
|
||||||
|
conn_event(struct ble_gap_event *event, void *arg)
|
||||||
|
{
|
||||||
|
switch (event->type) {
|
||||||
|
case BLE_GAP_EVENT_CONNECT:
|
||||||
|
if (event->connect.status == 0) {
|
||||||
|
MODLOG_DFLT(INFO,"Connection was established\n");
|
||||||
|
ble_gap_terminate(event->connect.conn_handle, 0x13);
|
||||||
|
} else {
|
||||||
|
MODLOG_DFLT(INFO,"Connection failed, error code: %i\n",
|
||||||
|
event->connect.status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BLE_GAP_EVENT_DISCONNECT:
|
||||||
|
MODLOG_DFLT(INFO,"Disconnected, reason code: %i\n",
|
||||||
|
event->disconnect.reason);
|
||||||
|
scan();
|
||||||
|
break;
|
||||||
|
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||||
|
MODLOG_DFLT(INFO,"Connection update request received\n");
|
||||||
|
break;
|
||||||
|
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||||
|
if (event->conn_update.status == 0) {
|
||||||
|
MODLOG_DFLT(INFO,"Connection update successful\n");
|
||||||
|
} else {
|
||||||
|
MODLOG_DFLT(INFO,"Connection update failed; reson: %d\n",
|
||||||
|
event->conn_update.status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MODLOG_DFLT(INFO,"Connection event type not supported, %d\n",
|
||||||
|
event->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
scan_event(struct ble_gap_event *event, void *arg)
|
||||||
|
{
|
||||||
|
/* predef_uuid stores information about UUID of device,
|
||||||
|
that we connect to */
|
||||||
|
const ble_uuid128_t predef_uuid =
|
||||||
|
BLE_UUID128_INIT(0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||||
|
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff);
|
||||||
|
struct ble_hs_adv_fields parsed_fields;
|
||||||
|
int uuid_cmp_result;
|
||||||
|
|
||||||
|
memset(&parsed_fields, 0, sizeof(parsed_fields));
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
/* advertising report has been received during discovery procedure */
|
||||||
|
case BLE_GAP_EVENT_DISC:
|
||||||
|
MODLOG_DFLT(INFO, "Advertising report received! Checking UUID...\n");
|
||||||
|
ble_hs_adv_parse_fields(&parsed_fields, event->disc.data,
|
||||||
|
event->disc.length_data);
|
||||||
|
/* Predefined UUID is compared to recieved one;
|
||||||
|
if doesn't fit - end procedure and go back to scanning,
|
||||||
|
else - connect. */
|
||||||
|
uuid_cmp_result = ble_uuid_cmp(&predef_uuid.u, &parsed_fields.uuids128->u);
|
||||||
|
if (uuid_cmp_result) {
|
||||||
|
MODLOG_DFLT(INFO, "UUID doesn't fit\n");
|
||||||
|
} else {
|
||||||
|
MODLOG_DFLT(INFO, "UUID fits, connecting...\n");
|
||||||
|
ble_gap_disc_cancel();
|
||||||
|
ble_gap_connect(g_own_addr_type, &(event->disc.addr), 10000,
|
||||||
|
NULL, conn_event, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BLE_GAP_EVENT_DISC_COMPLETE:
|
||||||
|
MODLOG_DFLT(INFO,"Discovery completed, reason: %d\n",
|
||||||
|
event->disc_complete.reason);
|
||||||
|
scan();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MODLOG_DFLT(ERROR, "Discovery event not handled\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scan(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* set scan parameters:
|
||||||
|
- scan interval in 0.625ms units
|
||||||
|
- scan window in 0.625ms units
|
||||||
|
- filter policy - 0 if whitelisting not used
|
||||||
|
- limited - should limited discovery be used
|
||||||
|
- passive - should passive scan be used
|
||||||
|
- filter duplicates - 1 enables filtering duplicated advertisements */
|
||||||
|
const struct ble_gap_disc_params scan_params = {10000, 200, 0, 0, 0, 1};
|
||||||
|
|
||||||
|
/* performs discovery procedure */
|
||||||
|
rc = ble_gap_disc(g_own_addr_type, 10000, &scan_params,scan_event, NULL);
|
||||||
|
assert(rc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_sync(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
/* Generate a non-resolvable private address. */
|
||||||
|
ble_app_set_addr();
|
||||||
|
|
||||||
|
/* g_own_addr_type will store type of addres our BSP uses */
|
||||||
|
|
||||||
|
rc = ble_hs_util_ensure_addr(0);
|
||||||
|
rc = ble_hs_id_infer_auto(0, &g_own_addr_type);
|
||||||
|
assert(rc == 0);
|
||||||
|
/* begin scanning */
|
||||||
|
scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_reset(int reason)
|
||||||
|
{
|
||||||
|
console_printf("Resetting state; reason=%d\n", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Initialize all packages. */
|
||||||
|
sysinit();
|
||||||
|
|
||||||
|
ble_hs_cfg.sync_cb = on_sync;
|
||||||
|
ble_hs_cfg.reset_cb = on_reset;
|
||||||
|
|
||||||
|
/* As the last thing, process events from default event queue. */
|
||||||
|
while (1) {
|
||||||
|
os_eventq_run(os_eventq_dflt_get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
48
src/libs/mynewt-nimble/apps/mesh_badge/README.md
Normal file
48
src/libs/mynewt-nimble/apps/mesh_badge/README.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
### Mesh Badge
|
||||||
|
|
||||||
|
|
||||||
|
##### Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
This sample app for the reel board showcases Bluetooth Mesh
|
||||||
|
|
||||||
|
The app starts off as a regular Bluetooth GATT peripheral application.
|
||||||
|
Install the the "nRF Connect" app on your phone (available both for
|
||||||
|
Android and iOS) to access the service that the app exposes. The service
|
||||||
|
can also be accessed with any Bluetooth LE GATT client from your PC,
|
||||||
|
however these instructions focus on the necessary steps for phones.
|
||||||
|
|
||||||
|
##### Steps to set up
|
||||||
|
***************
|
||||||
|
|
||||||
|
* On your phone, use the nRF Connect app to Scan for devices and look
|
||||||
|
for "reel board"
|
||||||
|
* Connect to the device. You'll see a single service - select it
|
||||||
|
* Request to write to the characteristic by pressing on the upward pointing
|
||||||
|
arrow symbol
|
||||||
|
* Select "Text" to enter text instead of hex
|
||||||
|
* Enter your name (or any other arbitrary text). Multiple words
|
||||||
|
separated by spaces are possible. The font used on the reel display
|
||||||
|
allows three rows of up to 12 characters
|
||||||
|
wide text. You can force line breaks with a comma.
|
||||||
|
* Press "Send" - this will trigger pairing since this is a protected
|
||||||
|
characteristic. The passkey for the pairing will be shown on the board's
|
||||||
|
display. Enter the passkey in your phone.
|
||||||
|
* Once pairing is complete the board will show the text you sent. If
|
||||||
|
you're not happy with it you can try writing something else.
|
||||||
|
* When you're happy with the text, disconnect from the board (exit the app or
|
||||||
|
go back to the device scan page)
|
||||||
|
* Once disconnected the board switches over to Bluetooth Mesh mode, and you
|
||||||
|
can't connect to it anymore over GATT.
|
||||||
|
|
||||||
|
If you configure multiple boards like this they can communicate with
|
||||||
|
each other over mesh: by pressing the user button on the board the first
|
||||||
|
word (name) of the stored text will be sent to all other boards in
|
||||||
|
the network and cause the other boards to display "<name> says hi!".
|
||||||
|
|
||||||
|
To reset a board to its initial state (disable mesh, erase the stored
|
||||||
|
text, and make it connectable over GATT):
|
||||||
|
|
||||||
|
* Keep the user button pressed when powering on (or press the reset button
|
||||||
|
when powered)
|
||||||
|
* Wait until "Reseting Device" is shown
|
39
src/libs/mynewt-nimble/apps/mesh_badge/pkg.yml
Normal file
39
src/libs/mynewt-nimble/apps/mesh_badge/pkg.yml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
pkg.name: apps/mesh_badge
|
||||||
|
pkg.type: app
|
||||||
|
pkg.description: Sample app for the reel board that showcases Bluetooth Mesh
|
||||||
|
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||||
|
pkg.homepage: "http://mynewt.apache.org/"
|
||||||
|
pkg.keywords:
|
||||||
|
|
||||||
|
pkg.deps:
|
||||||
|
- "@apache-mynewt-core/hw/drivers/display/cfb"
|
||||||
|
- "@apache-mynewt-core/hw/drivers/display/ssd1673"
|
||||||
|
- "@apache-mynewt-core/kernel/os"
|
||||||
|
- "@apache-mynewt-core/sys/console/full"
|
||||||
|
- "@apache-mynewt-core/sys/log/full"
|
||||||
|
- "@apache-mynewt-core/sys/log/modlog"
|
||||||
|
- "@apache-mynewt-core/sys/stats/full"
|
||||||
|
- "@apache-mynewt-core/sys/shell"
|
||||||
|
- nimble/controller
|
||||||
|
- nimble/host
|
||||||
|
- nimble/host/services/gap
|
||||||
|
- nimble/host/services/gatt
|
||||||
|
- nimble/host/store/config
|
||||||
|
- nimble/transport/ram
|
15
src/libs/mynewt-nimble/apps/mesh_badge/src/board.h
Normal file
15
src/libs/mynewt-nimble/apps/mesh_badge/src/board.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Phytec Messtechnik GmbH
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mesh/mesh.h"
|
||||||
|
|
||||||
|
void board_refresh_display(void);
|
||||||
|
void board_show_text(const char *text, bool center, int32_t duration);
|
||||||
|
void board_blink_leds(void);
|
||||||
|
void board_add_hello(uint16_t addr, const char *name);
|
||||||
|
void board_add_heartbeat(uint16_t addr, uint8_t hops);
|
||||||
|
int board_init(void);
|
226
src/libs/mynewt-nimble/apps/mesh_badge/src/gatt_svr.c
Normal file
226
src/libs/mynewt-nimble/apps/mesh_badge/src/gatt_svr.c
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
#include "bsp/bsp.h"
|
||||||
|
#include "host/ble_hs.h"
|
||||||
|
#include "host/ble_uuid.h"
|
||||||
|
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "board.h"
|
||||||
|
#include "mesh_badge.h"
|
||||||
|
|
||||||
|
static const ble_uuid16_t gatt_cud_uuid = BLE_UUID16_INIT(0x2901);
|
||||||
|
static const ble_uuid16_t gatt_cpf_uuid = BLE_UUID16_INIT(0x2904);
|
||||||
|
|
||||||
|
/** @brief GATT Characteristic Presentation Format Attribute Value. */
|
||||||
|
struct bt_gatt_cpf {
|
||||||
|
/** Format of the value of the characteristic */
|
||||||
|
uint8_t format;
|
||||||
|
/** Exponent field to determine how the value of this characteristic is further formatted */
|
||||||
|
int8_t exponent;
|
||||||
|
/** Unit of the characteristic */
|
||||||
|
uint16_t unit;
|
||||||
|
/** Name space of the description */
|
||||||
|
uint8_t name_space;
|
||||||
|
/** Description of the characteristic as defined in a higher layer profile */
|
||||||
|
uint16_t description;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#define CPF_FORMAT_UTF8 0x19
|
||||||
|
|
||||||
|
static const struct bt_gatt_cpf name_cpf = {
|
||||||
|
.format = CPF_FORMAT_UTF8,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ble_uuid128_t name_uuid = BLE_UUID128_INIT(
|
||||||
|
0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
|
||||||
|
0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);
|
||||||
|
|
||||||
|
static const ble_uuid128_t name_enc_uuid = BLE_UUID128_INIT(
|
||||||
|
0xf1, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
|
||||||
|
0x78, 0x56, 0x34, 0x12, 0x78, 0x56, 0x34, 0x12);
|
||||||
|
|
||||||
|
static int
|
||||||
|
gatt_svr_chr_access(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[] = {
|
||||||
|
{
|
||||||
|
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||||
|
.uuid = &name_uuid.u,
|
||||||
|
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||||
|
.uuid = &name_enc_uuid.u,
|
||||||
|
.access_cb = gatt_svr_chr_access,
|
||||||
|
.flags = BLE_GATT_CHR_F_READ |
|
||||||
|
BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
|
||||||
|
.descriptors = (struct ble_gatt_dsc_def[]) { {
|
||||||
|
.uuid = &gatt_cud_uuid.u,
|
||||||
|
.access_cb = gatt_svr_chr_access,
|
||||||
|
.att_flags = BLE_ATT_F_READ,
|
||||||
|
}, {
|
||||||
|
.uuid = &gatt_cpf_uuid.u,
|
||||||
|
.access_cb = gatt_svr_chr_access,
|
||||||
|
.att_flags = BLE_ATT_F_READ,
|
||||||
|
}, {
|
||||||
|
0, /* No more descriptors in this characteristic. */
|
||||||
|
} }
|
||||||
|
}, {
|
||||||
|
0, /* No more characteristics in this service. */
|
||||||
|
} },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
0, /* No more services. */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int read_name(struct os_mbuf *om)
|
||||||
|
{
|
||||||
|
const char *value = bt_get_name();
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = os_mbuf_append(om, value, (uint16_t) strlen(value));
|
||||||
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_name(struct os_mbuf *om)
|
||||||
|
{
|
||||||
|
char name[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH)];
|
||||||
|
uint16_t len;
|
||||||
|
uint16_t om_len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
om_len = OS_MBUF_PKTLEN(om);
|
||||||
|
if (om_len >= sizeof(name)) {
|
||||||
|
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ble_hs_mbuf_to_flat(om, name, sizeof(name) - 1, &len);
|
||||||
|
if (rc != 0) {
|
||||||
|
return BLE_ATT_ERR_UNLIKELY;
|
||||||
|
}
|
||||||
|
|
||||||
|
name[len] = '\0';
|
||||||
|
|
||||||
|
rc = bt_set_name(name);
|
||||||
|
if (rc) {
|
||||||
|
return BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
|
}
|
||||||
|
|
||||||
|
board_refresh_display();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gatt_svr_chr_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||||
|
struct ble_gatt_access_ctxt *ctxt,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
const ble_uuid_t *uuid;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
uuid = ctxt->chr->uuid;
|
||||||
|
|
||||||
|
if (ble_uuid_cmp(uuid, &name_enc_uuid.u) == 0) {
|
||||||
|
switch (ctxt->op) {
|
||||||
|
case BLE_GATT_ACCESS_OP_READ_CHR:
|
||||||
|
rc = read_name(ctxt->om);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
case BLE_GATT_ACCESS_OP_WRITE_CHR:
|
||||||
|
rc = write_name(ctxt->om);
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return BLE_ATT_ERR_UNLIKELY;
|
||||||
|
}
|
||||||
|
} else if (ble_uuid_cmp(uuid, &gatt_cud_uuid.u) == 0) {
|
||||||
|
rc = os_mbuf_append(ctxt->om, "Badge Name",
|
||||||
|
(uint16_t) strlen("Badge Name"));
|
||||||
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
|
} else if (ble_uuid_cmp(uuid, &gatt_cpf_uuid.u) == 0) {
|
||||||
|
rc = os_mbuf_append(ctxt->om, &name_cpf,
|
||||||
|
(uint16_t) sizeof(name_cpf));
|
||||||
|
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown characteristic; the nimble stack should not have called this
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
assert(0);
|
||||||
|
return BLE_ATT_ERR_UNLIKELY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
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:
|
||||||
|
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
|
||||||
|
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
|
||||||
|
ctxt->svc.handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BLE_GATT_REGISTER_OP_CHR:
|
||||||
|
MODLOG_DFLT(DEBUG, "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:
|
||||||
|
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
|
||||||
|
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
|
||||||
|
ctxt->dsc.handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gatt_svr_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
393
src/libs/mynewt-nimble/apps/mesh_badge/src/main.c
Normal file
393
src/libs/mynewt-nimble/apps/mesh_badge/src/main.c
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "host/ble_gap.h"
|
||||||
|
#include "mesh/glue.h"
|
||||||
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
#include "base64/base64.h"
|
||||||
|
|
||||||
|
#include "mesh_badge.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
static char badge_name[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH)];
|
||||||
|
|
||||||
|
#define MESH_BADGE_NAME_ENCODE_SIZE \
|
||||||
|
BASE64_ENCODE_SIZE(sizeof(badge_name))
|
||||||
|
|
||||||
|
static bool reset_mesh;
|
||||||
|
|
||||||
|
void print_addr(const void *addr)
|
||||||
|
{
|
||||||
|
const uint8_t *u8p;
|
||||||
|
|
||||||
|
u8p = addr;
|
||||||
|
MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_conn_desc(struct ble_gap_conn_desc *desc)
|
||||||
|
{
|
||||||
|
MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
|
||||||
|
desc->conn_handle, desc->our_ota_addr.type);
|
||||||
|
print_addr(desc->our_ota_addr.val);
|
||||||
|
MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
|
||||||
|
desc->our_id_addr.type);
|
||||||
|
print_addr(desc->our_id_addr.val);
|
||||||
|
MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
|
||||||
|
desc->peer_ota_addr.type);
|
||||||
|
print_addr(desc->peer_ota_addr.val);
|
||||||
|
MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
|
||||||
|
desc->peer_id_addr.type);
|
||||||
|
print_addr(desc->peer_id_addr.val);
|
||||||
|
MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
|
||||||
|
"encrypted=%d authenticated=%d bonded=%d\n",
|
||||||
|
desc->conn_itvl, desc->conn_latency,
|
||||||
|
desc->supervision_timeout,
|
||||||
|
desc->sec_state.encrypted,
|
||||||
|
desc->sec_state.authenticated,
|
||||||
|
desc->sec_state.bonded);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gap_event(struct ble_gap_event *event, void *arg);
|
||||||
|
|
||||||
|
static void advertise(void)
|
||||||
|
{
|
||||||
|
uint8_t own_addr_type;
|
||||||
|
struct ble_gap_adv_params adv_params;
|
||||||
|
struct ble_hs_adv_fields fields;
|
||||||
|
const char *name;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Figure out address to use while advertising (no privacy for now) */
|
||||||
|
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||||
|
if (rc != 0) {
|
||||||
|
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Indicate that the TX power level field should be included; have the
|
||||||
|
* stack fill this value automatically. This is done by assiging 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;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
name = ble_svc_gap_device_name();
|
||||||
|
fields.name = (uint8_t *)name;
|
||||||
|
fields.name_len = (uint8_t) strlen(name);
|
||||||
|
fields.name_is_complete = 1;
|
||||||
|
|
||||||
|
rc = ble_gap_adv_set_fields(&fields);
|
||||||
|
if (rc != 0) {
|
||||||
|
MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", 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, gap_event, NULL);
|
||||||
|
if (rc != 0) {
|
||||||
|
MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void passkey_display(uint16_t conn_handle)
|
||||||
|
{
|
||||||
|
char buf[20];
|
||||||
|
struct ble_sm_io pk;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
bt_rand(&pk.passkey, sizeof(pk.passkey));
|
||||||
|
/* Max value is 999999 */
|
||||||
|
pk.passkey %= 1000000;
|
||||||
|
pk.action = BLE_SM_IOACT_DISP;
|
||||||
|
|
||||||
|
rc = ble_sm_inject_io(conn_handle, &pk);
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
|
snprintk(buf, sizeof(buf), "Passkey:\n%06lu", pk.passkey);
|
||||||
|
|
||||||
|
printk("%s\n", buf);
|
||||||
|
board_show_text(buf, false, K_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pairing_complete(uint16_t conn_handle, bool bonded)
|
||||||
|
{
|
||||||
|
printk("Pairing Complete\n");
|
||||||
|
board_show_text("Pairing Complete", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pairing_failed(uint16_t conn_handle)
|
||||||
|
{
|
||||||
|
printk("Pairing Failed\n");
|
||||||
|
board_show_text("Pairing Failed", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void connected(uint16_t conn_handle, int err)
|
||||||
|
{
|
||||||
|
printk("Connected (err 0x%02x)\n", err);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
board_show_text("Connection failed", false, K_SECONDS(2));
|
||||||
|
} else {
|
||||||
|
board_show_text("Connected", false, K_FOREVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disconnected(uint16_t conn_handle, int reason)
|
||||||
|
{
|
||||||
|
printk("Disconnected (reason 0x%02x)\n", reason);
|
||||||
|
|
||||||
|
if (strcmp(MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME), bt_get_name()) != 0 &&
|
||||||
|
!mesh_is_initialized()) {
|
||||||
|
/* Mesh will take over advertising control */
|
||||||
|
ble_gap_adv_stop();
|
||||||
|
mesh_start();
|
||||||
|
} else {
|
||||||
|
board_show_text("Disconnected", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int 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. */
|
||||||
|
MODLOG_DFLT(INFO, "connection %s; status=%d ",
|
||||||
|
event->connect.status == 0 ? "established" : "failed",
|
||||||
|
event->connect.status);
|
||||||
|
if (event->connect.status == 0) {
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
print_conn_desc(&desc);
|
||||||
|
connected(event->connect.conn_handle,
|
||||||
|
event->connect.status);
|
||||||
|
}
|
||||||
|
MODLOG_DFLT(INFO, "\n");
|
||||||
|
|
||||||
|
if (event->connect.status != 0) {
|
||||||
|
/* Connection failed; resume advertising. */
|
||||||
|
advertise();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_DISCONNECT:
|
||||||
|
MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
|
||||||
|
print_conn_desc(&event->disconnect.conn);
|
||||||
|
MODLOG_DFLT(INFO, "\n");
|
||||||
|
|
||||||
|
/* Connection terminated; resume advertising. */
|
||||||
|
advertise();
|
||||||
|
|
||||||
|
disconnected(event->disconnect.conn.conn_handle,
|
||||||
|
event->disconnect.reason);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_CONN_UPDATE:
|
||||||
|
/* The central has updated the connection parameters. */
|
||||||
|
MODLOG_DFLT(INFO, "connection updated; status=%d ",
|
||||||
|
event->conn_update.status);
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
print_conn_desc(&desc);
|
||||||
|
MODLOG_DFLT(INFO, "\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_ENC_CHANGE:
|
||||||
|
/* Encryption has been enabled or disabled for this connection. */
|
||||||
|
MODLOG_DFLT(INFO, "encryption change event; status=%d ",
|
||||||
|
event->enc_change.status);
|
||||||
|
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
print_conn_desc(&desc);
|
||||||
|
MODLOG_DFLT(INFO, "\n");
|
||||||
|
|
||||||
|
if (desc.sec_state.bonded) {
|
||||||
|
pairing_complete(event->enc_change.conn_handle, true);
|
||||||
|
} else if(desc.sec_state.encrypted) {
|
||||||
|
pairing_complete(event->enc_change.conn_handle, false);
|
||||||
|
} else {
|
||||||
|
pairing_failed(event->enc_change.conn_handle);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_PASSKEY_ACTION:
|
||||||
|
MODLOG_DFLT(INFO, "passkey action event; conn_handle=%d action=%d numcmp=%d\n",
|
||||||
|
event->passkey.conn_handle,
|
||||||
|
event->passkey.params.action,
|
||||||
|
event->passkey.params.numcmp);
|
||||||
|
passkey_display(event->passkey.conn_handle);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case BLE_GAP_EVENT_REPEAT_PAIRING:
|
||||||
|
/* We already have a bond with the peer, but it is attempting to
|
||||||
|
* establish a new secure link. This app sacrifices security for
|
||||||
|
* convenience: just throw away the old bond and accept the new link.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Delete the old bond. */
|
||||||
|
rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
|
||||||
|
assert(rc == 0);
|
||||||
|
ble_store_util_delete_peer(&desc.peer_id_addr);
|
||||||
|
|
||||||
|
/* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
|
||||||
|
* continue with the pairing operation.
|
||||||
|
*/
|
||||||
|
return BLE_GAP_REPEAT_PAIRING_RETRY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_sync(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
ble_addr_t addr;
|
||||||
|
|
||||||
|
/* Use NRPA */
|
||||||
|
err = ble_hs_id_gen_rnd(1, &addr);
|
||||||
|
assert(err == 0);
|
||||||
|
err = ble_hs_id_set_rnd(addr.val);
|
||||||
|
assert(err == 0);
|
||||||
|
|
||||||
|
printk("Bluetooth initialized\n");
|
||||||
|
|
||||||
|
err = mesh_init(addr.type);
|
||||||
|
if (err) {
|
||||||
|
printk("Initializing mesh failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("Mesh initialized\n");
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
||||||
|
settings_load();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset_mesh) {
|
||||||
|
bt_mesh_reset();
|
||||||
|
reset_mesh = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mesh_is_initialized()) {
|
||||||
|
advertise();
|
||||||
|
} else {
|
||||||
|
printk("Already provisioned\n");
|
||||||
|
ble_svc_gap_device_name_set(bt_get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
board_refresh_display();
|
||||||
|
|
||||||
|
printk("Board started\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void schedule_mesh_reset(void)
|
||||||
|
{
|
||||||
|
reset_mesh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_reset(int reason)
|
||||||
|
{
|
||||||
|
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *bt_get_name(void)
|
||||||
|
{
|
||||||
|
char buf[MESH_BADGE_NAME_ENCODE_SIZE];
|
||||||
|
int rc, len;
|
||||||
|
|
||||||
|
rc = conf_get_stored_value("mesh_badge/badge_name",
|
||||||
|
buf, sizeof(buf));
|
||||||
|
if (rc == OS_ENOENT) {
|
||||||
|
bt_set_name(MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME));
|
||||||
|
} else {
|
||||||
|
assert(rc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(badge_name, '\0', sizeof(badge_name));
|
||||||
|
len = base64_decode(buf, badge_name);
|
||||||
|
if (len < 0) {
|
||||||
|
bt_set_name(MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
return badge_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_set_name(const char *name)
|
||||||
|
{
|
||||||
|
char buf[MESH_BADGE_NAME_ENCODE_SIZE];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(badge_name, '\0', sizeof(badge_name));
|
||||||
|
memcpy(badge_name, name, strlen(name));
|
||||||
|
base64_encode(badge_name, sizeof(badge_name), buf, 1);
|
||||||
|
rc = conf_save_one("mesh_badge/badge_name", buf);
|
||||||
|
assert(rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Initialize OS */
|
||||||
|
sysinit();
|
||||||
|
|
||||||
|
err = board_init();
|
||||||
|
if (err) {
|
||||||
|
printk("board init failed (err %d)\n", err);
|
||||||
|
assert(err == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the NimBLE host configuration. */
|
||||||
|
ble_hs_cfg.reset_cb = on_reset;
|
||||||
|
ble_hs_cfg.sync_cb = on_sync;
|
||||||
|
ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
|
||||||
|
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||||
|
ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY;
|
||||||
|
|
||||||
|
err = gatt_svr_init();
|
||||||
|
assert(err == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As the last thing, process events from default event queue.
|
||||||
|
*/
|
||||||
|
while (1) {
|
||||||
|
os_eventq_run(os_eventq_dflt_get());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
313
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh.c
Normal file
313
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "mesh/mesh.h"
|
||||||
|
|
||||||
|
#include "mesh_badge.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#define BT_COMP_ID_LF 0x05f1
|
||||||
|
|
||||||
|
#define MOD_LF 0x0000
|
||||||
|
#define OP_HELLO 0xbb
|
||||||
|
#define OP_HEARTBEAT 0xbc
|
||||||
|
#define OP_VND_HELLO BT_MESH_MODEL_OP_3(OP_HELLO, BT_COMP_ID_LF)
|
||||||
|
#define OP_VND_HEARTBEAT BT_MESH_MODEL_OP_3(OP_HEARTBEAT, BT_COMP_ID_LF)
|
||||||
|
|
||||||
|
#define DEFAULT_TTL 31
|
||||||
|
#define GROUP_ADDR 0xc123
|
||||||
|
#define NET_IDX 0x000
|
||||||
|
#define APP_IDX 0x000
|
||||||
|
#define FLAGS 0
|
||||||
|
static struct ble_npl_callout hello_work;
|
||||||
|
static struct ble_npl_callout mesh_start_work;
|
||||||
|
|
||||||
|
static void heartbeat(const struct bt_mesh_hb_sub *sub, uint8_t hops,
|
||||||
|
uint16_t feat)
|
||||||
|
{
|
||||||
|
board_show_text("Heartbeat Received", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bt_mesh_cfg_cli cfg_cli = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static void attention_on(struct bt_mesh_model *model)
|
||||||
|
{
|
||||||
|
board_show_text("Attention!", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void attention_off(struct bt_mesh_model *model)
|
||||||
|
{
|
||||||
|
board_refresh_display();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bt_mesh_health_srv_cb health_srv_cb = {
|
||||||
|
.attn_on = attention_on,
|
||||||
|
.attn_off = attention_off,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_mesh_health_srv health_srv = {
|
||||||
|
.cb = &health_srv_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct os_mbuf *bt_mesh_pub_msg_health_pub;
|
||||||
|
static struct bt_mesh_model_pub health_pub;
|
||||||
|
|
||||||
|
static struct bt_mesh_model root_models[] = {
|
||||||
|
BT_MESH_MODEL_CFG_SRV,
|
||||||
|
BT_MESH_MODEL_CFG_CLI(&cfg_cli),
|
||||||
|
BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void vnd_hello(struct bt_mesh_model *model,
|
||||||
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
|
struct os_mbuf *buf)
|
||||||
|
{
|
||||||
|
char str[32];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
printk("Hello message from 0x%04x\n", ctx->addr);
|
||||||
|
|
||||||
|
if (ctx->addr == bt_mesh_model_elem(model)->addr) {
|
||||||
|
printk("Ignoring message from self\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = min(buf->om_len, 8);
|
||||||
|
memcpy(str, buf->om_data, len);
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
board_add_hello(ctx->addr, str);
|
||||||
|
|
||||||
|
strcpy(str + len, " says hi!");
|
||||||
|
|
||||||
|
board_show_text(str, false, K_SECONDS(3));
|
||||||
|
|
||||||
|
board_blink_leds();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vnd_heartbeat(struct bt_mesh_model *model,
|
||||||
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
|
struct os_mbuf *buf)
|
||||||
|
{
|
||||||
|
uint8_t init_ttl, hops;
|
||||||
|
|
||||||
|
/* Ignore messages from self */
|
||||||
|
if (ctx->addr == bt_mesh_model_elem(model)->addr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_ttl = net_buf_simple_pull_u8(buf);
|
||||||
|
hops = init_ttl - ctx->recv_ttl + 1;
|
||||||
|
|
||||||
|
printk("Heartbeat from 0x%04x over %u hop%s\n", ctx->addr,
|
||||||
|
hops, hops == 1 ? "" : "s");
|
||||||
|
|
||||||
|
board_add_heartbeat(ctx->addr, hops);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bt_mesh_model_op vnd_ops[] = {
|
||||||
|
{ OP_VND_HELLO, 1, vnd_hello },
|
||||||
|
{ OP_VND_HEARTBEAT, 1, vnd_heartbeat },
|
||||||
|
BT_MESH_MODEL_OP_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pub_update(struct bt_mesh_model *mod)
|
||||||
|
{
|
||||||
|
struct os_mbuf *msg = mod->pub->msg;
|
||||||
|
|
||||||
|
printk("Preparing to send heartbeat\n");
|
||||||
|
|
||||||
|
bt_mesh_model_msg_init(msg, OP_VND_HEARTBEAT);
|
||||||
|
net_buf_simple_add_u8(msg, DEFAULT_TTL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct os_mbuf *bt_mesh_pub_msg_vnd_pub;
|
||||||
|
static struct bt_mesh_model_pub vnd_pub;
|
||||||
|
|
||||||
|
static struct bt_mesh_model vnd_models[] = {
|
||||||
|
BT_MESH_MODEL_VND(BT_COMP_ID_LF, MOD_LF, vnd_ops, &vnd_pub, NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_mesh_elem elements[] = {
|
||||||
|
BT_MESH_ELEM(0, root_models, vnd_models),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct bt_mesh_comp comp = {
|
||||||
|
.cid = BT_COMP_ID_LF,
|
||||||
|
.elem = elements,
|
||||||
|
.elem_count = ARRAY_SIZE(elements),
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t first_name_len(const char *name)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (len = 0; *name; name++, len++) {
|
||||||
|
switch (*name) {
|
||||||
|
case ' ':
|
||||||
|
case ',':
|
||||||
|
case '\n':
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_hello(struct ble_npl_event *work)
|
||||||
|
{
|
||||||
|
struct os_mbuf *msg = NET_BUF_SIMPLE(3 + 8 + 4);
|
||||||
|
struct bt_mesh_msg_ctx ctx = {
|
||||||
|
.net_idx = NET_IDX,
|
||||||
|
.app_idx = APP_IDX,
|
||||||
|
.addr = GROUP_ADDR,
|
||||||
|
.send_ttl = DEFAULT_TTL,
|
||||||
|
};
|
||||||
|
const char *name = bt_get_name();
|
||||||
|
|
||||||
|
bt_mesh_model_msg_init(msg, OP_VND_HELLO);
|
||||||
|
net_buf_simple_add_mem(msg, name, first_name_len(name));
|
||||||
|
|
||||||
|
if (bt_mesh_model_send(&vnd_models[0], &ctx, msg, NULL, NULL) == 0) {
|
||||||
|
board_show_text("Saying \"hi!\" to everyone", false,
|
||||||
|
K_SECONDS(2));
|
||||||
|
} else {
|
||||||
|
board_show_text("Sending Failed!", false, K_SECONDS(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mbuf_free_chain(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh_send_hello(void)
|
||||||
|
{
|
||||||
|
k_work_submit(&hello_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int provision_and_configure(void)
|
||||||
|
{
|
||||||
|
static const uint8_t net_key[16] = {
|
||||||
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
||||||
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
||||||
|
};
|
||||||
|
static const uint8_t app_key[16] = {
|
||||||
|
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||||
|
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||||
|
};
|
||||||
|
static const uint16_t iv_index;
|
||||||
|
struct bt_mesh_cfg_mod_pub pub = {
|
||||||
|
.addr = GROUP_ADDR,
|
||||||
|
.app_idx = APP_IDX,
|
||||||
|
.ttl = DEFAULT_TTL,
|
||||||
|
.period = BT_MESH_PUB_PERIOD_SEC(10),
|
||||||
|
};
|
||||||
|
uint8_t dev_key[16];
|
||||||
|
uint16_t addr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = bt_rand(dev_key, sizeof(dev_key));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = bt_rand(&addr, sizeof(addr));
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} while (!addr);
|
||||||
|
|
||||||
|
/* Make sure it's a unicast address (highest bit unset) */
|
||||||
|
addr &= ~0x8000;
|
||||||
|
|
||||||
|
err = bt_mesh_provision(net_key, NET_IDX, FLAGS, iv_index, addr,
|
||||||
|
dev_key);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("Configuring...\n");
|
||||||
|
|
||||||
|
/* Add Application Key */
|
||||||
|
bt_mesh_cfg_app_key_add(NET_IDX, addr, NET_IDX, APP_IDX, app_key, NULL);
|
||||||
|
|
||||||
|
/* Bind to vendor model */
|
||||||
|
bt_mesh_cfg_mod_app_bind_vnd(NET_IDX, addr, addr, APP_IDX,
|
||||||
|
MOD_LF, BT_COMP_ID_LF, NULL);
|
||||||
|
|
||||||
|
/* Bind to Health model */
|
||||||
|
bt_mesh_cfg_mod_app_bind(NET_IDX, addr, addr, APP_IDX,
|
||||||
|
BT_MESH_MODEL_ID_HEALTH_SRV, NULL);
|
||||||
|
|
||||||
|
/* Add model subscription */
|
||||||
|
bt_mesh_cfg_mod_sub_add_vnd(NET_IDX, addr, addr, GROUP_ADDR,
|
||||||
|
MOD_LF, BT_COMP_ID_LF, NULL);
|
||||||
|
|
||||||
|
bt_mesh_cfg_mod_pub_set_vnd(NET_IDX, addr, addr, MOD_LF, BT_COMP_ID_LF,
|
||||||
|
&pub, NULL);
|
||||||
|
|
||||||
|
printk("Configuration complete\n");
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_mesh(struct ble_npl_event *work)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = provision_and_configure();
|
||||||
|
if (err < 0) {
|
||||||
|
board_show_text("Starting Mesh Failed", false,
|
||||||
|
K_SECONDS(2));
|
||||||
|
} else {
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
snprintk(buf, sizeof(buf),
|
||||||
|
"Mesh Started\nAddr: 0x%04x", err);
|
||||||
|
board_show_text(buf, false, K_SECONDS(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh_start(void)
|
||||||
|
{
|
||||||
|
k_work_submit(&mesh_start_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mesh_is_initialized(void)
|
||||||
|
{
|
||||||
|
return bt_mesh_is_provisioned();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t mesh_get_addr(void)
|
||||||
|
{
|
||||||
|
return elements[0].addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mesh_init(uint8_t addr_type)
|
||||||
|
{
|
||||||
|
static const uint8_t dev_uuid[16] = { 0xc0, 0xff, 0xee };
|
||||||
|
static const struct bt_mesh_prov prov = {
|
||||||
|
.uuid = dev_uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
hb_cb = { .recv = heartbeat };
|
||||||
|
|
||||||
|
bt_mesh_pub_msg_health_pub = NET_BUF_SIMPLE(0);
|
||||||
|
health_pub.msg = bt_mesh_pub_msg_health_pub;
|
||||||
|
|
||||||
|
bt_mesh_pub_msg_vnd_pub = NET_BUF_SIMPLE(3 + 1);
|
||||||
|
vnd_pub.msg = bt_mesh_pub_msg_vnd_pub;
|
||||||
|
vnd_pub.update = pub_update;
|
||||||
|
|
||||||
|
k_work_init(&hello_work, send_hello);
|
||||||
|
k_work_init(&mesh_start_work, start_mesh);
|
||||||
|
|
||||||
|
return bt_mesh_init(addr_type, &prov, &comp);
|
||||||
|
}
|
14
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh.h
Normal file
14
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mesh/mesh.h"
|
||||||
|
|
||||||
|
void mesh_send_hello(void);
|
||||||
|
|
||||||
|
uint16_t mesh_get_addr(void);
|
||||||
|
bool mesh_is_initialized(void);
|
||||||
|
void mesh_start(void);
|
||||||
|
int mesh_init(uint8_t addr_type);
|
28
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh_badge.h
Normal file
28
src/libs/mynewt-nimble/apps/mesh_badge/src/mesh_badge.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ble_gatt_register_ctxt;
|
||||||
|
|
||||||
|
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
|
||||||
|
int gatt_svr_init(void);
|
||||||
|
|
||||||
|
void schedule_mesh_reset(void);
|
||||||
|
const char *bt_get_name(void);
|
||||||
|
int bt_set_name(const char *);
|
||||||
|
|
508
src/libs/mynewt-nimble/apps/mesh_badge/src/reel_board.c
Normal file
508
src/libs/mynewt-nimble/apps/mesh_badge/src/reel_board.c
Normal file
@ -0,0 +1,508 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Phytec Messtechnik GmbH
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "os/mynewt.h"
|
||||||
|
#include "bsp/bsp.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "hal/hal_flash.h"
|
||||||
|
#include "hal/hal_gpio.h"
|
||||||
|
#include "mesh/glue.h"
|
||||||
|
#include "services/gap/ble_svc_gap.h"
|
||||||
|
|
||||||
|
#include "mesh_badge.h"
|
||||||
|
#include "display/cfb.h"
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "board.h"
|
||||||
|
|
||||||
|
#define printk console_printf
|
||||||
|
|
||||||
|
enum font_size {
|
||||||
|
FONT_BIG = 0,
|
||||||
|
FONT_MEDIUM = 1,
|
||||||
|
FONT_SMALL = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct font_info {
|
||||||
|
uint8_t columns;
|
||||||
|
} fonts[] = {
|
||||||
|
[FONT_BIG] = { .columns = 12 },
|
||||||
|
[FONT_MEDIUM] = { .columns = 16 },
|
||||||
|
[FONT_SMALL] = { .columns = 25 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LONG_PRESS_TIMEOUT K_SECONDS(1)
|
||||||
|
|
||||||
|
#define STAT_COUNT 128
|
||||||
|
|
||||||
|
#define EDGE (GPIO_INT_EDGE | GPIO_INT_DOUBLE_EDGE)
|
||||||
|
|
||||||
|
#ifdef SW0_GPIO_FLAGS
|
||||||
|
#define PULL_UP SW0_GPIO_FLAGS
|
||||||
|
#else
|
||||||
|
#define PULL_UP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct os_dev *epd_dev;
|
||||||
|
static bool pressed;
|
||||||
|
static bool stats_view;
|
||||||
|
static struct k_delayed_work epd_work;
|
||||||
|
static struct k_delayed_work long_press_work;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int pin;
|
||||||
|
} leds[] = {
|
||||||
|
{ .pin = LED_1, },
|
||||||
|
{ .pin = RGB_LED_RED, },
|
||||||
|
{ .pin = RGB_LED_GRN, },
|
||||||
|
{ .pin = RGB_LED_BLU, },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct k_delayed_work led_timer;
|
||||||
|
|
||||||
|
static size_t print_line(enum font_size font_size, int row, const char *text,
|
||||||
|
size_t len, bool center)
|
||||||
|
{
|
||||||
|
uint8_t font_height, font_width;
|
||||||
|
char line[fonts[FONT_SMALL].columns + 1];
|
||||||
|
int pad;
|
||||||
|
|
||||||
|
cfb_framebuffer_set_font(epd_dev, font_size);
|
||||||
|
|
||||||
|
len = min(len, fonts[font_size].columns);
|
||||||
|
memcpy(line, text, len);
|
||||||
|
line[len] = '\0';
|
||||||
|
|
||||||
|
if (center) {
|
||||||
|
pad = (fonts[font_size].columns - len) / 2;
|
||||||
|
} else {
|
||||||
|
pad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfb_get_font_size(epd_dev, font_size, &font_width, &font_height);
|
||||||
|
|
||||||
|
if (cfb_print(epd_dev, line, font_width * pad, font_height * row)) {
|
||||||
|
printk("Failed to print a string\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t get_len(enum font_size font, const char *text)
|
||||||
|
{
|
||||||
|
const char *space = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i <= fonts[font].columns; i++) {
|
||||||
|
switch (text[i]) {
|
||||||
|
case '\n':
|
||||||
|
case '\0':
|
||||||
|
return i;
|
||||||
|
case ' ':
|
||||||
|
space = &text[i];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got more characters than fits a line, and a space was
|
||||||
|
* encountered, fall back to the last space.
|
||||||
|
*/
|
||||||
|
if (space) {
|
||||||
|
return space - text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fonts[font].columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_blink_leds(void)
|
||||||
|
{
|
||||||
|
k_delayed_work_submit(&led_timer, K_MSEC(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_show_text(const char *text, bool center, int32_t duration)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cfb_framebuffer_clear(epd_dev, false);
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while (*text == ' ' || *text == '\n') {
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = get_len(FONT_BIG, text);
|
||||||
|
if (!len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
text += print_line(FONT_BIG, i, text, len, center);
|
||||||
|
if (!*text) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfb_framebuffer_finalize(epd_dev);
|
||||||
|
|
||||||
|
if (duration != K_FOREVER) {
|
||||||
|
k_delayed_work_submit(&epd_work, duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct stat {
|
||||||
|
uint16_t addr;
|
||||||
|
char name[9];
|
||||||
|
uint8_t min_hops;
|
||||||
|
uint8_t max_hops;
|
||||||
|
uint16_t hello_count;
|
||||||
|
uint16_t heartbeat_count;
|
||||||
|
} stats[STAT_COUNT] = {
|
||||||
|
[0 ... (STAT_COUNT - 1)] = {
|
||||||
|
.min_hops = BT_MESH_TTL_MAX,
|
||||||
|
.max_hops = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t stat_count;
|
||||||
|
|
||||||
|
#define NO_UPDATE -1
|
||||||
|
|
||||||
|
static int add_hello(uint16_t addr, const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(stats); i++) {
|
||||||
|
struct stat *stat = &stats[i];
|
||||||
|
|
||||||
|
if (!stat->addr) {
|
||||||
|
stat->addr = addr;
|
||||||
|
strncpy(stat->name, name, sizeof(stat->name) - 1);
|
||||||
|
stat->hello_count = 1;
|
||||||
|
stat_count++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat->addr == addr) {
|
||||||
|
/* Update name, incase it has changed */
|
||||||
|
strncpy(stat->name, name, sizeof(stat->name) - 1);
|
||||||
|
|
||||||
|
if (stat->hello_count < 0xffff) {
|
||||||
|
stat->hello_count++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_UPDATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_UPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_heartbeat(uint16_t addr, uint8_t hops)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(stats); i++) {
|
||||||
|
struct stat *stat = &stats[i];
|
||||||
|
|
||||||
|
if (!stat->addr) {
|
||||||
|
stat->addr = addr;
|
||||||
|
stat->heartbeat_count = 1;
|
||||||
|
stat->min_hops = hops;
|
||||||
|
stat->max_hops = hops;
|
||||||
|
stat_count++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat->addr == addr) {
|
||||||
|
if (hops < stat->min_hops) {
|
||||||
|
stat->min_hops = hops;
|
||||||
|
} else if (hops > stat->max_hops) {
|
||||||
|
stat->max_hops = hops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat->heartbeat_count < 0xffff) {
|
||||||
|
stat->heartbeat_count++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_UPDATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_UPDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_add_hello(uint16_t addr, const char *name)
|
||||||
|
{
|
||||||
|
uint32_t sort_i;
|
||||||
|
|
||||||
|
sort_i = add_hello(addr, name);
|
||||||
|
if (sort_i != NO_UPDATE) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_add_heartbeat(uint16_t addr, uint8_t hops)
|
||||||
|
{
|
||||||
|
uint32_t sort_i;
|
||||||
|
|
||||||
|
sort_i = add_heartbeat(addr, hops);
|
||||||
|
if (sort_i != NO_UPDATE) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_statistics(void)
|
||||||
|
{
|
||||||
|
int top[4] = { -1, -1, -1, -1 };
|
||||||
|
int len, i, line = 0;
|
||||||
|
struct stat *stat;
|
||||||
|
char str[32];
|
||||||
|
|
||||||
|
cfb_framebuffer_clear(epd_dev, false);
|
||||||
|
|
||||||
|
len = snprintk(str, sizeof(str),
|
||||||
|
"Own Address: 0x%04x", mesh_get_addr());
|
||||||
|
print_line(FONT_SMALL, line++, str, len, false);
|
||||||
|
|
||||||
|
len = snprintk(str, sizeof(str),
|
||||||
|
"Node Count: %lu", stat_count + 1);
|
||||||
|
print_line(FONT_SMALL, line++, str, len, false);
|
||||||
|
|
||||||
|
/* Find the top sender */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(stats); i++) {
|
||||||
|
int j;
|
||||||
|
|
||||||
|
stat = &stats[i];
|
||||||
|
if (!stat->addr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stat->hello_count) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < ARRAY_SIZE(top); j++) {
|
||||||
|
if (top[j] < 0) {
|
||||||
|
top[j] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat->hello_count <= stats[top[j]].hello_count) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move other elements down the list */
|
||||||
|
if (j < ARRAY_SIZE(top) - 1) {
|
||||||
|
memmove(&top[j + 1], &top[j],
|
||||||
|
((ARRAY_SIZE(top) - j - 1) *
|
||||||
|
sizeof(top[j])));
|
||||||
|
}
|
||||||
|
|
||||||
|
top[j] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat_count >= 0) {
|
||||||
|
len = snprintk(str, sizeof(str), "Most messages from:");
|
||||||
|
print_line(FONT_SMALL, line++, str, len, false);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(top); i++) {
|
||||||
|
if (top[i] < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat = &stats[top[i]];
|
||||||
|
|
||||||
|
len = snprintk(str, sizeof(str), "%-3u 0x%04x %s",
|
||||||
|
stat->hello_count, stat->addr,
|
||||||
|
stat->name);
|
||||||
|
print_line(FONT_SMALL, line++, str, len, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfb_framebuffer_finalize(epd_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void epd_update(struct ble_npl_event *work)
|
||||||
|
{
|
||||||
|
char buf[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH)];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (stats_view) {
|
||||||
|
show_statistics();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(buf, bt_get_name(), sizeof(buf));
|
||||||
|
|
||||||
|
/* Convert commas to newlines */
|
||||||
|
for (i = 0; buf[i] != '\0'; i++) {
|
||||||
|
if (buf[i] == ',') {
|
||||||
|
buf[i] = '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
board_show_text(buf, true, K_FOREVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void long_press(struct ble_npl_event *work)
|
||||||
|
{
|
||||||
|
/* Treat as release so actual release doesn't send messages */
|
||||||
|
pressed = false;
|
||||||
|
stats_view = !stats_view;
|
||||||
|
board_refresh_display();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool button_is_pressed(void)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
val = (uint32_t) hal_gpio_read(BUTTON_1);
|
||||||
|
|
||||||
|
return !val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_interrupt(struct os_event *ev)
|
||||||
|
{
|
||||||
|
int pin_pos = (int ) ev->ev_arg;
|
||||||
|
|
||||||
|
if (button_is_pressed() == pressed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pressed = !pressed;
|
||||||
|
printk("Button %s\n", pressed ? "pressed" : "released");
|
||||||
|
|
||||||
|
if (pressed) {
|
||||||
|
k_delayed_work_submit(&long_press_work, LONG_PRESS_TIMEOUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_delayed_work_cancel(&long_press_work);
|
||||||
|
|
||||||
|
if (!mesh_is_initialized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Short press does currently nothing in statistics view */
|
||||||
|
if (stats_view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pin_pos == BUTTON_1) {
|
||||||
|
mesh_send_hello();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct os_event button_event;
|
||||||
|
|
||||||
|
static void
|
||||||
|
gpio_irq_handler(void *arg)
|
||||||
|
{
|
||||||
|
button_event.ev_arg = arg;
|
||||||
|
os_eventq_put(os_eventq_dflt_get(), &button_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int configure_button(void)
|
||||||
|
{
|
||||||
|
button_event.ev_cb = button_interrupt;
|
||||||
|
|
||||||
|
hal_gpio_irq_init(BUTTON_1, gpio_irq_handler, (void *) BUTTON_1,
|
||||||
|
HAL_GPIO_TRIG_BOTH, HAL_GPIO_PULL_UP);
|
||||||
|
hal_gpio_irq_enable(BUTTON_1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void led_timeout(struct ble_npl_event *work)
|
||||||
|
{
|
||||||
|
static int led_cntr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Disable all LEDs */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(leds); i++) {
|
||||||
|
hal_gpio_write(leds[i].pin, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop after 5 iterations */
|
||||||
|
if (led_cntr > (ARRAY_SIZE(leds) * 5)) {
|
||||||
|
led_cntr = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select and enable current LED */
|
||||||
|
i = led_cntr++ % ARRAY_SIZE(leds);
|
||||||
|
hal_gpio_write(leds[i].pin, 0);
|
||||||
|
|
||||||
|
k_delayed_work_submit(&led_timer, K_MSEC(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int configure_leds(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(leds); i++) {
|
||||||
|
hal_gpio_init_out(leds[i].pin, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
k_delayed_work_init(&led_timer, led_timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int erase_storage(void)
|
||||||
|
{
|
||||||
|
bt_set_name(MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME));
|
||||||
|
ble_store_clear();
|
||||||
|
schedule_mesh_reset();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void board_refresh_display(void)
|
||||||
|
{
|
||||||
|
k_delayed_work_submit(&epd_work, K_NO_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_init(void)
|
||||||
|
{
|
||||||
|
epd_dev = os_dev_lookup(MYNEWT_VAL(SSD1673_OS_DEV_NAME));
|
||||||
|
if (epd_dev == NULL) {
|
||||||
|
printk("SSD1673 device not found\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfb_framebuffer_init(epd_dev)) {
|
||||||
|
printk("Framebuffer initialization failed\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfb_framebuffer_clear(epd_dev, true);
|
||||||
|
|
||||||
|
if (configure_button()) {
|
||||||
|
printk("Failed to configure button\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configure_leds()) {
|
||||||
|
printk("LED init failed\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_delayed_work_init(&epd_work, epd_update);
|
||||||
|
k_delayed_work_init(&long_press_work, long_press);
|
||||||
|
|
||||||
|
pressed = button_is_pressed();
|
||||||
|
if (pressed) {
|
||||||
|
printk("Erasing storage\n");
|
||||||
|
board_show_text("Resetting Device", false, K_SECONDS(4));
|
||||||
|
erase_storage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
58
src/libs/mynewt-nimble/apps/mesh_badge/syscfg.yml
Normal file
58
src/libs/mynewt-nimble/apps/mesh_badge/syscfg.yml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Package: apps/mesh_badge
|
||||||
|
|
||||||
|
syscfg.vals:
|
||||||
|
# Enable the shell task.
|
||||||
|
SHELL_TASK: 1
|
||||||
|
|
||||||
|
# Set log level to info (disable debug logging).
|
||||||
|
LOG_LEVEL: 1
|
||||||
|
|
||||||
|
# Default task settings
|
||||||
|
OS_MAIN_STACK_SIZE: 768
|
||||||
|
|
||||||
|
# Newtmgr is not supported in this app, so disable newtmgr-over-shell.
|
||||||
|
SHELL_NEWTMGR: 0
|
||||||
|
|
||||||
|
REEL_BOARD_ENABLE_ACTIVE_MODE: 1
|
||||||
|
SPI_0_MASTER: 1
|
||||||
|
|
||||||
|
BLE_MESH: 1
|
||||||
|
MSYS_1_BLOCK_COUNT: 48
|
||||||
|
|
||||||
|
BLE_SVC_GAP_DEVICE_NAME: '"reel board"'
|
||||||
|
|
||||||
|
BLE_SM_SC: 1
|
||||||
|
BLE_SM_BONDING: 1
|
||||||
|
BLE_MESH_RELAY: 1
|
||||||
|
BLE_MESH_GATT_PROXY: 0
|
||||||
|
BLE_MESH_PB_ADV: 0
|
||||||
|
BLE_MESH_PB_GATT: 0
|
||||||
|
BLE_MESH_ADV_BUF_COUNT: 30
|
||||||
|
BLE_MESH_LABEL_COUNT: 0
|
||||||
|
BLE_MESH_CFG_CLI: 1
|
||||||
|
BLE_MESH_TX_SEG_MAX: 6
|
||||||
|
BLE_MESH_TX_SEG_MSG_COUNT: 3
|
||||||
|
BLE_MESH_RX_SEG_MSG_COUNT: 3
|
||||||
|
BLE_MESH_CRPL: 128
|
||||||
|
BLE_MESH_RPL_STORE_TIMEOUT: 120
|
||||||
|
BLE_MESH_SETTINGS: 1
|
||||||
|
CONFIG_NFFS: 1
|
||||||
|
BLE_MESH_PB_ADV: 1
|
@ -69,6 +69,29 @@ extern "C" {
|
|||||||
/* Timing jitter as per spec is +/16 usecs */
|
/* Timing jitter as per spec is +/16 usecs */
|
||||||
#define BLE_LL_JITTER_USECS (16)
|
#define BLE_LL_JITTER_USECS (16)
|
||||||
|
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_SCA) < 0
|
||||||
|
#error Invalid SCA value
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 20
|
||||||
|
#define BLE_LL_SCA_ENUM 7
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 30
|
||||||
|
#define BLE_LL_SCA_ENUM 6
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 50
|
||||||
|
#define BLE_LL_SCA_ENUM 5
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 75
|
||||||
|
#define BLE_LL_SCA_ENUM 4
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 100
|
||||||
|
#define BLE_LL_SCA_ENUM 3
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 150
|
||||||
|
#define BLE_LL_SCA_ENUM 2
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 250
|
||||||
|
#define BLE_LL_SCA_ENUM 1
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_SCA) <= 500
|
||||||
|
#define BLE_LL_SCA_ENUM 0
|
||||||
|
#else
|
||||||
|
#error Invalid SCA value
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Packet queue header definition */
|
/* Packet queue header definition */
|
||||||
STAILQ_HEAD(ble_ll_pkt_q, os_mbuf_pkthdr);
|
STAILQ_HEAD(ble_ll_pkt_q, os_mbuf_pkthdr);
|
||||||
|
|
||||||
@ -373,6 +396,12 @@ struct ble_dev_addr
|
|||||||
#define BLE_LL_LLID_DATA_START (2)
|
#define BLE_LL_LLID_DATA_START (2)
|
||||||
#define BLE_LL_LLID_CTRL (3)
|
#define BLE_LL_LLID_CTRL (3)
|
||||||
|
|
||||||
|
#define BLE_LL_LLID_IS_CTRL(hdr) \
|
||||||
|
(((hdr) & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL)
|
||||||
|
#define BLE_LL_LLID_IS_DATA(hdr) \
|
||||||
|
((((hdr) & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_DATA_START) || \
|
||||||
|
(((hdr) & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_DATA_FRAG))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CONNECT_REQ
|
* CONNECT_REQ
|
||||||
* -> InitA (6 bytes)
|
* -> InitA (6 bytes)
|
||||||
@ -545,6 +574,7 @@ void ble_ll_rand_sample(uint8_t rnum);
|
|||||||
int ble_ll_rand_data_get(uint8_t *buf, uint8_t len);
|
int ble_ll_rand_data_get(uint8_t *buf, uint8_t len);
|
||||||
void ble_ll_rand_prand_get(uint8_t *prand);
|
void ble_ll_rand_prand_get(uint8_t *prand);
|
||||||
int ble_ll_rand_start(void);
|
int ble_ll_rand_start(void);
|
||||||
|
uint32_t ble_ll_rand(void);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
ble_ll_get_addr_type(uint8_t txrxflag)
|
ble_ll_get_addr_type(uint8_t txrxflag)
|
||||||
|
@ -58,6 +58,8 @@ extern "C" {
|
|||||||
/* Definition for RSSI when the RSSI is unknown */
|
/* Definition for RSSI when the RSSI is unknown */
|
||||||
#define BLE_LL_CONN_UNKNOWN_RSSI (127)
|
#define BLE_LL_CONN_UNKNOWN_RSSI (127)
|
||||||
|
|
||||||
|
#define BLE_LL_CONN_HANDLE_ISO_OFFSET (0x0100)
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
|
||||||
/*
|
/*
|
||||||
* Encryption states for a connection
|
* Encryption states for a connection
|
||||||
@ -69,6 +71,7 @@ extern "C" {
|
|||||||
enum conn_enc_state {
|
enum conn_enc_state {
|
||||||
CONN_ENC_S_UNENCRYPTED = 1,
|
CONN_ENC_S_UNENCRYPTED = 1,
|
||||||
CONN_ENC_S_ENCRYPTED,
|
CONN_ENC_S_ENCRYPTED,
|
||||||
|
CONN_ENC_S_ENC_RSP_TO_BE_SENT,
|
||||||
CONN_ENC_S_ENC_RSP_WAIT,
|
CONN_ENC_S_ENC_RSP_WAIT,
|
||||||
CONN_ENC_S_PAUSE_ENC_RSP_WAIT,
|
CONN_ENC_S_PAUSE_ENC_RSP_WAIT,
|
||||||
CONN_ENC_S_PAUSED,
|
CONN_ENC_S_PAUSED,
|
||||||
@ -270,6 +273,10 @@ struct ble_ll_conn_sm
|
|||||||
uint8_t last_rxd_hdr_byte; /* note: possibly can make 1 bit since we
|
uint8_t last_rxd_hdr_byte; /* note: possibly can make 1 bit since we
|
||||||
only use the MD bit now */
|
only use the MD bit now */
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
uint16_t cth_flow_pending;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* connection event mgmt */
|
/* connection event mgmt */
|
||||||
uint8_t reject_reason;
|
uint8_t reject_reason;
|
||||||
uint8_t host_reply_opcode;
|
uint8_t host_reply_opcode;
|
||||||
|
@ -39,7 +39,9 @@ extern "C" {
|
|||||||
#define BLE_LL_CTRL_PROC_LE_PING (7)
|
#define BLE_LL_CTRL_PROC_LE_PING (7)
|
||||||
#define BLE_LL_CTRL_PROC_DATA_LEN_UPD (8)
|
#define BLE_LL_CTRL_PROC_DATA_LEN_UPD (8)
|
||||||
#define BLE_LL_CTRL_PROC_PHY_UPDATE (9)
|
#define BLE_LL_CTRL_PROC_PHY_UPDATE (9)
|
||||||
#define BLE_LL_CTRL_PROC_NUM (10)
|
#define BLE_LL_CTRL_PROC_SCA_UPDATE (10)
|
||||||
|
#define BLE_LL_CTRL_PROC_CIS_CREATE (11)
|
||||||
|
#define BLE_LL_CTRL_PROC_NUM (12)
|
||||||
#define BLE_LL_CTRL_PROC_IDLE (255)
|
#define BLE_LL_CTRL_PROC_IDLE (255)
|
||||||
|
|
||||||
/* Checks if a particular control procedure is running */
|
/* Checks if a particular control procedure is running */
|
||||||
@ -54,45 +56,51 @@ extern "C" {
|
|||||||
* -> Opcode (1 byte)
|
* -> Opcode (1 byte)
|
||||||
* -> Data (0 - 26 bytes)
|
* -> Data (0 - 26 bytes)
|
||||||
*/
|
*/
|
||||||
#define BLE_LL_CTRL_CONN_UPDATE_IND (0)
|
#define BLE_LL_CTRL_CONN_UPDATE_IND (0x00)
|
||||||
#define BLE_LL_CTRL_CHANNEL_MAP_REQ (1)
|
#define BLE_LL_CTRL_CHANNEL_MAP_REQ (0x01)
|
||||||
#define BLE_LL_CTRL_TERMINATE_IND (2)
|
#define BLE_LL_CTRL_TERMINATE_IND (0x02)
|
||||||
#define BLE_LL_CTRL_ENC_REQ (3)
|
#define BLE_LL_CTRL_ENC_REQ (0x03)
|
||||||
#define BLE_LL_CTRL_ENC_RSP (4)
|
#define BLE_LL_CTRL_ENC_RSP (0x04)
|
||||||
#define BLE_LL_CTRL_START_ENC_REQ (5)
|
#define BLE_LL_CTRL_START_ENC_REQ (0x05)
|
||||||
#define BLE_LL_CTRL_START_ENC_RSP (6)
|
#define BLE_LL_CTRL_START_ENC_RSP (0x06)
|
||||||
#define BLE_LL_CTRL_UNKNOWN_RSP (7)
|
#define BLE_LL_CTRL_UNKNOWN_RSP (0x07)
|
||||||
#define BLE_LL_CTRL_FEATURE_REQ (8)
|
#define BLE_LL_CTRL_FEATURE_REQ (0x08)
|
||||||
#define BLE_LL_CTRL_FEATURE_RSP (9)
|
#define BLE_LL_CTRL_FEATURE_RSP (0x09)
|
||||||
#define BLE_LL_CTRL_PAUSE_ENC_REQ (10)
|
#define BLE_LL_CTRL_PAUSE_ENC_REQ (0x0A)
|
||||||
#define BLE_LL_CTRL_PAUSE_ENC_RSP (11)
|
#define BLE_LL_CTRL_PAUSE_ENC_RSP (0x0B)
|
||||||
#define BLE_LL_CTRL_VERSION_IND (12)
|
#define BLE_LL_CTRL_VERSION_IND (0x0C)
|
||||||
#define BLE_LL_CTRL_REJECT_IND (13)
|
#define BLE_LL_CTRL_REJECT_IND (0x0D)
|
||||||
#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (14)
|
#define BLE_LL_CTRL_SLAVE_FEATURE_REQ (0x0E)
|
||||||
#define BLE_LL_CTRL_CONN_PARM_REQ (15)
|
#define BLE_LL_CTRL_CONN_PARM_REQ (0x0F)
|
||||||
#define BLE_LL_CTRL_CONN_PARM_RSP (16)
|
#define BLE_LL_CTRL_CONN_PARM_RSP (0x10)
|
||||||
#define BLE_LL_CTRL_REJECT_IND_EXT (17)
|
#define BLE_LL_CTRL_REJECT_IND_EXT (0x11)
|
||||||
#define BLE_LL_CTRL_PING_REQ (18)
|
#define BLE_LL_CTRL_PING_REQ (0x12)
|
||||||
#define BLE_LL_CTRL_PING_RSP (19)
|
#define BLE_LL_CTRL_PING_RSP (0x13)
|
||||||
#define BLE_LL_CTRL_LENGTH_REQ (20)
|
#define BLE_LL_CTRL_LENGTH_REQ (0x14)
|
||||||
#define BLE_LL_CTRL_LENGTH_RSP (21)
|
#define BLE_LL_CTRL_LENGTH_RSP (0x15)
|
||||||
#define BLE_LL_CTRL_PHY_REQ (22)
|
#define BLE_LL_CTRL_PHY_REQ (0x16)
|
||||||
#define BLE_LL_CTRL_PHY_RSP (23)
|
#define BLE_LL_CTRL_PHY_RSP (0x17)
|
||||||
#define BLE_LL_CTRL_PHY_UPDATE_IND (24)
|
#define BLE_LL_CTRL_PHY_UPDATE_IND (0x18)
|
||||||
#define BLE_LL_CTRL_MIN_USED_CHAN_IND (25)
|
#define BLE_LL_CTRL_MIN_USED_CHAN_IND (0x19)
|
||||||
#define BLE_LL_CTRL_CTE_REQ (26)
|
#define BLE_LL_CTRL_CTE_REQ (0x1A)
|
||||||
#define BLE_LL_CTRL_CTE_RSP (27)
|
#define BLE_LL_CTRL_CTE_RSP (0x1B)
|
||||||
#define BLE_LL_CTRL_PERIODIC_SYNC_IND (28)
|
#define BLE_LL_CTRL_PERIODIC_SYNC_IND (0x1C)
|
||||||
#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ (29)
|
#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ (0x1D)
|
||||||
#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP (30)
|
#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP (0x1E)
|
||||||
|
#define BLE_LL_CTRL_CIS_REQ (0x1F)
|
||||||
|
#define BLE_LL_CTRL_CIS_RSP (0x20)
|
||||||
|
#define BLE_LL_CTRL_CIS_IND (0x21)
|
||||||
|
#define BLE_LL_CTRL_CIS_TERMINATE_IND (0x22)
|
||||||
|
|
||||||
/* Maximum opcode value */
|
/* Maximum opcode value */
|
||||||
#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CLOCK_ACCURACY_RSP + 1)
|
#define BLE_LL_CTRL_OPCODES (BLE_LL_CTRL_CIS_TERMINATE_IND + 1)
|
||||||
|
|
||||||
extern const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES];
|
extern const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES];
|
||||||
|
|
||||||
/* Maximum LL control PDU size */
|
/* Maximum LL control PDU size */
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
#if MYNEWT_VAL(BLE_ISO)
|
||||||
|
#define BLE_LL_CTRL_MAX_PDU_LEN (42)
|
||||||
|
#elif MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
||||||
#define BLE_LL_CTRL_MAX_PDU_LEN (35)
|
#define BLE_LL_CTRL_MAX_PDU_LEN (35)
|
||||||
#else
|
#else
|
||||||
#define BLE_LL_CTRL_MAX_PDU_LEN (27)
|
#define BLE_LL_CTRL_MAX_PDU_LEN (27)
|
||||||
@ -261,6 +269,12 @@ struct ble_ll_len_req
|
|||||||
#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN (1)
|
#define BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN (1)
|
||||||
#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN (1)
|
#define BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN (1)
|
||||||
|
|
||||||
|
/* BLE ISO */
|
||||||
|
#define BLE_LL_CTRL_CIS_REQ_LEN (42)
|
||||||
|
#define BLE_LL_CTRL_CIS_RSP_LEN (8)
|
||||||
|
#define BLE_LL_CTRL_CIS_IND_LEN (15)
|
||||||
|
#define BLE_LL_CTRL_CIS_TERMINATE_LEN (3)
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
struct ble_ll_conn_sm;
|
struct ble_ll_conn_sm;
|
||||||
void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc);
|
void ble_ll_ctrl_proc_start(struct ble_ll_conn_sm *connsm, int ctrl_proc);
|
||||||
@ -306,6 +320,11 @@ void ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line);
|
|||||||
uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask);
|
uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask);
|
||||||
uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask);
|
uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask);
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
void ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm,
|
||||||
|
uint8_t status, uint8_t peer_sca);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,7 +27,7 @@ extern "C" {
|
|||||||
#include "nimble/hci_common.h"
|
#include "nimble/hci_common.h"
|
||||||
|
|
||||||
/* For supported commands */
|
/* For supported commands */
|
||||||
#define BLE_LL_SUPP_CMD_LEN (42)
|
#define BLE_LL_SUPP_CMD_LEN (45)
|
||||||
extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN];
|
extern const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN];
|
||||||
|
|
||||||
/* The largest event the controller will send. */
|
/* The largest event the controller will send. */
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 H_BLE_LL_ISO
|
||||||
|
#define H_BLE_LL_ISO
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
|
int ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
|
int ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd);
|
||||||
|
int ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len, uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
|
int ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
int ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -225,6 +225,8 @@ static inline int ble_ll_phy_to_phy_mode(int phy, int phy_options)
|
|||||||
if (phy == BLE_PHY_CODED && phy_options == BLE_HCI_LE_PHY_CODED_S2_PREF) {
|
if (phy == BLE_PHY_CODED && phy_options == BLE_HCI_LE_PHY_CODED_S2_PREF) {
|
||||||
phy_mode = BLE_PHY_MODE_CODED_500KBPS;
|
phy_mode = BLE_PHY_MODE_CODED_500KBPS;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)phy_options;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return phy_mode;
|
return phy_mode;
|
||||||
|
@ -247,9 +247,6 @@ uint8_t g_dev_addr[BLE_DEV_ADDR_LEN];
|
|||||||
/** Our random address */
|
/** Our random address */
|
||||||
uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
|
uint8_t g_random_addr[BLE_DEV_ADDR_LEN];
|
||||||
|
|
||||||
/** Our supported features which can be controller by the host */
|
|
||||||
uint64_t g_ble_ll_supported_host_features = 0;
|
|
||||||
|
|
||||||
static const uint16_t g_ble_ll_pdu_header_tx_time[BLE_PHY_NUM_MODE] =
|
static const uint16_t g_ble_ll_pdu_header_tx_time[BLE_PHY_NUM_MODE] =
|
||||||
{
|
{
|
||||||
[BLE_PHY_MODE_1M] =
|
[BLE_PHY_MODE_1M] =
|
||||||
@ -1206,8 +1203,6 @@ ble_ll_task(void *arg)
|
|||||||
/* Tell the host that we are ready to receive packets */
|
/* Tell the host that we are ready to receive packets */
|
||||||
ble_ll_hci_send_noop();
|
ble_ll_hci_send_noop();
|
||||||
|
|
||||||
ble_ll_rand_start();
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER);
|
ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER);
|
||||||
assert(ev);
|
assert(ev);
|
||||||
@ -1305,10 +1300,6 @@ ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len)
|
|||||||
|
|
||||||
mask = (uint64_t)1 << (cmd->bit_num);
|
mask = (uint64_t)1 << (cmd->bit_num);
|
||||||
if (!(mask & BLE_LL_HOST_CONTROLLED_FEATURES)) {
|
if (!(mask & BLE_LL_HOST_CONTROLLED_FEATURES)) {
|
||||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(mask & g_ble_ll_supported_host_features)) {
|
|
||||||
return BLE_ERR_UNSUPPORTED;
|
return BLE_ERR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1372,6 +1363,20 @@ ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr)
|
|||||||
ble_hdr->txinfo.hdr_byte = hdr;
|
ble_hdr->txinfo.hdr_byte = hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_ll_validate_task(void)
|
||||||
|
{
|
||||||
|
#ifdef MYNEWT
|
||||||
|
#ifndef NDEBUG
|
||||||
|
struct os_task_info oti;
|
||||||
|
|
||||||
|
os_task_info_get(&g_ble_ll_task, &oti);
|
||||||
|
|
||||||
|
BLE_LL_ASSERT(oti.oti_stkusage < oti.oti_stksize);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to reset the controller. This performs a "software reset" of the link
|
* Called to reset the controller. This performs a "software reset" of the link
|
||||||
* layer; it does not perform a HW reset of the controller nor does it reset
|
* layer; it does not perform a HW reset of the controller nor does it reset
|
||||||
@ -1388,6 +1393,9 @@ ble_ll_reset(void)
|
|||||||
int rc;
|
int rc;
|
||||||
os_sr_t sr;
|
os_sr_t sr;
|
||||||
|
|
||||||
|
/* do sanity check on LL task stack */
|
||||||
|
ble_ll_validate_task();
|
||||||
|
|
||||||
OS_ENTER_CRITICAL(sr);
|
OS_ENTER_CRITICAL(sr);
|
||||||
ble_phy_disable();
|
ble_phy_disable();
|
||||||
ble_ll_sched_stop();
|
ble_ll_sched_stop();
|
||||||
@ -1447,23 +1455,6 @@ ble_ll_reset(void)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ble_ll_seed_prng(void)
|
|
||||||
{
|
|
||||||
uint32_t seed;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Seed random number generator with least significant bytes of device
|
|
||||||
* address.
|
|
||||||
*/
|
|
||||||
seed = 0;
|
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
seed |= g_dev_addr[i];
|
|
||||||
seed <<= 8;
|
|
||||||
}
|
|
||||||
srand(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode)
|
ble_ll_pdu_tx_time_get(uint16_t payload_len, int phy_mode)
|
||||||
{
|
{
|
||||||
@ -1678,16 +1669,24 @@ ble_ll_init(void)
|
|||||||
features |= BLE_LL_FEAT_SYNC_TRANS_SEND;
|
features |= BLE_LL_FEAT_SYNC_TRANS_SEND;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize random number generation */
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
ble_ll_rand_init();
|
features |= BLE_LL_FEAT_SCA_UPDATE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XXX: This really doesn't belong here, as the address probably has not
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
* been set yet.
|
features |= BLE_LL_FEAT_CIS_MASTER;
|
||||||
*/
|
features |= BLE_LL_FEAT_CIS_SLAVE;
|
||||||
ble_ll_seed_prng();
|
features |= BLE_LL_FEAT_ISO_BROADCASTER;
|
||||||
|
features |= BLE_LL_FEAT_ISO_HOST_SUPPORT;
|
||||||
|
#endif
|
||||||
|
|
||||||
lldata->ll_supp_features = features;
|
lldata->ll_supp_features = features;
|
||||||
|
|
||||||
|
/* Initialize random number generation */
|
||||||
|
ble_ll_rand_init();
|
||||||
|
/* Start the random number generator */
|
||||||
|
ble_ll_rand_start();
|
||||||
|
|
||||||
rc = stats_init_and_reg(STATS_HDR(ble_ll_stats),
|
rc = stats_init_and_reg(STATS_HDR(ble_ll_stats),
|
||||||
STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32),
|
STATS_SIZE_INIT_PARMS(ble_ll_stats, STATS_SIZE_32),
|
||||||
STATS_NAME_INIT_PARMS(ble_ll_stats),
|
STATS_NAME_INIT_PARMS(ble_ll_stats),
|
||||||
|
@ -131,6 +131,7 @@ struct ble_ll_adv_sm
|
|||||||
uint8_t aux_index : 1;
|
uint8_t aux_index : 1;
|
||||||
uint8_t aux_first_pdu : 1;
|
uint8_t aux_first_pdu : 1;
|
||||||
uint8_t aux_not_scanned : 1;
|
uint8_t aux_not_scanned : 1;
|
||||||
|
uint8_t aux_dropped : 1;
|
||||||
struct ble_mbuf_hdr *rx_ble_hdr;
|
struct ble_mbuf_hdr *rx_ble_hdr;
|
||||||
struct os_mbuf **aux_data;
|
struct os_mbuf **aux_data;
|
||||||
struct ble_ll_adv_aux aux[2];
|
struct ble_ll_adv_aux aux[2];
|
||||||
@ -685,7 +686,7 @@ ble_ll_adv_put_syncinfo(struct ble_ll_adv_sm *advsm,
|
|||||||
dptr[8] = advsm->periodic_chanmap[4] & 0x1f;
|
dptr[8] = advsm->periodic_chanmap[4] & 0x1f;
|
||||||
|
|
||||||
/* SCA (3 bits) */
|
/* SCA (3 bits) */
|
||||||
dptr[8] |= MYNEWT_VAL(BLE_LL_MASTER_SCA) << 5;
|
dptr[8] |= BLE_LL_SCA_ENUM << 5;
|
||||||
|
|
||||||
/* AA (4 bytes) */
|
/* AA (4 bytes) */
|
||||||
put_le32(&dptr[9], advsm->periodic_access_addr);
|
put_le32(&dptr[9], advsm->periodic_access_addr);
|
||||||
@ -1269,7 +1270,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
|
|||||||
rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
|
rc = ble_phy_tx_set_start_time(txstart, sch->remainder);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
STATS_INC(ble_ll_stats, adv_late_starts);
|
STATS_INC(ble_ll_stats, adv_late_starts);
|
||||||
goto adv_tx_done;
|
goto adv_aux_dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
|
||||||
@ -1304,7 +1305,7 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
|
|||||||
/* Transmit advertisement */
|
/* Transmit advertisement */
|
||||||
rc = ble_phy_tx(pducb, advsm, end_trans);
|
rc = ble_phy_tx(pducb, advsm, end_trans);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
goto adv_tx_done;
|
goto adv_aux_dropped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable/disable whitelisting based on filter policy */
|
/* Enable/disable whitelisting based on filter policy */
|
||||||
@ -1322,7 +1323,8 @@ ble_ll_adv_secondary_tx_start_cb(struct ble_ll_sched_item *sch)
|
|||||||
|
|
||||||
return BLE_LL_SCHED_STATE_RUNNING;
|
return BLE_LL_SCHED_STATE_RUNNING;
|
||||||
|
|
||||||
adv_tx_done:
|
adv_aux_dropped:
|
||||||
|
advsm->aux_dropped = 1;
|
||||||
ble_ll_adv_tx_done(advsm);
|
ble_ll_adv_tx_done(advsm);
|
||||||
return BLE_LL_SCHED_STATE_DONE;
|
return BLE_LL_SCHED_STATE_DONE;
|
||||||
}
|
}
|
||||||
@ -1377,7 +1379,7 @@ ble_ll_adv_aux_calculate(struct ble_ll_adv_sm *advsm,
|
|||||||
g_ble_ll_conn_params.num_used_chans,
|
g_ble_ll_conn_params.num_used_chans,
|
||||||
g_ble_ll_conn_params.master_chan_map);
|
g_ble_ll_conn_params.master_chan_map);
|
||||||
#else
|
#else
|
||||||
aux->chan = ble_ll_utils_remapped_channel(rand() % BLE_PHY_NUM_DATA_CHANS,
|
aux->chan = ble_ll_utils_remapped_channel(ble_ll_rand() % BLE_PHY_NUM_DATA_CHANS,
|
||||||
g_ble_ll_conn_params.master_chan_map);
|
g_ble_ll_conn_params.master_chan_map);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1554,6 +1556,7 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm)
|
|||||||
advsm->aux_index = 0;
|
advsm->aux_index = 0;
|
||||||
advsm->aux_first_pdu = 1;
|
advsm->aux_first_pdu = 1;
|
||||||
advsm->aux_not_scanned = 0;
|
advsm->aux_not_scanned = 0;
|
||||||
|
advsm->aux_dropped = 0;
|
||||||
|
|
||||||
aux = AUX_CURRENT(advsm);
|
aux = AUX_CURRENT(advsm);
|
||||||
ble_ll_adv_aux_calculate(advsm, aux, 0);
|
ble_ll_adv_aux_calculate(advsm, aux, 0);
|
||||||
@ -1853,7 +1856,7 @@ ble_ll_adv_update_did(struct ble_ll_adv_sm *advsm)
|
|||||||
* the previously used value.
|
* the previously used value.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
advsm->adi = (advsm->adi & 0xf000) | (rand() & 0x0fff);
|
advsm->adi = (advsm->adi & 0xf000) | (ble_ll_rand() & 0x0fff);
|
||||||
} while (old_adi == advsm->adi);
|
} while (old_adi == advsm->adi);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2544,11 +2547,11 @@ ble_ll_adv_sm_start_periodic(struct ble_ll_adv_sm *advsm)
|
|||||||
advsm->periodic_num_used_chans = g_ble_ll_conn_params.num_used_chans;
|
advsm->periodic_num_used_chans = g_ble_ll_conn_params.num_used_chans;
|
||||||
advsm->periodic_event_cntr = 0;
|
advsm->periodic_event_cntr = 0;
|
||||||
/* for chaining we start with random counter as we share access addr */
|
/* for chaining we start with random counter as we share access addr */
|
||||||
advsm->periodic_chain_event_cntr = rand();
|
advsm->periodic_chain_event_cntr = ble_ll_rand();
|
||||||
advsm->periodic_access_addr = ble_ll_utils_calc_access_addr();
|
advsm->periodic_access_addr = ble_ll_utils_calc_access_addr();
|
||||||
advsm->periodic_channel_id = ((advsm->periodic_access_addr & 0xffff0000) >> 16) ^
|
advsm->periodic_channel_id = ((advsm->periodic_access_addr & 0xffff0000) >> 16) ^
|
||||||
(advsm->periodic_access_addr & 0x0000ffff);
|
(advsm->periodic_access_addr & 0x0000ffff);
|
||||||
advsm->periodic_crcinit = rand() & 0xffffff;
|
advsm->periodic_crcinit = ble_ll_rand() & 0xffffff;
|
||||||
|
|
||||||
usecs = (uint32_t)advsm->periodic_adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL;
|
usecs = (uint32_t)advsm->periodic_adv_itvl_max * BLE_LL_ADV_PERIODIC_ITVL;
|
||||||
ticks = os_cputime_usecs_to_ticks(usecs);
|
ticks = os_cputime_usecs_to_ticks(usecs);
|
||||||
@ -2737,7 +2740,7 @@ ble_ll_adv_sm_start(struct ble_ll_adv_sm *advsm)
|
|||||||
*/
|
*/
|
||||||
earliest_start_time = ble_ll_rfmgmt_enable_now();
|
earliest_start_time = ble_ll_rfmgmt_enable_now();
|
||||||
|
|
||||||
start_delay_us = rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
|
start_delay_us = ble_ll_rand() % (BLE_LL_ADV_DELAY_MS_MAX * 1000);
|
||||||
advsm->adv_pdu_start_time = os_cputime_get32() +
|
advsm->adv_pdu_start_time = os_cputime_get32() +
|
||||||
os_cputime_usecs_to_ticks(start_delay_us);
|
os_cputime_usecs_to_ticks(start_delay_us);
|
||||||
|
|
||||||
@ -4020,7 +4023,7 @@ ble_ll_adv_periodic_send_sync_ind(struct ble_ll_adv_sm *advsm,
|
|||||||
/* SID, AType, SCA */
|
/* SID, AType, SCA */
|
||||||
sync_ind[24] = (advsm->adi >> 12);
|
sync_ind[24] = (advsm->adi >> 12);
|
||||||
sync_ind[24] |= !!(advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) << 4;
|
sync_ind[24] |= !!(advsm->flags & BLE_LL_ADV_SM_FLAG_TX_ADD) << 4;
|
||||||
sync_ind[24] |= MYNEWT_VAL(BLE_LL_MASTER_SCA) << 5;
|
sync_ind[24] |= BLE_LL_SCA_ENUM << 5;
|
||||||
|
|
||||||
/* PHY */
|
/* PHY */
|
||||||
sync_ind[25] = (0x01 << (advsm->sec_phy - 1));
|
sync_ind[25] = (0x01 << (advsm->sec_phy - 1));
|
||||||
@ -4836,6 +4839,11 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm)
|
|||||||
/* We don't need RF anymore */
|
/* We don't need RF anymore */
|
||||||
ble_ll_rfmgmt_release();
|
ble_ll_rfmgmt_release();
|
||||||
|
|
||||||
|
if (advsm->aux_dropped) {
|
||||||
|
ble_ll_adv_drop_event(advsm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (advsm->aux_not_scanned) {
|
if (advsm->aux_not_scanned) {
|
||||||
ble_ll_sched_rmv_elem(&aux_next->sch);
|
ble_ll_sched_rmv_elem(&aux_next->sch);
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,166 @@ STATS_NAME_END(ble_ll_conn_stats)
|
|||||||
|
|
||||||
static void ble_ll_conn_event_end(struct ble_npl_event *ev);
|
static void ble_ll_conn_event_end(struct ble_npl_event *ev);
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
struct ble_ll_conn_cth_flow {
|
||||||
|
bool enabled;
|
||||||
|
uint16_t max_buffers;
|
||||||
|
uint16_t num_buffers;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ble_ll_conn_cth_flow g_ble_ll_conn_cth_flow;
|
||||||
|
|
||||||
|
static struct ble_npl_event g_ble_ll_conn_cth_flow_error_ev;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ble_ll_conn_cth_flow_is_enabled(void)
|
||||||
|
{
|
||||||
|
return g_ble_ll_conn_cth_flow.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ble_ll_conn_cth_flow_alloc_credit(struct ble_ll_conn_sm *connsm)
|
||||||
|
{
|
||||||
|
struct ble_ll_conn_cth_flow *cth = &g_ble_ll_conn_cth_flow;
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
|
||||||
|
if (!cth->num_buffers) {
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
connsm->cth_flow_pending++;
|
||||||
|
cth->num_buffers--;
|
||||||
|
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_ll_conn_cth_flow_free_credit(struct ble_ll_conn_sm *connsm, uint16_t credits)
|
||||||
|
{
|
||||||
|
struct ble_ll_conn_cth_flow *cth = &g_ble_ll_conn_cth_flow;
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's not quite clear what we should do if host gives back more credits
|
||||||
|
* that we have allocated. For now let's just set invalid values back to
|
||||||
|
* sane values and continue.
|
||||||
|
*/
|
||||||
|
|
||||||
|
cth->num_buffers += credits;
|
||||||
|
if (cth->num_buffers > cth->max_buffers) {
|
||||||
|
cth->num_buffers = cth->max_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connsm->cth_flow_pending < credits) {
|
||||||
|
connsm->cth_flow_pending = 0;
|
||||||
|
} else {
|
||||||
|
connsm->cth_flow_pending -= credits;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_ll_conn_cth_flow_error_fn(struct ble_npl_event *ev)
|
||||||
|
{
|
||||||
|
struct ble_hci_ev *hci_ev;
|
||||||
|
struct ble_hci_ev_command_complete *hci_ev_cp;
|
||||||
|
uint16_t opcode;
|
||||||
|
|
||||||
|
hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
|
||||||
|
if (!hci_ev) {
|
||||||
|
/* Not much we can do anyway... */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We are here in case length of HCI_Host_Number_Of_Completed_Packets was
|
||||||
|
* invalid. We will send an error back to host and we can only hope host is
|
||||||
|
* reasonable and will do some actions to recover, e.g. it should disconnect
|
||||||
|
* all connections to guarantee that all credits are back in pool and we're
|
||||||
|
* back in sync (although spec does not really say what should happen).
|
||||||
|
*/
|
||||||
|
|
||||||
|
opcode = BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
|
||||||
|
BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS);
|
||||||
|
|
||||||
|
hci_ev->opcode = BLE_HCI_EVCODE_COMMAND_COMPLETE;
|
||||||
|
hci_ev->length = sizeof(*hci_ev_cp);
|
||||||
|
|
||||||
|
hci_ev_cp = (void *)hci_ev->data;
|
||||||
|
hci_ev_cp->num_packets = BLE_LL_CFG_NUM_HCI_CMD_PKTS;
|
||||||
|
hci_ev_cp->opcode = htole16(opcode);
|
||||||
|
hci_ev_cp->status = BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
|
||||||
|
ble_ll_hci_event_send(hci_ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_ll_conn_cth_flow_set_buffers(uint16_t num_buffers)
|
||||||
|
{
|
||||||
|
BLE_LL_ASSERT(num_buffers);
|
||||||
|
|
||||||
|
g_ble_ll_conn_cth_flow.max_buffers = num_buffers;
|
||||||
|
g_ble_ll_conn_cth_flow.num_buffers = num_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ble_ll_conn_cth_flow_enable(bool enabled)
|
||||||
|
{
|
||||||
|
struct ble_ll_conn_cth_flow *cth = &g_ble_ll_conn_cth_flow;
|
||||||
|
|
||||||
|
if (cth->enabled == enabled) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cth->enabled = enabled;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf)
|
||||||
|
{
|
||||||
|
const struct ble_hci_cmd *cmd;
|
||||||
|
const struct ble_hci_cb_host_num_comp_pkts_cp *cp;
|
||||||
|
struct ble_ll_conn_sm *connsm;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cmd = (const void *)cmdbuf;
|
||||||
|
cp = (const void *)cmd->data;
|
||||||
|
|
||||||
|
if (cmd->length != sizeof(cp->handles) + cp->handles * sizeof(cp->h[0])) {
|
||||||
|
ble_npl_eventq_put(&g_ble_ll_data.ll_evq, &g_ble_ll_conn_cth_flow_error_ev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < cp->handles; i++) {
|
||||||
|
/*
|
||||||
|
* It's probably ok that we do not have active connection with given
|
||||||
|
* handle - this can happen if disconnection already happened in LL but
|
||||||
|
* host sent credits back before processing disconnection event. In such
|
||||||
|
* case we can simply ignore command for that connection since credits
|
||||||
|
* are returned by LL already.
|
||||||
|
*/
|
||||||
|
connsm = ble_ll_conn_find_active_conn(cp->h[i].handle);
|
||||||
|
if (connsm) {
|
||||||
|
ble_ll_conn_cth_flow_free_credit(connsm, cp->h[i].count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
||||||
/**
|
/**
|
||||||
* Checks to see if we should start a PHY update procedure
|
* Checks to see if we should start a PHY update procedure
|
||||||
@ -332,7 +492,7 @@ ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Set time that we last serviced the schedule */
|
/* Set time that we last serviced the schedule */
|
||||||
if ((int32_t)(s1->last_scheduled - s2->last_scheduled) < 0) {
|
if (CPUTIME_LT(s1->last_scheduled, s2->last_scheduled)) {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
} else {
|
} else {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
@ -855,8 +1015,14 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm)
|
|||||||
/*
|
/*
|
||||||
* If we are encrypting, we are only allowed to send certain
|
* If we are encrypting, we are only allowed to send certain
|
||||||
* kinds of LL control PDU's. If none is enqueued, send empty pdu!
|
* kinds of LL control PDU's. If none is enqueued, send empty pdu!
|
||||||
|
*
|
||||||
|
* In Slave role, we are allowed to send unencrypted packets until
|
||||||
|
* LL_ENC_RSP is sent.
|
||||||
*/
|
*/
|
||||||
if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
|
if (((connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) &&
|
||||||
|
CONN_IS_MASTER(connsm)) ||
|
||||||
|
((connsm->enc_data.enc_state > CONN_ENC_S_ENC_RSP_TO_BE_SENT) &&
|
||||||
|
CONN_IS_SLAVE(connsm))) {
|
||||||
if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) {
|
if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) {
|
||||||
CONN_F_EMPTY_PDU_TXD(connsm) = 1;
|
CONN_F_EMPTY_PDU_TXD(connsm) = 1;
|
||||||
goto conn_tx_pdu;
|
goto conn_tx_pdu;
|
||||||
@ -991,7 +1157,7 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ticks = os_cputime_usecs_to_ticks(ticks);
|
ticks = os_cputime_usecs_to_ticks(ticks);
|
||||||
if ((int32_t)((os_cputime_get32() + ticks) - next_event_time) < 0) {
|
if (CPUTIME_LT(os_cputime_get32() + ticks, next_event_time)) {
|
||||||
md = 1;
|
md = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1450,10 +1616,10 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm)
|
|||||||
*/
|
*/
|
||||||
connsm->tx_win_size = BLE_LL_CONN_TX_WIN_MIN + 1;
|
connsm->tx_win_size = BLE_LL_CONN_TX_WIN_MIN + 1;
|
||||||
connsm->tx_win_off = 0;
|
connsm->tx_win_off = 0;
|
||||||
connsm->master_sca = MYNEWT_VAL(BLE_LL_MASTER_SCA);
|
connsm->master_sca = BLE_LL_SCA_ENUM;
|
||||||
|
|
||||||
/* Hop increment is a random value between 5 and 16. */
|
/* Hop increment is a random value between 5 and 16. */
|
||||||
connsm->hop_inc = (rand() % 12) + 5;
|
connsm->hop_inc = (ble_ll_rand() % 12) + 5;
|
||||||
|
|
||||||
/* Set channel map to map requested by host */
|
/* Set channel map to map requested by host */
|
||||||
connsm->num_used_chans = g_ble_ll_conn_params.num_used_chans;
|
connsm->num_used_chans = g_ble_ll_conn_params.num_used_chans;
|
||||||
@ -1462,7 +1628,7 @@ ble_ll_conn_master_common_init(struct ble_ll_conn_sm *connsm)
|
|||||||
|
|
||||||
/* Calculate random access address and crc initialization value */
|
/* Calculate random access address and crc initialization value */
|
||||||
connsm->access_addr = ble_ll_utils_calc_access_addr();
|
connsm->access_addr = ble_ll_utils_calc_access_addr();
|
||||||
connsm->crcinit = rand() & 0xffffff;
|
connsm->crcinit = ble_ll_rand() & 0xffffff;
|
||||||
|
|
||||||
/* Set initial schedule callback */
|
/* Set initial schedule callback */
|
||||||
connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
|
connsm->conn_sch.sched_cb = ble_ll_conn_event_start_cb;
|
||||||
@ -1861,6 +2027,10 @@ ble_ll_conn_end(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
|
|||||||
/* Remove from the active connection list */
|
/* Remove from the active connection list */
|
||||||
SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
|
SLIST_REMOVE(&g_ble_ll_conn_active_list, connsm, ble_ll_conn_sm, act_sle);
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
ble_ll_conn_cth_flow_free_credit(connsm, connsm->cth_flow_pending);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free the current transmit pdu if there is one. */
|
/* Free the current transmit pdu if there is one. */
|
||||||
if (connsm->cur_tx_pdu) {
|
if (connsm->cur_tx_pdu) {
|
||||||
os_mbuf_free_chain(connsm->cur_tx_pdu);
|
os_mbuf_free_chain(connsm->cur_tx_pdu);
|
||||||
@ -3239,6 +3409,13 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
|
|||||||
*/
|
*/
|
||||||
memcpy(init_addr, rl->rl_local_rpa, BLE_DEV_ADDR_LEN);
|
memcpy(init_addr, rl->rl_local_rpa, BLE_DEV_ADDR_LEN);
|
||||||
}
|
}
|
||||||
|
} else if (!ble_ll_is_rpa(adv_addr, adv_addr_type)) {
|
||||||
|
/* undirected with ID address, assure privacy if on RL */
|
||||||
|
rl = ble_ll_resolv_list_find(adv_addr, adv_addr_type);
|
||||||
|
if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
|
||||||
|
rl->rl_has_peer) {
|
||||||
|
goto init_rx_isr_exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3452,12 +3629,18 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
|
|||||||
uint16_t acl_hdr;
|
uint16_t acl_hdr;
|
||||||
struct ble_ll_conn_sm *connsm;
|
struct ble_ll_conn_sm *connsm;
|
||||||
|
|
||||||
if (BLE_MBUF_HDR_CRC_OK(hdr)) {
|
/* Packets with invalid CRC are not sent to LL */
|
||||||
|
BLE_LL_ASSERT(BLE_MBUF_HDR_CRC_OK(hdr));
|
||||||
|
|
||||||
/* XXX: there is a chance that the connection was thrown away and
|
/* XXX: there is a chance that the connection was thrown away and
|
||||||
re-used before processing packets here. Fix this. */
|
re-used before processing packets here. Fix this. */
|
||||||
/* We better have a connection state machine */
|
/* We better have a connection state machine */
|
||||||
connsm = ble_ll_conn_find_active_conn(hdr->rxinfo.handle);
|
connsm = ble_ll_conn_find_active_conn(hdr->rxinfo.handle);
|
||||||
if (connsm) {
|
if (!connsm) {
|
||||||
|
STATS_INC(ble_ll_conn_stats, no_conn_sm);
|
||||||
|
goto conn_rx_data_pdu_end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check state machine */
|
/* Check state machine */
|
||||||
ble_ll_conn_chk_csm_flags(connsm);
|
ble_ll_conn_chk_csm_flags(connsm);
|
||||||
|
|
||||||
@ -3471,8 +3654,7 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
|
|||||||
* Check that the LLID and payload length are reasonable.
|
* Check that the LLID and payload length are reasonable.
|
||||||
* Empty payload is only allowed for LLID == 01b.
|
* Empty payload is only allowed for LLID == 01b.
|
||||||
* */
|
* */
|
||||||
if ((llid == 0) ||
|
if ((llid == 0) || ((acl_len == 0) && (llid != BLE_LL_LLID_DATA_FRAG))) {
|
||||||
((acl_len == 0) && (llid != BLE_LL_LLID_DATA_FRAG))) {
|
|
||||||
STATS_INC(ble_ll_conn_stats, rx_bad_llid);
|
STATS_INC(ble_ll_conn_stats, rx_bad_llid);
|
||||||
goto conn_rx_data_pdu_end;
|
goto conn_rx_data_pdu_end;
|
||||||
}
|
}
|
||||||
@ -3483,11 +3665,15 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
|
|||||||
*
|
*
|
||||||
* Reference: Core 5.0, Vol 6, Part B, 5.1.3.1
|
* Reference: Core 5.0, Vol 6, Part B, 5.1.3.1
|
||||||
*/
|
*/
|
||||||
if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT) &&
|
if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT &&
|
||||||
!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
|
CONN_IS_MASTER(connsm)) ||
|
||||||
|
(connsm->enc_data.enc_state >= CONN_ENC_S_ENC_RSP_TO_BE_SENT &&
|
||||||
|
CONN_IS_SLAVE(connsm))) {
|
||||||
|
if (!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
|
||||||
ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
|
ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
|
||||||
goto conn_rx_data_pdu_end;
|
goto conn_rx_data_pdu_end;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
||||||
@ -3520,7 +3706,11 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
|
|||||||
* as the last received sequence number
|
* as the last received sequence number
|
||||||
*/
|
*/
|
||||||
rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
|
rxd_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
|
||||||
if (rxd_sn != connsm->last_rxd_sn) {
|
if (rxd_sn == connsm->last_rxd_sn) {
|
||||||
|
STATS_INC(ble_ll_conn_stats, data_pdu_rx_dup);
|
||||||
|
goto conn_rx_data_pdu_end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Update last rxd sn */
|
/* Update last rxd sn */
|
||||||
connsm->last_rxd_sn = rxd_sn;
|
connsm->last_rxd_sn = rxd_sn;
|
||||||
|
|
||||||
@ -3565,16 +3755,16 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
|
|||||||
|
|
||||||
/* NOTE: we dont free the mbuf since we handed it off! */
|
/* NOTE: we dont free the mbuf since we handed it off! */
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
STATS_INC(ble_ll_conn_stats, data_pdu_rx_dup);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
STATS_INC(ble_ll_conn_stats, no_conn_sm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free buffer */
|
/* Free buffer */
|
||||||
conn_rx_data_pdu_end:
|
conn_rx_data_pdu_end:
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
/* Need to give credit back if we allocated one for this PDU */
|
||||||
|
if (hdr->rxinfo.flags & BLE_MBUF_HDR_F_CONN_CREDIT) {
|
||||||
|
ble_ll_conn_cth_flow_free_credit(connsm, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
os_mbuf_free_chain(rxpdu);
|
os_mbuf_free_chain(rxpdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3595,7 +3785,6 @@ int
|
|||||||
ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int is_ctrl;
|
|
||||||
uint8_t hdr_byte;
|
uint8_t hdr_byte;
|
||||||
uint8_t hdr_sn;
|
uint8_t hdr_sn;
|
||||||
uint8_t hdr_nesn;
|
uint8_t hdr_nesn;
|
||||||
@ -3609,14 +3798,43 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
|||||||
uint32_t add_usecs;
|
uint32_t add_usecs;
|
||||||
struct os_mbuf *txpdu;
|
struct os_mbuf *txpdu;
|
||||||
struct ble_ll_conn_sm *connsm;
|
struct ble_ll_conn_sm *connsm;
|
||||||
struct os_mbuf *rxpdu;
|
struct os_mbuf *rxpdu = NULL;
|
||||||
struct ble_mbuf_hdr *txhdr;
|
struct ble_mbuf_hdr *txhdr;
|
||||||
int rx_phy_mode;
|
int rx_phy_mode;
|
||||||
|
bool alloc_rxpdu = true;
|
||||||
|
|
||||||
|
rc = -1;
|
||||||
|
connsm = g_ble_ll_conn_cur_sm;
|
||||||
|
|
||||||
/* Retrieve the header and payload length */
|
/* Retrieve the header and payload length */
|
||||||
hdr_byte = rxbuf[0];
|
hdr_byte = rxbuf[0];
|
||||||
rx_pyld_len = rxbuf[1];
|
rx_pyld_len = rxbuf[1];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to alloc rxpdu for packets with invalid CRC, we would throw them
|
||||||
|
* away instantly from LL anyway.
|
||||||
|
*/
|
||||||
|
if (!BLE_MBUF_HDR_CRC_OK(rxhdr)) {
|
||||||
|
alloc_rxpdu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
/*
|
||||||
|
* If flow control is enabled, we need to have credit available for each
|
||||||
|
* non-empty data packet that LL may send to host. If there are no credits
|
||||||
|
* available, we don't need to allocate buffer for this packet so LL will
|
||||||
|
* nak it.
|
||||||
|
*/
|
||||||
|
if (alloc_rxpdu && ble_ll_conn_cth_flow_is_enabled() &&
|
||||||
|
BLE_LL_LLID_IS_DATA(hdr_byte) && (rx_pyld_len > 0)) {
|
||||||
|
if (ble_ll_conn_cth_flow_alloc_credit(connsm)) {
|
||||||
|
rxhdr->rxinfo.flags |= BLE_MBUF_HDR_F_CONN_CREDIT;
|
||||||
|
} else {
|
||||||
|
alloc_rxpdu = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to attempt to allocate a buffer here. The reason we do this
|
* We need to attempt to allocate a buffer here. The reason we do this
|
||||||
* now is that we should not ack the packet if we have no receive
|
* now is that we should not ack the packet if we have no receive
|
||||||
@ -3624,14 +3842,14 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
|||||||
* acked, but we should not ack the received frame if we cant hand it up.
|
* acked, but we should not ack the received frame if we cant hand it up.
|
||||||
* NOTE: we hand up empty pdu's to the LL task!
|
* NOTE: we hand up empty pdu's to the LL task!
|
||||||
*/
|
*/
|
||||||
|
if (alloc_rxpdu) {
|
||||||
rxpdu = ble_ll_rxpdu_alloc(rx_pyld_len + BLE_LL_PDU_HDR_LEN);
|
rxpdu = ble_ll_rxpdu_alloc(rx_pyld_len + BLE_LL_PDU_HDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should have a current connection state machine. If we dont, we just
|
* We should have a current connection state machine. If we dont, we just
|
||||||
* hand the packet to the higher layer to count it.
|
* hand the packet to the higher layer to count it.
|
||||||
*/
|
*/
|
||||||
rc = -1;
|
|
||||||
connsm = g_ble_ll_conn_cur_sm;
|
|
||||||
if (!connsm) {
|
if (!connsm) {
|
||||||
STATS_INC(ble_ll_conn_stats, rx_data_pdu_no_conn);
|
STATS_INC(ble_ll_conn_stats, rx_data_pdu_no_conn);
|
||||||
goto conn_exit;
|
goto conn_exit;
|
||||||
@ -3693,9 +3911,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
|||||||
/* Set last received header byte */
|
/* Set last received header byte */
|
||||||
connsm->last_rxd_hdr_byte = hdr_byte;
|
connsm->last_rxd_hdr_byte = hdr_byte;
|
||||||
|
|
||||||
is_ctrl = 0;
|
if (BLE_LL_LLID_IS_CTRL(hdr_byte)) {
|
||||||
if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
|
|
||||||
is_ctrl = 1;
|
|
||||||
opcode = rxbuf[2];
|
opcode = rxbuf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3784,7 +4000,7 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
|||||||
/* Adjust payload for max TX time and octets */
|
/* Adjust payload for max TX time and octets */
|
||||||
|
|
||||||
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
||||||
if (is_ctrl &&
|
if (BLE_LL_LLID_IS_CTRL(hdr_byte) &&
|
||||||
(connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) &&
|
(connsm->conn_role == BLE_LL_CONN_ROLE_SLAVE) &&
|
||||||
(opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) {
|
(opcode == BLE_LL_CTRL_PHY_UPDATE_IND)) {
|
||||||
connsm->phy_tx_transition =
|
connsm->phy_tx_transition =
|
||||||
@ -3803,8 +4019,9 @@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
|
|||||||
/* If this is a TERMINATE_IND, we have to reply */
|
/* If this is a TERMINATE_IND, we have to reply */
|
||||||
chk_rx_terminate_ind:
|
chk_rx_terminate_ind:
|
||||||
/* If we received a terminate IND, we must set some flags */
|
/* If we received a terminate IND, we must set some flags */
|
||||||
if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND)
|
if (BLE_LL_LLID_IS_CTRL(hdr_byte) &&
|
||||||
&& (rx_pyld_len == (1 + BLE_LL_CTRL_TERMINATE_IND_LEN))) {
|
(opcode == BLE_LL_CTRL_TERMINATE_IND) &&
|
||||||
|
(rx_pyld_len == (1 + BLE_LL_CTRL_TERMINATE_IND_LEN))) {
|
||||||
connsm->csmflags.cfbit.terminate_ind_rxd = 1;
|
connsm->csmflags.cfbit.terminate_ind_rxd = 1;
|
||||||
connsm->rxd_disconnect_reason = rxbuf[3];
|
connsm->rxd_disconnect_reason = rxbuf[3];
|
||||||
}
|
}
|
||||||
@ -4226,6 +4443,12 @@ ble_ll_conn_module_reset(void)
|
|||||||
g_ble_ll_conn_sync_transfer_params.mode = 0;
|
g_ble_ll_conn_sync_transfer_params.mode = 0;
|
||||||
g_ble_ll_conn_sync_transfer_params.sync_timeout_us = 0;
|
g_ble_ll_conn_sync_transfer_params.sync_timeout_us = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
g_ble_ll_conn_cth_flow.enabled = false;
|
||||||
|
g_ble_ll_conn_cth_flow.max_buffers = 1;
|
||||||
|
g_ble_ll_conn_cth_flow.num_buffers = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the connection module */
|
/* Initialize the connection module */
|
||||||
@ -4265,6 +4488,11 @@ ble_ll_conn_module_init(void)
|
|||||||
"ble_ll_conn");
|
"ble_ll_conn");
|
||||||
BLE_LL_ASSERT(rc == 0);
|
BLE_LL_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
ble_npl_event_init(&g_ble_ll_conn_cth_flow_error_ev,
|
||||||
|
ble_ll_conn_cth_flow_error_fn, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Call reset to finish reset of initialization */
|
/* Call reset to finish reset of initialization */
|
||||||
ble_ll_conn_module_reset();
|
ble_ll_conn_module_reset();
|
||||||
}
|
}
|
||||||
|
@ -1128,16 +1128,11 @@ ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ble_ll_conn_hci_disconnect_cmd(const uint8_t *cmdbuf, uint8_t len)
|
ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
struct ble_ll_conn_sm *connsm;
|
struct ble_ll_conn_sm *connsm;
|
||||||
const struct ble_hci_lc_disconnect_cp *cmd = (const void *) cmdbuf;
|
|
||||||
|
|
||||||
if (len != sizeof (*cmd)) {
|
|
||||||
return BLE_ERR_INV_HCI_CMD_PARMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for valid parameters */
|
/* Check for valid parameters */
|
||||||
handle = le16toh(cmd->conn_handle);
|
handle = le16toh(cmd->conn_handle);
|
||||||
@ -1565,6 +1560,34 @@ ltk_key_cmd_complete:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
int
|
||||||
|
ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len,
|
||||||
|
uint8_t *rspbuf, uint8_t *rsplen)
|
||||||
|
{
|
||||||
|
const struct ble_hci_le_request_peer_sca_cp *params = (const void *)cmdbuf;
|
||||||
|
struct ble_ll_conn_sm *connsm;
|
||||||
|
|
||||||
|
connsm = ble_ll_conn_find_active_conn(params->conn_handle);
|
||||||
|
if (!connsm) {
|
||||||
|
return BLE_ERR_UNK_CONN_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(connsm->remote_features[2] & (BLE_LL_FEAT_SCA_UPDATE >> 24))) {
|
||||||
|
return BLE_ERR_UNSUPP_REM_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_PENDING_CTRL_PROC(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE)) {
|
||||||
|
/* Not really specified what we should return */
|
||||||
|
return BLE_ERR_CTLR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_ll_ctrl_proc_start(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
||||||
/**
|
/**
|
||||||
* Read authenticated payload timeout (OGF=3, OCF==0x007B)
|
* Read authenticated payload timeout (OGF=3, OCF==0x007B)
|
||||||
|
@ -164,7 +164,7 @@ bool ble_ll_conn_init_pending_aux_conn_rsp(void);
|
|||||||
void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm,
|
void ble_ll_disconn_comp_event_send(struct ble_ll_conn_sm *connsm,
|
||||||
uint8_t reason);
|
uint8_t reason);
|
||||||
void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm);
|
void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm);
|
||||||
int ble_ll_conn_hci_disconnect_cmd(const uint8_t *cmdbuf, uint8_t len);
|
int ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd);
|
||||||
int ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len);
|
int ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len);
|
||||||
int ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len);
|
int ble_ll_conn_create(const uint8_t *cmdbuf, uint8_t len);
|
||||||
int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len);
|
int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len);
|
||||||
@ -196,12 +196,23 @@ int ble_ll_conn_hci_wr_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len,
|
|||||||
uint8_t *rspbuf, uint8_t *rsplen);
|
uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
int ble_ll_conn_hci_rd_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len,
|
int ble_ll_conn_hci_rd_auth_pyld_tmo(const uint8_t *cmdbuf, uint8_t len,
|
||||||
uint8_t *rspbuf, uint8_t *rsplen);
|
uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
int ble_ll_conn_req_peer_sca(const uint8_t *cmdbuf, uint8_t len,
|
||||||
|
uint8_t *rspbuf, uint8_t *rsplen);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING)
|
||||||
void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm);
|
void ble_ll_conn_auth_pyld_timer_start(struct ble_ll_conn_sm *connsm);
|
||||||
#else
|
#else
|
||||||
#define ble_ll_conn_auth_pyld_timer_start(x)
|
#define ble_ll_conn_auth_pyld_timer_start(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
void ble_ll_conn_cth_flow_set_buffers(uint16_t num_buffers);
|
||||||
|
bool ble_ll_conn_cth_flow_enable(bool enabled);
|
||||||
|
void ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg);
|
int ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg);
|
||||||
int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg);
|
int ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg);
|
||||||
|
|
||||||
|
@ -112,6 +112,10 @@ const uint8_t g_ble_ll_ctrl_pkt_lengths[BLE_LL_CTRL_OPCODES] =
|
|||||||
BLE_LL_CTRL_PERIODIC_SYNC_IND_LEN,
|
BLE_LL_CTRL_PERIODIC_SYNC_IND_LEN,
|
||||||
BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN,
|
BLE_LL_CTRL_CLOCK_ACCURACY_REQ_LEN,
|
||||||
BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN,
|
BLE_LL_CTRL_CLOCK_ACCURACY_RSP_LEN,
|
||||||
|
BLE_LL_CTRL_CIS_REQ_LEN,
|
||||||
|
BLE_LL_CTRL_CIS_RSP_LEN,
|
||||||
|
BLE_LL_CTRL_CIS_IND_LEN,
|
||||||
|
BLE_LL_CTRL_CIS_TERMINATE_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -505,6 +509,12 @@ ble_ll_ctrl_proc_unk_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr, uint8_t *
|
|||||||
ble_ll_ctrl_phy_update_cancel(connsm, BLE_ERR_UNSUPP_REM_FEATURE);
|
ble_ll_ctrl_phy_update_cancel(connsm, BLE_ERR_UNSUPP_REM_FEATURE);
|
||||||
ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE;
|
ctrl_proc = BLE_LL_CTRL_PROC_PHY_UPDATE;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_LL_CTRL_CLOCK_ACCURACY_REQ:
|
||||||
|
ble_ll_hci_ev_sca_update(connsm, BLE_ERR_UNSUPPORTED, 0);
|
||||||
|
ctrl_proc = BLE_LL_CTRL_PROC_SCA_UPDATE;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ctrl_proc = BLE_LL_CTRL_PROC_NUM;
|
ctrl_proc = BLE_LL_CTRL_PROC_NUM;
|
||||||
@ -836,6 +846,20 @@ ble_ll_ctrl_phy_req_rsp_make(struct ble_ll_conn_sm *connsm, uint8_t *ctrdata)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
/**
|
||||||
|
* Create a LL_CLOCK_ACCURACY_REQ or LL_CLOCK_ACCURACY_RSP pdu
|
||||||
|
*
|
||||||
|
* @param connsm Pointer to connection state machine
|
||||||
|
* @param ctrdata: Pointer to where CtrData starts in pdu
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ble_ll_ctrl_sca_req_rsp_make(struct ble_ll_conn_sm *connsm, uint8_t *ctrdata)
|
||||||
|
{
|
||||||
|
ctrdata[0] = BLE_LL_SCA_ENUM;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req,
|
ble_ll_ctrl_rx_phy_req(struct ble_ll_conn_sm *connsm, uint8_t *req,
|
||||||
uint8_t *rsp)
|
uint8_t *rsp)
|
||||||
@ -1040,11 +1064,70 @@ ble_ll_ctrl_rx_periodic_sync_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
|
|||||||
connsm->sync_transfer_skip,
|
connsm->sync_transfer_skip,
|
||||||
connsm->sync_transfer_sync_timeout);
|
connsm->sync_transfer_sync_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BLE_ERR_MAX;
|
return BLE_ERR_MAX;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
/**
|
||||||
|
* Called when a BLE_LL_CTRL_CLOCK_ACCURACY_REQ PDU is received
|
||||||
|
*
|
||||||
|
* @param connsm
|
||||||
|
* @param dptr
|
||||||
|
* @param rsp Pointer to CtrData of BLE_LL_CTRL_CLOCK_ACCURACY_RSP.
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
static uint8_t
|
||||||
|
ble_ll_ctrl_rx_sca_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
|
||||||
|
uint8_t *rsp)
|
||||||
|
{
|
||||||
|
ble_ll_ctrl_sca_req_rsp_make(connsm, rsp);
|
||||||
|
return BLE_LL_CTRL_CLOCK_ACCURACY_RSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a BLE_LL_CTRL_CLOCK_ACCURACY_RSP PDU is received
|
||||||
|
*
|
||||||
|
* @param connsm
|
||||||
|
* @param dptr
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
static uint8_t
|
||||||
|
ble_ll_ctrl_rx_sca_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
|
||||||
|
{
|
||||||
|
if (connsm->cur_ctrl_proc != BLE_LL_CTRL_PROC_SCA_UPDATE) {
|
||||||
|
return BLE_LL_CTRL_UNKNOWN_RSP;
|
||||||
|
}
|
||||||
|
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE);
|
||||||
|
ble_ll_hci_ev_sca_update(connsm, BLE_ERR_SUCCESS, dptr[0]);
|
||||||
|
return BLE_ERR_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
static uint8_t
|
||||||
|
ble_ll_ctrl_rx_cis_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
|
||||||
|
uint8_t *rspdata)
|
||||||
|
{
|
||||||
|
return BLE_LL_CTRL_UNKNOWN_RSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
ble_ll_ctrl_rx_cis_rsp(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
|
||||||
|
uint8_t *rspdata)
|
||||||
|
{
|
||||||
|
return BLE_LL_CTRL_UNKNOWN_RSP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
ble_ll_ctrl_rx_cis_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
|
||||||
|
{
|
||||||
|
return BLE_LL_CTRL_UNKNOWN_RSP;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* Create a link layer length request or length response PDU.
|
* Create a link layer length request or length response PDU.
|
||||||
*
|
*
|
||||||
@ -1250,6 +1333,15 @@ ble_ll_ctrl_start_enc_send(struct ble_ll_conn_sm *connsm)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
static void
|
||||||
|
ble_ll_ctrl_cis_create(struct ble_ll_conn_sm *connsm, uint8_t *dptr)
|
||||||
|
{
|
||||||
|
/* TODO Implement */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a link layer control "encrypt request" PDU.
|
* Create a link layer control "encrypt request" PDU.
|
||||||
*
|
*
|
||||||
@ -1351,7 +1443,7 @@ ble_ll_ctrl_rx_enc_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
|
|||||||
return BLE_LL_CTRL_UNKNOWN_RSP;
|
return BLE_LL_CTRL_UNKNOWN_RSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT;
|
connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_TO_BE_SENT;
|
||||||
|
|
||||||
/* In case we were already encrypted we need to reset packet counters */
|
/* In case we were already encrypted we need to reset packet counters */
|
||||||
connsm->enc_data.rx_pkt_cntr = 0;
|
connsm->enc_data.rx_pkt_cntr = 0;
|
||||||
@ -1676,6 +1768,12 @@ ble_ll_ctrl_rx_reject_ind(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
|
|||||||
*/
|
*/
|
||||||
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
|
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_DATA_LEN_UPD);
|
||||||
break;
|
break;
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_LL_CTRL_PROC_SCA_UPDATE:
|
||||||
|
ble_ll_hci_ev_sca_update(connsm, ble_error, 0);
|
||||||
|
ble_ll_ctrl_proc_stop(connsm, BLE_LL_CTRL_PROC_SCA_UPDATE);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2138,6 +2236,18 @@ ble_ll_ctrl_proc_init(struct ble_ll_conn_sm *connsm, int ctrl_proc)
|
|||||||
opcode = BLE_LL_CTRL_PHY_REQ;
|
opcode = BLE_LL_CTRL_PHY_REQ;
|
||||||
ble_ll_ctrl_phy_req_rsp_make(connsm, ctrdata);
|
ble_ll_ctrl_phy_req_rsp_make(connsm, ctrdata);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_LL_CTRL_PROC_SCA_UPDATE:
|
||||||
|
opcode = BLE_LL_CTRL_CLOCK_ACCURACY_REQ;
|
||||||
|
ble_ll_ctrl_sca_req_rsp_make(connsm, ctrdata);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
case BLE_LL_CTRL_PROC_CIS_CREATE:
|
||||||
|
opcode = BLE_LL_CTRL_CIS_REQ;
|
||||||
|
ble_ll_ctrl_cis_create(connsm, ctrdata);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
BLE_LL_ASSERT(0);
|
BLE_LL_ASSERT(0);
|
||||||
@ -2568,6 +2678,26 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om)
|
|||||||
rsp_opcode = ble_ll_ctrl_rx_phy_update_ind(connsm, dptr);
|
rsp_opcode = ble_ll_ctrl_rx_phy_update_ind(connsm, dptr);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_LL_CTRL_CLOCK_ACCURACY_REQ:
|
||||||
|
rsp_opcode = ble_ll_ctrl_rx_sca_req(connsm, dptr, rspdata);
|
||||||
|
break;
|
||||||
|
case BLE_LL_CTRL_CLOCK_ACCURACY_RSP:
|
||||||
|
rsp_opcode = ble_ll_ctrl_rx_sca_rsp(connsm, dptr);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
case BLE_LL_CTRL_CIS_REQ:
|
||||||
|
rsp_opcode = ble_ll_ctrl_rx_cis_req(connsm, dptr, rspdata);
|
||||||
|
break;
|
||||||
|
case BLE_LL_CTRL_CIS_RSP:
|
||||||
|
rsp_opcode = ble_ll_ctrl_rx_cis_rsp(connsm, dptr, rspdata);
|
||||||
|
break;
|
||||||
|
case BLE_LL_CTRL_CIS_IND:
|
||||||
|
rsp_opcode = ble_ll_ctrl_rx_cis_ind(connsm, dptr);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
|
||||||
case BLE_LL_CTRL_PERIODIC_SYNC_IND:
|
case BLE_LL_CTRL_PERIODIC_SYNC_IND:
|
||||||
rsp_opcode = ble_ll_ctrl_rx_periodic_sync_ind(connsm, dptr);
|
rsp_opcode = ble_ll_ctrl_rx_periodic_sync_ind(connsm, dptr);
|
||||||
@ -2709,6 +2839,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm)
|
|||||||
connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_WAIT;
|
connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_WAIT;
|
||||||
break;
|
break;
|
||||||
case BLE_LL_CTRL_ENC_RSP:
|
case BLE_LL_CTRL_ENC_RSP:
|
||||||
|
connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT;
|
||||||
connsm->csmflags.cfbit.send_ltk_req = 1;
|
connsm->csmflags.cfbit.send_ltk_req = 1;
|
||||||
break;
|
break;
|
||||||
case BLE_LL_CTRL_START_ENC_RSP:
|
case BLE_LL_CTRL_START_ENC_RSP:
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "controller/ble_ll_whitelist.h"
|
#include "controller/ble_ll_whitelist.h"
|
||||||
#include "controller/ble_ll_resolv.h"
|
#include "controller/ble_ll_resolv.h"
|
||||||
#include "controller/ble_ll_sync.h"
|
#include "controller/ble_ll_sync.h"
|
||||||
|
#include "controller/ble_ll_iso.h"
|
||||||
#include "ble_ll_priv.h"
|
#include "ble_ll_priv.h"
|
||||||
#include "ble_ll_conn_priv.h"
|
#include "ble_ll_conn_priv.h"
|
||||||
|
|
||||||
@ -327,6 +328,31 @@ ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen)
|
|||||||
return BLE_ERR_SUCCESS;
|
return BLE_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
/**
|
||||||
|
* HCI read buffer size v2 command. Returns the ACL and ISO data packet length and
|
||||||
|
* num data packets.
|
||||||
|
*
|
||||||
|
* @param rspbuf Pointer to response buffer
|
||||||
|
* @param rsplen Length of response buffer
|
||||||
|
*
|
||||||
|
* @return int BLE error code
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ble_ll_hci_le_read_bufsize_v2(uint8_t *rspbuf, uint8_t *rsplen)
|
||||||
|
{
|
||||||
|
struct ble_hci_le_rd_buf_size_v2_rp *rp = (void *) rspbuf;
|
||||||
|
|
||||||
|
rp->data_len = htole16(g_ble_ll_data.ll_acl_pkt_size);
|
||||||
|
rp->data_packets = g_ble_ll_data.ll_num_acl_pkts;
|
||||||
|
rp->iso_data_len = 0;
|
||||||
|
rp->iso_data_packets = 0;
|
||||||
|
|
||||||
|
*rsplen = sizeof(*rp);
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
|
||||||
/**
|
/**
|
||||||
* Checks the preferred phy masks for validity and places the preferred masks
|
* Checks the preferred phy masks for validity and places the preferred masks
|
||||||
@ -618,6 +644,9 @@ ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf)
|
|||||||
case BLE_HCI_OCF_LE_GEN_DHKEY:
|
case BLE_HCI_OCF_LE_GEN_DHKEY:
|
||||||
case BLE_HCI_OCF_LE_SET_PHY:
|
case BLE_HCI_OCF_LE_SET_PHY:
|
||||||
case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC:
|
case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC:
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_HCI_OCF_LE_REQ_PEER_SCA:
|
||||||
|
#endif
|
||||||
rc = 1;
|
rc = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1149,10 +1178,77 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
|
|||||||
rc = ble_ll_set_default_sync_transfer_params(cmdbuf, len);
|
rc = ble_ll_set_default_sync_transfer_params(cmdbuf, len);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
case BLE_HCI_OCF_LE_READ_ISO_TX_SYNC:
|
||||||
|
rc = ble_ll_iso_read_tx_sync(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_SET_CIG_PARAM:
|
||||||
|
rc = ble_ll_iso_set_cig_param(cmdbuf, len, rspbuf, rsplen);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_CREATE_CIS:
|
||||||
|
rc = ble_ll_iso_create_cis(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_REMOVE_CIG:
|
||||||
|
rc = ble_ll_iso_remove_cig(cmdbuf, len, rspbuf, rsplen);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_ACCEPT_CIS_REQ:
|
||||||
|
rc = ble_ll_iso_accept_cis_req(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_REJECT_CIS_REQ:
|
||||||
|
rc = ble_ll_iso_reject_cis_req(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_CREATE_BIG:
|
||||||
|
rc = ble_ll_iso_create_big(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_TERMINATE_BIG:
|
||||||
|
rc = ble_ll_iso_terminate_big(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_BIG_CREATE_SYNC:
|
||||||
|
rc = ble_ll_iso_big_create_sync(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC:
|
||||||
|
rc = ble_ll_iso_big_terminate_sync(cmdbuf,len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH:
|
||||||
|
rc = ble_ll_iso_setup_iso_data_path(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH:
|
||||||
|
rc = ble_ll_iso_remove_iso_data_path(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_RD_BUF_SIZE_V2:
|
||||||
|
rc = ble_ll_hci_le_read_bufsize_v2(rspbuf, rsplen);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST)
|
||||||
|
case BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST:
|
||||||
|
rc = ble_ll_iso_set_cig_param_test(cmdbuf, len, rspbuf, rsplen);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_CREATE_BIG_TEST:
|
||||||
|
rc = ble_ll_iso_create_big_test(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST:
|
||||||
|
rc = ble_ll_iso_transmit_test(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_ISO_RECEIVE_TEST:
|
||||||
|
rc = ble_ll_iso_receive_test(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS:
|
||||||
|
rc = ble_ll_iso_read_counters_test(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_LE_ISO_TEST_END:
|
||||||
|
rc = ble_ll_iso_end_test(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if MYNEWT_VAL(BLE_VERSION) >= 52
|
#if MYNEWT_VAL(BLE_VERSION) >= 52
|
||||||
case BLE_HCI_OCF_LE_SET_HOST_FEAT:
|
case BLE_HCI_OCF_LE_SET_HOST_FEAT:
|
||||||
rc = ble_ll_set_host_feat(cmdbuf, len);
|
rc = ble_ll_set_host_feat(cmdbuf, len);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
case BLE_HCI_OCF_LE_REQ_PEER_SCA:
|
||||||
|
rc = ble_ll_conn_req_peer_sca(cmdbuf, len,
|
||||||
|
rspbuf, rsplen);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
rc = BLE_ERR_UNKNOWN_HCI_CMD;
|
rc = BLE_ERR_UNKNOWN_HCI_CMD;
|
||||||
@ -1174,6 +1270,26 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ble_ll_hci_disconnect(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
const struct ble_hci_lc_disconnect_cp *cmd;
|
||||||
|
|
||||||
|
cmd = (const void *) cmdbuf;
|
||||||
|
|
||||||
|
if (len != sizeof (*cmd)) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
if (le16toh(cmd->conn_handle) >= BLE_LL_CONN_HANDLE_ISO_OFFSET) {
|
||||||
|
return ble_ll_iso_disconnect_cmd(cmd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ble_ll_conn_hci_disconnect_cmd(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a link control command sent from the host to the controller. The HCI
|
* Process a link control command sent from the host to the controller. The HCI
|
||||||
* command has a 3 byte command header followed by data. The header is:
|
* command has a 3 byte command header followed by data. The header is:
|
||||||
@ -1194,7 +1310,7 @@ ble_ll_hci_link_ctrl_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf)
|
|||||||
|
|
||||||
switch (ocf) {
|
switch (ocf) {
|
||||||
case BLE_HCI_OCF_DISCONNECT_CMD:
|
case BLE_HCI_OCF_DISCONNECT_CMD:
|
||||||
rc = ble_ll_conn_hci_disconnect_cmd(cmdbuf, len);
|
rc = ble_ll_hci_disconnect(cmdbuf, len);
|
||||||
/* Send command status instead of command complete */
|
/* Send command status instead of command complete */
|
||||||
rc += (BLE_ERR_MAX + 1);
|
rc += (BLE_ERR_MAX + 1);
|
||||||
break;
|
break;
|
||||||
@ -1227,6 +1343,64 @@ ble_ll_hci_cb_set_event_mask(const uint8_t *cmdbuf, uint8_t len)
|
|||||||
return BLE_ERR_SUCCESS;
|
return BLE_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
static int
|
||||||
|
ble_ll_hci_cb_set_ctrlr_to_host_fc(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
const struct ble_hci_cb_ctlr_to_host_fc_cp *cmd = (const void *) cmdbuf;
|
||||||
|
|
||||||
|
if (len != sizeof (*cmd)) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only allow to either disable flow control or enable for ACL only */
|
||||||
|
if (cmd->enable > 1) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ble_ll_conn_cth_flow_enable(cmd->enable)) {
|
||||||
|
return BLE_ERR_CMD_DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ble_ll_hci_cb_host_buf_size(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
const struct ble_hci_cb_host_buf_size_cp *cmd = (const void *) cmdbuf;
|
||||||
|
uint16_t acl_num;
|
||||||
|
uint16_t acl_data_len;
|
||||||
|
|
||||||
|
if (len != sizeof (*cmd)) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We do not support SCO so those parameters should be set to 0 */
|
||||||
|
if (cmd->sco_num || cmd->sco_data_len) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Core 5.2 Vol 4 Part E section 7.3.39 states that "Both the Host and the
|
||||||
|
* Controller shall support command and event packets, where the data portion
|
||||||
|
* (excluding header) contained in the packets is 255 octets in size.".
|
||||||
|
* This means we can basically accept any allowed value since LL does not
|
||||||
|
* reassemble incoming data thus will not send more than 255 octets in single
|
||||||
|
* data packet.
|
||||||
|
*/
|
||||||
|
acl_num = le16toh(cmd->acl_num);
|
||||||
|
acl_data_len = le16toh(cmd->acl_data_len);
|
||||||
|
if (acl_data_len < 255) {
|
||||||
|
return BLE_ERR_INV_HCI_CMD_PARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_ll_conn_cth_flow_set_buffers(acl_num);
|
||||||
|
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ble_ll_hci_cb_set_event_mask2(const uint8_t *cmdbuf, uint8_t len)
|
ble_ll_hci_cb_set_event_mask2(const uint8_t *cmdbuf, uint8_t len)
|
||||||
{
|
{
|
||||||
@ -1259,6 +1433,22 @@ ble_ll_hci_ctlr_bb_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
|
|||||||
rc = ble_ll_reset();
|
rc = ble_ll_reset();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
case BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC:
|
||||||
|
rc = ble_ll_hci_cb_set_ctrlr_to_host_fc(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_CB_HOST_BUF_SIZE:
|
||||||
|
rc = ble_ll_hci_cb_host_buf_size(cmdbuf, len);
|
||||||
|
break;
|
||||||
|
case BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS:
|
||||||
|
/*
|
||||||
|
* HCI_Host_Number_Of_Completed_Packets is handled immediately when
|
||||||
|
* received from transport so we should never receive it here.
|
||||||
|
*/
|
||||||
|
BLE_LL_ASSERT(0);
|
||||||
|
rc = BLE_ERR_UNKNOWN_HCI_CMD;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case BLE_HCI_OCF_CB_SET_EVENT_MASK2:
|
case BLE_HCI_OCF_CB_SET_EVENT_MASK2:
|
||||||
rc = ble_ll_hci_cb_set_event_mask2(cmdbuf, len);
|
rc = ble_ll_hci_cb_set_event_mask2(cmdbuf, len);
|
||||||
break;
|
break;
|
||||||
@ -1454,9 +1644,33 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev)
|
|||||||
* BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion.
|
* BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg)
|
ble_ll_hci_cmd_rx(uint8_t *cmdbuf, void *arg)
|
||||||
{
|
{
|
||||||
struct ble_npl_event *ev;
|
struct ble_npl_event *ev;
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
const struct ble_hci_cmd *cmd;
|
||||||
|
uint16_t opcode;
|
||||||
|
uint16_t ocf;
|
||||||
|
uint16_t ogf;
|
||||||
|
|
||||||
|
cmd = (const void *)cmdbuf;
|
||||||
|
opcode = le16toh(cmd->opcode);
|
||||||
|
ogf = BLE_HCI_OGF(opcode);
|
||||||
|
ocf = BLE_HCI_OCF(opcode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HCI_Host_Number_Of_Completed_Packets is processed outside standard flow
|
||||||
|
* thus it can be sent at any time, even if another command is already
|
||||||
|
* pending. This means we should better process it here and send an event to
|
||||||
|
* LL in case of error.
|
||||||
|
*/
|
||||||
|
if ((ogf == BLE_HCI_OGF_CTLR_BASEBAND) &&
|
||||||
|
(ocf == BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS)) {
|
||||||
|
ble_ll_conn_cth_flow_process_cmd(cmdbuf);
|
||||||
|
ble_hci_trans_buf_free(cmdbuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get an event structure off the queue */
|
/* Get an event structure off the queue */
|
||||||
ev = &g_ble_ll_hci_cmd_ev;
|
ev = &g_ble_ll_hci_cmd_ev;
|
||||||
@ -1465,7 +1679,7 @@ ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill out the event and post to Link Layer */
|
/* Fill out the event and post to Link Layer */
|
||||||
ble_npl_event_set_arg(ev, cmd);
|
ble_npl_event_set_arg(ev, cmdbuf);
|
||||||
ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev);
|
ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -461,6 +461,37 @@ ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
void
|
||||||
|
ble_ll_hci_ev_sca_update(struct ble_ll_conn_sm *connsm, uint8_t status,
|
||||||
|
uint8_t peer_sca)
|
||||||
|
{
|
||||||
|
struct ble_hci_ev_le_subev_peer_sca_complete *ev;
|
||||||
|
struct ble_hci_ev *hci_ev;
|
||||||
|
|
||||||
|
if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hci_ev = (void *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
|
||||||
|
if (!hci_ev) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hci_ev->opcode = BLE_HCI_EVCODE_LE_META;
|
||||||
|
hci_ev->length = sizeof(*ev);
|
||||||
|
ev = (void *) hci_ev->data;
|
||||||
|
|
||||||
|
ev->subev_code = BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP;
|
||||||
|
ev->status = status;
|
||||||
|
ev->conn_handle = htole16(connsm->conn_handle);
|
||||||
|
ev->sca = peer_sca;
|
||||||
|
|
||||||
|
ble_ll_hci_event_send(hci_ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line)
|
ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line)
|
||||||
{
|
{
|
||||||
|
146
src/libs/mynewt-nimble/nimble/controller/src/ble_ll_iso.c
Normal file
146
src/libs/mynewt-nimble/nimble/controller/src/ble_ll_iso.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 "syscfg/syscfg.h"
|
||||||
|
#include "nimble/ble.h"
|
||||||
|
#include "nimble/hci_common.h"
|
||||||
|
#include "controller/ble_ll_iso.h"
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_read_tx_sync(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_set_cig_param(const uint8_t *cmdbuf, uint8_t len,
|
||||||
|
uint8_t *rspbuf, uint8_t *rsplen)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_create_cis(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_remove_cig(const uint8_t *cmdbuf, uint8_t len,
|
||||||
|
uint8_t *rspbuf, uint8_t *rsplen)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_accept_cis_req(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_reject_cis_req(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_setup_iso_data_path(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_remove_iso_data_path(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
/* Nothing to do here for now when HCI is supported */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int
|
||||||
|
ble_ll_iso_create_big(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_terminate_big(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_big_create_sync(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_big_terminate_sync(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO_TEST)
|
||||||
|
int
|
||||||
|
ble_ll_iso_set_cig_param_test(const uint8_t *cmdbuf, uint8_t len,
|
||||||
|
uint8_t *rspbuf, uint8_t *rsplen)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_create_big_test(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_transmit_test(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_receive_test(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_read_counters_test(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_ll_iso_end_test(const uint8_t *cmdbuf, uint8_t len)
|
||||||
|
{
|
||||||
|
return BLE_ERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -17,6 +17,9 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* for jrand48 */
|
||||||
|
#define _XOPEN_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -120,6 +123,21 @@ ble_ll_rand_data_get(uint8_t *buf, uint8_t len)
|
|||||||
return BLE_ERR_SUCCESS;
|
return BLE_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simple wrapper to allow easy replacement of rand() */
|
||||||
|
uint32_t
|
||||||
|
ble_ll_rand(void)
|
||||||
|
{
|
||||||
|
static unsigned short xsubi[3];
|
||||||
|
static bool init = true;
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
init = false;
|
||||||
|
ble_ll_rand_data_get((uint8_t *)xsubi, sizeof(xsubi));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t) jrand48(xsubi);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to obtain a "prand" as defined in core V4.2 Vol 6 Part B 1.3.2.2
|
* Called to obtain a "prand" as defined in core V4.2 Vol 6 Part B 1.3.2.2
|
||||||
*
|
*
|
||||||
|
@ -293,7 +293,7 @@ ble_ll_scan_req_backoff(struct ble_ll_scan_sm *scansm, int success)
|
|||||||
STATS_INC(ble_ll_stats, scan_req_txf);
|
STATS_INC(ble_ll_stats, scan_req_txf);
|
||||||
}
|
}
|
||||||
|
|
||||||
scansm->backoff_count = rand() & (scansm->upper_limit - 1);
|
scansm->backoff_count = ble_ll_rand() & (scansm->upper_limit - 1);
|
||||||
++scansm->backoff_count;
|
++scansm->backoff_count;
|
||||||
BLE_LL_ASSERT(scansm->backoff_count <= 256);
|
BLE_LL_ASSERT(scansm->backoff_count <= 256);
|
||||||
}
|
}
|
||||||
@ -305,7 +305,7 @@ ble_ll_scan_refresh_nrpa(struct ble_ll_scan_sm *scansm)
|
|||||||
ble_npl_time_t now;
|
ble_npl_time_t now;
|
||||||
|
|
||||||
now = ble_npl_time_get();
|
now = ble_npl_time_get();
|
||||||
if ((ble_npl_stime_t)(now - scansm->scan_nrpa_timer) >= 0) {
|
if (CPUTIME_GEQ(now, scansm->scan_nrpa_timer)) {
|
||||||
/* Generate new NRPA */
|
/* Generate new NRPA */
|
||||||
ble_ll_rand_data_get(scansm->scan_nrpa, BLE_DEV_ADDR_LEN);
|
ble_ll_rand_data_get(scansm->scan_nrpa, BLE_DEV_ADDR_LEN);
|
||||||
scansm->scan_nrpa[5] &= ~0xc0;
|
scansm->scan_nrpa[5] &= ~0xc0;
|
||||||
@ -617,7 +617,7 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd,
|
|||||||
static int
|
static int
|
||||||
ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype,
|
ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype,
|
||||||
const uint8_t *addr, uint8_t addr_type,
|
const uint8_t *addr, uint8_t addr_type,
|
||||||
uint8_t rssi,
|
int8_t rssi,
|
||||||
uint8_t adv_data_len,
|
uint8_t adv_data_len,
|
||||||
struct os_mbuf *adv_data,
|
struct os_mbuf *adv_data,
|
||||||
const uint8_t *inita, uint8_t inita_type)
|
const uint8_t *inita, uint8_t inita_type)
|
||||||
@ -1125,6 +1125,22 @@ ble_ll_scan_sm_stop(int chk_disable)
|
|||||||
scansm = &g_ble_ll_scan_sm;
|
scansm = &g_ble_ll_scan_sm;
|
||||||
os_cputime_timer_stop(&scansm->scan_timer);
|
os_cputime_timer_stop(&scansm->scan_timer);
|
||||||
|
|
||||||
|
/* Only set state if we are currently in a scan window */
|
||||||
|
if (chk_disable) {
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
lls = ble_ll_state_get();
|
||||||
|
|
||||||
|
if ((lls == BLE_LL_STATE_SCANNING) ||
|
||||||
|
(lls == BLE_LL_STATE_INITIATING && chk_disable == 1)) {
|
||||||
|
/* Disable phy */
|
||||||
|
ble_phy_disable();
|
||||||
|
|
||||||
|
/* Set LL state to standby */
|
||||||
|
ble_ll_state_set(BLE_LL_STATE_STANDBY);
|
||||||
|
}
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
}
|
||||||
|
|
||||||
OS_ENTER_CRITICAL(sr);
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
|
||||||
/* Disable scanning state machine */
|
/* Disable scanning state machine */
|
||||||
@ -1149,22 +1165,6 @@ ble_ll_scan_sm_stop(int chk_disable)
|
|||||||
/* Count # of times stopped */
|
/* Count # of times stopped */
|
||||||
STATS_INC(ble_ll_stats, scan_stops);
|
STATS_INC(ble_ll_stats, scan_stops);
|
||||||
|
|
||||||
/* Only set state if we are currently in a scan window */
|
|
||||||
if (chk_disable) {
|
|
||||||
OS_ENTER_CRITICAL(sr);
|
|
||||||
lls = ble_ll_state_get();
|
|
||||||
|
|
||||||
if ((lls == BLE_LL_STATE_SCANNING) ||
|
|
||||||
(lls == BLE_LL_STATE_INITIATING && chk_disable == 1)) {
|
|
||||||
/* Disable phy */
|
|
||||||
ble_phy_disable();
|
|
||||||
|
|
||||||
/* Set LL state to standby */
|
|
||||||
ble_ll_state_set(BLE_LL_STATE_STANDBY);
|
|
||||||
}
|
|
||||||
OS_EXIT_CRITICAL(sr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No need for RF anymore */
|
/* No need for RF anymore */
|
||||||
OS_ENTER_CRITICAL(sr);
|
OS_ENTER_CRITICAL(sr);
|
||||||
ble_ll_rfmgmt_scan_changed(false, 0);
|
ble_ll_rfmgmt_scan_changed(false, 0);
|
||||||
@ -1991,10 +1991,10 @@ ble_ll_scan_rx_filter(struct ble_mbuf_hdr *hdr, struct ble_ll_scan_addr_data *ad
|
|||||||
{
|
{
|
||||||
struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm;
|
struct ble_ll_scan_sm *scansm = &g_ble_ll_scan_sm;
|
||||||
struct ble_ll_scan_params *scanp = scansm->scanp;
|
struct ble_ll_scan_params *scanp = scansm->scanp;
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
|
||||||
struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data;
|
struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data;
|
||||||
#endif
|
#endif
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
|
||||||
struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo;
|
struct ble_mbuf_hdr_rxinfo *rxinfo = &hdr->rxinfo;
|
||||||
struct ble_ll_resolv_entry *rl = NULL;
|
struct ble_ll_resolv_entry *rl = NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -2227,6 +2227,7 @@ ble_ll_scan_rx_isr_on_aux(uint8_t pdu_type, uint8_t *rxbuf,
|
|||||||
*/
|
*/
|
||||||
if (aux_data->flags & BLE_LL_AUX_IS_MATCHED) {
|
if (aux_data->flags & BLE_LL_AUX_IS_MATCHED) {
|
||||||
rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH;
|
rxinfo->flags |= BLE_MBUF_HDR_F_DEVMATCH;
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||||
rxinfo->rpa_index = aux_data->rpa_index;
|
rxinfo->rpa_index = aux_data->rpa_index;
|
||||||
if (rxinfo->rpa_index >= 0) {
|
if (rxinfo->rpa_index >= 0) {
|
||||||
rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED;
|
rxinfo->flags |= BLE_MBUF_HDR_F_RESOLVED;
|
||||||
@ -2234,6 +2235,7 @@ ble_ll_scan_rx_isr_on_aux(uint8_t pdu_type, uint8_t *rxbuf,
|
|||||||
if (aux_data->flags & BLE_LL_AUX_IS_TARGETA_RESOLVED) {
|
if (aux_data->flags & BLE_LL_AUX_IS_TARGETA_RESOLVED) {
|
||||||
rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED;
|
rxinfo->flags |= BLE_MBUF_HDR_F_TARGETA_RESOLVED;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3019,7 +3021,8 @@ ble_ll_scan_rx_pkt_in_on_legacy(uint8_t pdu_type, struct os_mbuf *om,
|
|||||||
|
|
||||||
if (!BLE_MBUF_HDR_DEVMATCH(hdr) ||
|
if (!BLE_MBUF_HDR_DEVMATCH(hdr) ||
|
||||||
!BLE_MBUF_HDR_CRC_OK(hdr) ||
|
!BLE_MBUF_HDR_CRC_OK(hdr) ||
|
||||||
BLE_MBUF_HDR_IGNORED(hdr)) {
|
BLE_MBUF_HDR_IGNORED(hdr) ||
|
||||||
|
!scansm->scan_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3058,10 +3061,6 @@ ble_ll_scan_rx_pkt_in_on_aux(uint8_t pdu_type, struct os_mbuf *om,
|
|||||||
bool send_hci_report;
|
bool send_hci_report;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!scansm->ext_scanning) {
|
|
||||||
goto scan_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aux_data) {
|
if (aux_data) {
|
||||||
aux_data->flags_ll |= aux_data->flags_isr;
|
aux_data->flags_ll |= aux_data->flags_isr;
|
||||||
}
|
}
|
||||||
@ -3077,7 +3076,8 @@ ble_ll_scan_rx_pkt_in_on_aux(uint8_t pdu_type, struct os_mbuf *om,
|
|||||||
BLE_MBUF_HDR_IGNORED(hdr) ||
|
BLE_MBUF_HDR_IGNORED(hdr) ||
|
||||||
BLE_MBUF_HDR_AUX_INVALID(hdr) ||
|
BLE_MBUF_HDR_AUX_INVALID(hdr) ||
|
||||||
(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR) ||
|
(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR) ||
|
||||||
(pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND)) {
|
(pdu_type != BLE_ADV_PDU_TYPE_ADV_EXT_IND) ||
|
||||||
|
!scansm->scan_enabled) {
|
||||||
if (aux_data) {
|
if (aux_data) {
|
||||||
ble_ll_scan_end_adv_evt(aux_data);
|
ble_ll_scan_end_adv_evt(aux_data);
|
||||||
ble_ll_scan_aux_data_unref(aux_data);
|
ble_ll_scan_aux_data_unref(aux_data);
|
||||||
|
@ -83,14 +83,14 @@ ble_ll_sched_is_overlap(struct ble_ll_sched_item *s1,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = 1;
|
rc = 1;
|
||||||
if ((int32_t)(s1->start_time - s2->start_time) < 0) {
|
if (CPUTIME_LT(s1->start_time, s2->start_time)) {
|
||||||
/* Make sure this event does not overlap current event */
|
/* Make sure this event does not overlap current event */
|
||||||
if ((int32_t)(s1->end_time - s2->start_time) <= 0) {
|
if (CPUTIME_LEQ(s1->end_time, s2->start_time)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check for overlap */
|
/* Check for overlap */
|
||||||
if ((int32_t)(s1->start_time - s2->end_time) >= 0) {
|
if (CPUTIME_GEQ(s1->start_time, s2->end_time)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ ble_ll_sched_overlaps_current(struct ble_ll_sched_item *sch)
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
if (ble_ll_state_get() == BLE_LL_STATE_CONNECTION) {
|
if (ble_ll_state_get() == BLE_LL_STATE_CONNECTION) {
|
||||||
ce_end_time = ble_ll_conn_get_ce_end_time();
|
ce_end_time = ble_ll_conn_get_ce_end_time();
|
||||||
if ((int32_t)(ce_end_time - sch->start_time) > 0) {
|
if (CPUTIME_GT(ce_end_time, sch->start_time)) {
|
||||||
rc = 1;
|
rc = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
|
|||||||
sch->end_time = connsm->ce_end_time;
|
sch->end_time = connsm->ce_end_time;
|
||||||
|
|
||||||
/* Better be past current time or we just leave */
|
/* Better be past current time or we just leave */
|
||||||
if ((int32_t)(sch->start_time - os_cputime_get32()) < 0) {
|
if (CPUTIME_LT(sch->start_time, os_cputime_get32())) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
|
|||||||
end_overlap = entry;
|
end_overlap = entry;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
break;
|
break;
|
||||||
@ -468,7 +468,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm,
|
|||||||
sch->end_time = earliest_end;
|
sch->end_time = earliest_end;
|
||||||
|
|
||||||
/* We can insert if before entry in list */
|
/* We can insert if before entry in list */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
if ((earliest_start - initial_start) <= itvl_t) {
|
if ((earliest_start - initial_start) <= itvl_t) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
@ -655,7 +655,7 @@ ble_ll_sched_master_new(struct ble_ll_conn_sm *connsm,
|
|||||||
sch->end_time = earliest_end;
|
sch->end_time = earliest_end;
|
||||||
|
|
||||||
/* We can insert if before entry in list */
|
/* We can insert if before entry in list */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
if ((earliest_start - initial_start) <= itvl_t) {
|
if ((earliest_start - initial_start) <= itvl_t) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
@ -770,7 +770,7 @@ ble_ll_sched_slave_new(struct ble_ll_conn_sm *connsm)
|
|||||||
while (1) {
|
while (1) {
|
||||||
next_sch = entry->link.tqe_next;
|
next_sch = entry->link.tqe_next;
|
||||||
/* Insert if event ends before next starts */
|
/* Insert if event ends before next starts */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
break;
|
break;
|
||||||
@ -1047,7 +1047,7 @@ ble_ll_sched_adv_new(struct ble_ll_sched_item *sch, ble_ll_sched_adv_new_cb cb,
|
|||||||
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
||||||
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
||||||
/* We can insert if before entry in list */
|
/* We can insert if before entry in list */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1111,7 +1111,7 @@ ble_ll_sched_periodic_adv(struct ble_ll_sched_item *sch, uint32_t *start,
|
|||||||
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
||||||
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
||||||
/* We can insert if before entry in list */
|
/* We can insert if before entry in list */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1200,7 +1200,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start,
|
|||||||
end_overlap = entry;
|
end_overlap = entry;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
before = entry;
|
before = entry;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1233,7 +1233,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start,
|
|||||||
sch->end_time = sch->start_time + duration;
|
sch->end_time = sch->start_time + duration;
|
||||||
while (1) {
|
while (1) {
|
||||||
next_sch = entry->link.tqe_next;
|
next_sch = entry->link.tqe_next;
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
rand_ticks = entry->start_time - sch->end_time;
|
rand_ticks = entry->start_time - sch->end_time;
|
||||||
before = entry;
|
before = entry;
|
||||||
TAILQ_INSERT_BEFORE(before, sch, link);
|
TAILQ_INSERT_BEFORE(before, sch, link);
|
||||||
@ -1266,7 +1266,7 @@ ble_ll_sched_adv_reschedule(struct ble_ll_sched_item *sch, uint32_t *start,
|
|||||||
if (!rc) {
|
if (!rc) {
|
||||||
sch->enqueued = 1;
|
sch->enqueued = 1;
|
||||||
if (rand_ticks) {
|
if (rand_ticks) {
|
||||||
sch->start_time += rand() % rand_ticks;
|
sch->start_time += ble_ll_rand() % rand_ticks;
|
||||||
}
|
}
|
||||||
sch->end_time = sch->start_time + duration;
|
sch->end_time = sch->start_time + duration;
|
||||||
*start = sch->start_time;
|
*start = sch->start_time;
|
||||||
@ -1580,7 +1580,7 @@ ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode)
|
|||||||
while (sch) {
|
while (sch) {
|
||||||
/* Let's check if there is no scheduled item which want to start within
|
/* Let's check if there is no scheduled item which want to start within
|
||||||
* given usecs.*/
|
* given usecs.*/
|
||||||
if ((int32_t)(sch->start_time - now + os_cputime_usecs_to_ticks(usec_dur)) > 0) {
|
if (CPUTIME_GT(sch->start_time, now + os_cputime_usecs_to_ticks(usec_dur))) {
|
||||||
/* We are fine. Have time for scan req */
|
/* We are fine. Have time for scan req */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1670,7 +1670,7 @@ ble_ll_sched_aux_scan(struct ble_mbuf_hdr *ble_hdr,
|
|||||||
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
os_cputime_timer_stop(&g_ble_ll_sched_timer);
|
||||||
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
TAILQ_FOREACH(entry, &g_ble_ll_sched_q, link) {
|
||||||
/* We can insert if before entry in list */
|
/* We can insert if before entry in list */
|
||||||
if ((int32_t)(sch->end_time - entry->start_time) <= 0) {
|
if (CPUTIME_LEQ(sch->end_time, entry->start_time)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
TAILQ_INSERT_BEFORE(entry, sch, link);
|
TAILQ_INSERT_BEFORE(entry, sch, link);
|
||||||
sch->enqueued = 1;
|
sch->enqueued = 1;
|
||||||
|
@ -36,7 +36,22 @@
|
|||||||
|
|
||||||
/* Octet 10 */
|
/* Octet 10 */
|
||||||
#define BLE_SUPP_CMD_RD_TX_PWR (0 << 2)
|
#define BLE_SUPP_CMD_RD_TX_PWR (0 << 2)
|
||||||
#define BLE_LL_SUPP_CMD_OCTET_10 (BLE_SUPP_CMD_RD_TX_PWR)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL)
|
||||||
|
#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (1 << 5)
|
||||||
|
#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (1 << 6)
|
||||||
|
#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (1 << 7)
|
||||||
|
#else
|
||||||
|
#define BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW (0 << 5)
|
||||||
|
#define BLE_SUPP_CMD_HOST_BUFFER_SIZE (0 << 6)
|
||||||
|
#define BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS (0 << 7)
|
||||||
|
#endif
|
||||||
|
#define BLE_LL_SUPP_CMD_OCTET_10 \
|
||||||
|
( \
|
||||||
|
BLE_SUPP_CMD_RD_TX_PWR | \
|
||||||
|
BLE_SUPP_CMD_SET_CTRL_TO_HOST_FLOW | \
|
||||||
|
BLE_SUPP_CMD_HOST_BUFFER_SIZE | \
|
||||||
|
BLE_SUPP_CMD_HOST_NUM_COMP_PACKETS \
|
||||||
|
)
|
||||||
|
|
||||||
/* Octet 14 */
|
/* Octet 14 */
|
||||||
#define BLE_SUPP_CMD_RD_LOC_VER (1 << 3)
|
#define BLE_SUPP_CMD_RD_LOC_VER (1 << 3)
|
||||||
@ -404,10 +419,77 @@
|
|||||||
#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (0 << 0)
|
#define BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS (0 << 0)
|
||||||
#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (0 << 1)
|
#define BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS (0 << 1)
|
||||||
#endif
|
#endif
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (1 << 5)
|
||||||
|
#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (1 << 6)
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (1 << 7)
|
||||||
|
#else
|
||||||
|
#define BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 (0 << 5)
|
||||||
|
#define BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC (0 << 6)
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_CIG_PARAM (0 << 7)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BLE_LL_SUPP_CMD_OCTET_41 \
|
#define BLE_LL_SUPP_CMD_OCTET_41 \
|
||||||
( \
|
( \
|
||||||
BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \
|
BLE_SUPP_CMD_LE_PADV_SYNC_TRANSFER_PARAMS | \
|
||||||
BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS \
|
BLE_SUPP_CMD_LE_PADV_DEFAULT_SYNC_TRANSFER_PARAMS | \
|
||||||
|
BLE_SUPP_CMD_LE_READ_BUF_SIZE_V2 | \
|
||||||
|
BLE_SUPP_CMD_LE_READ_ISO_TX_SYNC | \
|
||||||
|
BLE_SUPP_CMD_LE_SET_CIG_PARAM \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Octet 42 */
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ISO)
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (1 << 0)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_CIS (1 << 1)
|
||||||
|
#define BLE_SUPP_CMD_LE_REMOVE_CIG (1 << 2)
|
||||||
|
#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (1 << 3)
|
||||||
|
#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (1 << 4)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_BIG (1 << 5)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (1 << 6)
|
||||||
|
#define BLE_SUPP_CMD_LE_TERMINATE_BIG (1 << 7)
|
||||||
|
#else
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST (0 << 0)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_CIS (0 << 1)
|
||||||
|
#define BLE_SUPP_CMD_LE_REMOVE_CIG (0 << 2)
|
||||||
|
#define BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ (0 << 3)
|
||||||
|
#define BLE_SUPP_CMD_LE_REJECT_CIS_REQ (0 << 4)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_BIG (0 << 5)
|
||||||
|
#define BLE_SUPP_CMD_LE_CREATE_BIG_TEST (0 << 6)
|
||||||
|
#define BLE_SUPP_CMD_LE_TERMINATE_BIG (0 << 7)
|
||||||
|
#endif
|
||||||
|
#define BLE_LL_SUPP_CMD_OCTET_42 \
|
||||||
|
( \
|
||||||
|
BLE_SUPP_CMD_LE_SET_CIG_PARAM_TEST | \
|
||||||
|
BLE_SUPP_CMD_LE_CREATE_CIS | \
|
||||||
|
BLE_SUPP_CMD_LE_REMOVE_CIG | \
|
||||||
|
BLE_SUPP_CMD_LE_ACCEPT_CIS_REQ | \
|
||||||
|
BLE_SUPP_CMD_LE_REJECT_CIS_REQ | \
|
||||||
|
BLE_SUPP_CMD_LE_CREATE_BIG | \
|
||||||
|
BLE_SUPP_CMD_LE_CREATE_BIG_TEST | \
|
||||||
|
BLE_SUPP_CMD_LE_TERMINATE_BIG \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Octet 43 */
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_SCA_UPDATE)
|
||||||
|
#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (1 << 2)
|
||||||
|
#else
|
||||||
|
#define BLE_SUPP_CMD_LE_REQUEST_PEER_SCA (0 << 0)
|
||||||
|
#endif
|
||||||
|
#define BLE_LL_SUPP_CMD_OCTET_43 \
|
||||||
|
( \
|
||||||
|
BLE_SUPP_CMD_LE_REQUEST_PEER_SCA \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Octet 44 */
|
||||||
|
#if MYNEWT_VAL(BLE_VERSION) >= 52
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (1 << 0)
|
||||||
|
#else
|
||||||
|
#define BLE_SUPP_CMD_LE_SET_HOST_FEATURE (0 << 0)
|
||||||
|
#endif
|
||||||
|
#define BLE_LL_SUPP_CMD_OCTET_44 \
|
||||||
|
( \
|
||||||
|
BLE_SUPP_CMD_LE_SET_HOST_FEATURE \
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Defines the array of supported commands */
|
/* Defines the array of supported commands */
|
||||||
@ -455,4 +537,7 @@ const uint8_t g_ble_ll_supp_cmds[BLE_LL_SUPP_CMD_LEN] =
|
|||||||
BLE_LL_SUPP_CMD_OCTET_39,
|
BLE_LL_SUPP_CMD_OCTET_39,
|
||||||
BLE_LL_SUPP_CMD_OCTET_40, /* Octet 40 */
|
BLE_LL_SUPP_CMD_OCTET_40, /* Octet 40 */
|
||||||
BLE_LL_SUPP_CMD_OCTET_41,
|
BLE_LL_SUPP_CMD_OCTET_41,
|
||||||
|
BLE_LL_SUPP_CMD_OCTET_42,
|
||||||
|
BLE_LL_SUPP_CMD_OCTET_43,
|
||||||
|
BLE_LL_SUPP_CMD_OCTET_44,
|
||||||
};
|
};
|
||||||
|
@ -2094,7 +2094,7 @@ ble_ll_sync_send_sync_ind(struct ble_ll_sync_sm *syncsm,
|
|||||||
sync_ind[24] |= (syncsm->adv_addr_type == BLE_ADDR_RANDOM) << 4;
|
sync_ind[24] |= (syncsm->adv_addr_type == BLE_ADDR_RANDOM) << 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_ind[24] |= MYNEWT_VAL(BLE_LL_MASTER_SCA) << 5;
|
sync_ind[24] |= BLE_LL_SCA_ENUM << 5;
|
||||||
|
|
||||||
/* PHY */
|
/* PHY */
|
||||||
sync_ind[25] = (0x01 << (ble_ll_sync_phy_mode_to_hci(syncsm->phy_mode) - 1));
|
sync_ind[25] = (0x01 << (ble_ll_sync_phy_mode_to_hci(syncsm->phy_mode) - 1));
|
||||||
|
@ -50,8 +50,8 @@ ble_ll_utils_calc_access_addr(void)
|
|||||||
aa = 0;
|
aa = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Get two, 16-bit random numbers */
|
/* Get two, 16-bit random numbers */
|
||||||
aa_low = rand() & 0xFFFF;
|
aa_low = ble_ll_rand() & 0xFFFF;
|
||||||
aa_high = rand() & 0xFFFF;
|
aa_high = ble_ll_rand() & 0xFFFF;
|
||||||
|
|
||||||
/* All four bytes cannot be equal */
|
/* All four bytes cannot be equal */
|
||||||
if (aa_low == aa_high) {
|
if (aa_low == aa_high) {
|
||||||
@ -292,8 +292,7 @@ ble_ll_utils_calc_window_widening(uint32_t anchor_point,
|
|||||||
time_since_last_anchor = (int32_t)(anchor_point - last_anchor_point);
|
time_since_last_anchor = (int32_t)(anchor_point - last_anchor_point);
|
||||||
if (time_since_last_anchor > 0) {
|
if (time_since_last_anchor > 0) {
|
||||||
delta_msec = os_cputime_ticks_to_usecs(time_since_last_anchor) / 1000;
|
delta_msec = os_cputime_ticks_to_usecs(time_since_last_anchor) / 1000;
|
||||||
total_sca_ppm = g_ble_sca_ppm_tbl[master_sca] +
|
total_sca_ppm = g_ble_sca_ppm_tbl[master_sca] + MYNEWT_VAL(BLE_LL_SCA);
|
||||||
MYNEWT_VAL(BLE_LL_OUR_SCA);
|
|
||||||
window_widening = (total_sca_ppm * delta_msec) / 1000;
|
window_widening = (total_sca_ppm * delta_msec) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,35 +38,10 @@ syscfg.defs:
|
|||||||
type: 'task_priority'
|
type: 'task_priority'
|
||||||
value: 0
|
value: 0
|
||||||
|
|
||||||
# Sleep clock accuracy (sca). This is the amount of drift in the system
|
BLE_LL_SCA:
|
||||||
# during when the device is sleeping (in parts per million).
|
description: Sleep clock accuracy of our device (in ppm)
|
||||||
#
|
value: MYNEWT_VAL(BLE_LL_OUR_SCA)
|
||||||
# NOTE: 'the' master sca is an enumerated value based on the sca. Rather
|
range: 0..500
|
||||||
# than have a piece of code calculate this value, the developer must set
|
|
||||||
# this value based on the value of the SCA using the following table:
|
|
||||||
#
|
|
||||||
# SCA between 251 and 500 ppm (inclusive); master sca = 0
|
|
||||||
# SCA between 151 and 250 ppm (inclusive); master sca = 1
|
|
||||||
# SCA between 101 and 150 ppm (inclusive); master sca = 2
|
|
||||||
# SCA between 76 and 100 ppm (inclusive); master sca = 3
|
|
||||||
# SCA between 51 and 75 ppm (inclusive); master sca = 4
|
|
||||||
# SCA between 31 and 50 ppm (inclusive); master sca = 5
|
|
||||||
# SCA between 21 and 30 ppm (inclusive); master sca = 6
|
|
||||||
# SCA between 0 and 20 ppm (inclusive); master sca = 7
|
|
||||||
#
|
|
||||||
# For example:
|
|
||||||
# if your clock drift is 101 ppm, your master should be set to 2.
|
|
||||||
# if your clock drift is 20, your master sca should be set to 7.
|
|
||||||
#
|
|
||||||
# The values provided below are merely meant to be an example and should
|
|
||||||
# be replaced by values appropriate for your platform.
|
|
||||||
BLE_LL_OUR_SCA:
|
|
||||||
description: 'The system clock accuracy of the device.'
|
|
||||||
value: '60' # in ppm
|
|
||||||
|
|
||||||
BLE_LL_MASTER_SCA:
|
|
||||||
description: 'Enumerated value based on our sca'
|
|
||||||
value: '4'
|
|
||||||
|
|
||||||
BLE_LL_TX_PWR_DBM:
|
BLE_LL_TX_PWR_DBM:
|
||||||
description: 'Transmit power level.'
|
description: 'Transmit power level.'
|
||||||
@ -285,6 +260,35 @@ syscfg.defs:
|
|||||||
Advertising Sync Transfer Feature.
|
Advertising Sync Transfer Feature.
|
||||||
value: MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER)
|
value: MYNEWT_VAL(BLE_PERIODIC_ADV_SYNC_TRANSFER)
|
||||||
|
|
||||||
|
BLE_LL_CFG_FEAT_CTRL_TO_HOST_FLOW_CONTROL:
|
||||||
|
description: >
|
||||||
|
Enable controller-to-host flow control support. This allows host to
|
||||||
|
limit number of ACL packets sent at once from controller to avoid
|
||||||
|
congestion on HCI transport if feature is also supported by host.
|
||||||
|
value: 0
|
||||||
|
|
||||||
|
BLE_LL_CFG_FEAT_LL_SCA_UPDATE:
|
||||||
|
description: >
|
||||||
|
This option is used to enable/disable support for SCA update procedure
|
||||||
|
value: 0
|
||||||
|
restrictions:
|
||||||
|
- '(BLE_VERSION >= 52) if 1'
|
||||||
|
|
||||||
|
BLE_LL_CFG_FEAT_LL_ISO:
|
||||||
|
description: >
|
||||||
|
This option is used to enable/disable support for LE Isochronous Channels
|
||||||
|
as per Bluetooth v5.2 channels
|
||||||
|
value: MYNEWT_VAL(BLE_ISO)
|
||||||
|
restrictions:
|
||||||
|
- '(BLE_VERSION >= 52) if 1'
|
||||||
|
|
||||||
|
BLE_LL_CFG_FEAT_LL_ISO_TEST:
|
||||||
|
description: >
|
||||||
|
This option is used to enable/disbale test commands for ISO support
|
||||||
|
value: MYNEWT_VAL(BLE_ISO_TEST)
|
||||||
|
restrictions:
|
||||||
|
- 'BLE_LL_CFG_FEAT_LL_ISO if 1'
|
||||||
|
|
||||||
BLE_LL_EXT_ADV_AUX_PTR_CNT:
|
BLE_LL_EXT_ADV_AUX_PTR_CNT:
|
||||||
description: >
|
description: >
|
||||||
This option configure a max number of scheduled outstanding auxiliary
|
This option configure a max number of scheduled outstanding auxiliary
|
||||||
@ -404,6 +408,10 @@ syscfg.defs:
|
|||||||
description: use BLE_LL_RFMGMT_ENABLE_TIME instead
|
description: use BLE_LL_RFMGMT_ENABLE_TIME instead
|
||||||
value: 0
|
value: 0
|
||||||
deprecated: 1
|
deprecated: 1
|
||||||
|
BLE_LL_OUR_SCA:
|
||||||
|
description: use BLE_LL_SCA instead
|
||||||
|
value: 60
|
||||||
|
deprecated: 1
|
||||||
|
|
||||||
# defunct settings (to be removed eventually)
|
# defunct settings (to be removed eventually)
|
||||||
BLE_DEVICE:
|
BLE_DEVICE:
|
||||||
@ -418,6 +426,10 @@ syscfg.defs:
|
|||||||
description: Superseded by BLE_LL_NUM_COMP_PKT_ITVL_MS
|
description: Superseded by BLE_LL_NUM_COMP_PKT_ITVL_MS
|
||||||
value: '(2 * OS_TICKS_PER_SEC)'
|
value: '(2 * OS_TICKS_PER_SEC)'
|
||||||
defunct: 1
|
defunct: 1
|
||||||
|
BLE_LL_MASTER_SCA:
|
||||||
|
description: use BLE_LL_SCA instead
|
||||||
|
value: 4
|
||||||
|
defunct: 1
|
||||||
|
|
||||||
|
|
||||||
syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV:
|
syscfg.vals.BLE_LL_CFG_FEAT_LL_EXT_ADV:
|
||||||
|
68
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/README.md
Normal file
68
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/README.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<!--
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
-->
|
||||||
|
|
||||||
|
## How to run NimBLE controller on Dialog DA1469x
|
||||||
|
|
||||||
|
Dialog DA1469x has separate Cortex-M0+ core inside CMAC hw block which can run
|
||||||
|
NimBLE controller. This means DA1469x can run full NimBLE stack: host is running
|
||||||
|
on M33 core while controller is running on M0+ core. Both communicate using
|
||||||
|
standard HCI H4 protocol exchanged over mailboxes located in shared memory.
|
||||||
|
|
||||||
|
### Basic setup
|
||||||
|
|
||||||
|
In order to run full NimBLE stack on DA1469x you will need two newt targets: one
|
||||||
|
for M33 (e.g. `dialog_da1469x-dk-pro` BSP) and one for M0+ (`dialog_cmac` BSP).
|
||||||
|
|
||||||
|
Once everything is configured properly, you only need to build target for M33.
|
||||||
|
Target configured for M0+ will be build automatically and image is linked with
|
||||||
|
M33 image so everything can be flashed at once just as if there is only single
|
||||||
|
target used.
|
||||||
|
|
||||||
|
Target for M33 should be set and configured as any other BLE application. In
|
||||||
|
order to use NimBLE controller on CMAC, set proper HCI transport via syscfg:
|
||||||
|
|
||||||
|
BLE_HCI_TRANSPORT: dialog_cmac
|
||||||
|
|
||||||
|
This will include proper transport, driver and add M0+ target to build process.
|
||||||
|
|
||||||
|
For M0+, there is sample target provided in `targets/dialog_cmac` and it's used
|
||||||
|
by default unless overrided by syscfg in M33 target:
|
||||||
|
|
||||||
|
CMAC_IMAGE_TARGET_NAME: "@apache-mynewt-nimble/targets/dialog_cmac"
|
||||||
|
|
||||||
|
If you wish to create own target for M0+, make sure your target is set the same
|
||||||
|
way (`app`, `bsp` and `build_profile`) as sample. Also it is recommended to use
|
||||||
|
syscfg settings from sample target in new target.
|
||||||
|
|
||||||
|
### NimBLE configuration
|
||||||
|
|
||||||
|
Since host and controller are running on different cores, they both use separate
|
||||||
|
configuration: host configuration is in M33 target, controller configuration is
|
||||||
|
in M0+ target. There is currently no way to automatically synchronize both, so
|
||||||
|
care needs to be taken when enabling features in either of targets.
|
||||||
|
|
||||||
|
A possible workaround is to use separate `.yml` file with all the NimBLE syscfg
|
||||||
|
values settings and include it in both targets using `$import` directive which
|
||||||
|
is supported by recent versions of `newt` tool.
|
||||||
|
|
||||||
|
### Advanced settings
|
||||||
|
|
||||||
|
(tbd)
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 H_BLE_XCVR_
|
||||||
|
#define H_BLE_XCVR_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XCVR_TX_SCHED_DELAY_USECS (250)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define HW whitelist size. This is the total possible whitelist size;
|
||||||
|
* not necessarily the size that will be used (may be smaller)
|
||||||
|
*/
|
||||||
|
#define BLE_HW_WHITE_LIST_SIZE (8)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* H_BLE_XCVR_ */
|
33
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/pkg.yml
Normal file
33
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/pkg.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
pkg.name: nimble/drivers/dialog_cmac
|
||||||
|
pkg.description: BLE driver for Dialog CMAC
|
||||||
|
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||||
|
pkg.homepage: "http://mynewt.apache.org/"
|
||||||
|
pkg.keywords:
|
||||||
|
- ble
|
||||||
|
- bluetooth
|
||||||
|
pkg.deps:
|
||||||
|
- "@apache-mynewt-nimble/nimble/controller"
|
||||||
|
- "@apache-mynewt-core/crypto/tinycrypt"
|
||||||
|
pkg.apis:
|
||||||
|
- ble_driver
|
||||||
|
pkg.req_apis:
|
||||||
|
- ble_transport
|
340
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_hw.c
Normal file
340
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_hw.c
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mcu/mcu.h"
|
||||||
|
#include "nimble/ble.h"
|
||||||
|
#include "controller/ble_hw.h"
|
||||||
|
#include "CMAC.h"
|
||||||
|
#include "cmac_driver/cmac_shared.h"
|
||||||
|
#include "mcu/mcu.h"
|
||||||
|
#include "tinycrypt/aes.h"
|
||||||
|
|
||||||
|
static struct tc_aes_key_sched_struct g_ctx;
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
|
||||||
|
{
|
||||||
|
cmac_rand_set_isr_cb(cb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_rng_start(void)
|
||||||
|
{
|
||||||
|
/* Chime the M33 in case we need random numbers generated */
|
||||||
|
cmac_rand_start();
|
||||||
|
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV1C_CMAC2SYS_IRQ_SET_Msk;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_rng_stop(void)
|
||||||
|
{
|
||||||
|
cmac_rand_stop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BLE_HW_RESOLV_LIST_SIZE (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE))
|
||||||
|
|
||||||
|
struct ble_hw_resolv_irk {
|
||||||
|
uint32_t key[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ble_hw_resolv_list {
|
||||||
|
uint8_t count;
|
||||||
|
struct ble_hw_resolv_irk irk[BLE_HW_RESOLV_LIST_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ble_hw_resolv_proc {
|
||||||
|
uint32_t hash;
|
||||||
|
uint8_t f_configured;
|
||||||
|
uint8_t f_active;
|
||||||
|
uint8_t f_match;
|
||||||
|
uint8_t f_done;
|
||||||
|
struct ble_hw_resolv_irk *irk;
|
||||||
|
struct ble_hw_resolv_irk *irk_end;
|
||||||
|
uint32_t crypto_prand_in[4];
|
||||||
|
uint32_t crypto_e_out[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ble_hw_resolv_list g_ble_hw_resolv_list;
|
||||||
|
static struct ble_hw_resolv_proc g_ble_hw_resolv_proc;
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_get_public_addr(ble_addr_t *addr)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_get_static_addr(ble_addr_t *addr)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_clear(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
ble_hw_whitelist_size(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_enable(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_disable(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_whitelist_match(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_encrypt_block(struct ble_encryption_block *ecb)
|
||||||
|
{
|
||||||
|
uint32_t in_addr;
|
||||||
|
uint32_t out_addr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following code bears some explanation. This function is called by
|
||||||
|
* the LL task to encrypt blocks and calculate session keys. Address
|
||||||
|
* resolution also calls this function. Furthermore, during connections,
|
||||||
|
* the M0 crypto accelerator is used but this function is not called when
|
||||||
|
* using it. During the entire connection event, the M0 crypto block cannot
|
||||||
|
* be used as the crypto state (some of it) needs to remain un-changed.
|
||||||
|
* Note that this is also true when address resolution is enabled: the
|
||||||
|
* HW crypto block is set up and cannot be modified.
|
||||||
|
*
|
||||||
|
* Rather than attempt to share the M0 crypto block between the various
|
||||||
|
* controller features which require it, we decided to use software to
|
||||||
|
* perform the encryption task for anything being done at the link-layer
|
||||||
|
* (outside of an ISR). If this function is called inside an ISR, and it
|
||||||
|
* is when resolving addresses, the crypto accelerator is not being used
|
||||||
|
* by a connection event. Thus, we check to see if we are inside of an ISR.
|
||||||
|
* If so, we use the M0 crypto block. If outside of an ISR, we use the M33
|
||||||
|
*/
|
||||||
|
if (!os_arch_in_isr()) {
|
||||||
|
tc_aes128_set_encrypt_key(&g_ctx, ecb->key);
|
||||||
|
tc_aes_encrypt(ecb->cipher_text, ecb->plain_text, &g_ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to retain state of in/out pointers */
|
||||||
|
in_addr = CMAC->CM_CRYPTO_IN_ADR2_REG;
|
||||||
|
out_addr = CMAC->CM_CRYPTO_OUT_ADR_REG;
|
||||||
|
|
||||||
|
while (CMAC->CM_CRYPTO_STAT_REG & CMAC_CM_CRYPTO_STAT_REG_CM_CRYPTO_BUSY_Msk);
|
||||||
|
|
||||||
|
/* RECB, memory in/out, encryption */
|
||||||
|
CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ECB_ENC_EN_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_IN_SEL_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_OUT_SEL_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ENC_DECN_Msk;
|
||||||
|
|
||||||
|
CMAC->CM_CRYPTO_KEY_31_0_REG = get_le32(&ecb->key[0]);
|
||||||
|
CMAC->CM_CRYPTO_KEY_63_32_REG = get_le32(&ecb->key[4]);
|
||||||
|
CMAC->CM_CRYPTO_KEY_95_64_REG = get_le32(&ecb->key[8]);
|
||||||
|
CMAC->CM_CRYPTO_KEY_127_96_REG = get_le32(&ecb->key[12]);
|
||||||
|
CMAC->CM_CRYPTO_IN_ADR2_REG = (uint32_t)ecb->plain_text;
|
||||||
|
CMAC->CM_CRYPTO_OUT_ADR_REG = (uint32_t)ecb->cipher_text;
|
||||||
|
|
||||||
|
CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk;
|
||||||
|
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV_CRYPTO_START_Msk;
|
||||||
|
while (!(CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk));
|
||||||
|
CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk;
|
||||||
|
|
||||||
|
CMAC->CM_CRYPTO_IN_ADR2_REG = in_addr;
|
||||||
|
CMAC->CM_CRYPTO_OUT_ADR_REG = out_addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_resolv_list_clear(void)
|
||||||
|
{
|
||||||
|
g_ble_hw_resolv_list.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_resolv_list_add(uint8_t *irk)
|
||||||
|
{
|
||||||
|
struct ble_hw_resolv_irk *e;
|
||||||
|
|
||||||
|
if (g_ble_hw_resolv_list.count == BLE_HW_RESOLV_LIST_SIZE) {
|
||||||
|
return BLE_ERR_MEM_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = &g_ble_hw_resolv_list.irk[g_ble_hw_resolv_list.count];
|
||||||
|
/* Prepare key here so we do not need to do it during resolving */
|
||||||
|
e->key[0] = get_le32(&irk[0]);
|
||||||
|
e->key[1] = get_le32(&irk[4]);
|
||||||
|
e->key[2] = get_le32(&irk[8]);
|
||||||
|
e->key[3] = get_le32(&irk[12]);
|
||||||
|
|
||||||
|
g_ble_hw_resolv_list.count++;
|
||||||
|
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_resolv_list_rmv(int index)
|
||||||
|
{
|
||||||
|
struct ble_hw_resolv_irk *e;
|
||||||
|
|
||||||
|
if (index < g_ble_hw_resolv_list.count) {
|
||||||
|
g_ble_hw_resolv_list.count--;
|
||||||
|
|
||||||
|
e = &g_ble_hw_resolv_list.irk[index];
|
||||||
|
memmove(e, e + 1, (g_ble_hw_resolv_list.count - index) * sizeof(e->key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
ble_hw_resolv_list_size(void)
|
||||||
|
{
|
||||||
|
return BLE_HW_RESOLV_LIST_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ble_hw_resolv_list_match(void)
|
||||||
|
{
|
||||||
|
return g_ble_hw_resolv_proc.f_match ?
|
||||||
|
g_ble_hw_resolv_proc.irk - g_ble_hw_resolv_list.irk : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_hw_resolv_proc_next(void)
|
||||||
|
{
|
||||||
|
void *src = &g_ble_hw_resolv_proc.irk->key;
|
||||||
|
|
||||||
|
if (g_ble_hw_resolv_proc.irk == g_ble_hw_resolv_proc.irk_end) {
|
||||||
|
g_ble_hw_resolv_proc.f_done = 1;
|
||||||
|
g_ble_hw_resolv_proc.f_active = 0;
|
||||||
|
} else {
|
||||||
|
__asm__ volatile (".syntax unified \n"
|
||||||
|
" ldm %[ptr]!, {r1, r2, r3, r4} \n"
|
||||||
|
" ldr %[ptr], =%[reg] \n"
|
||||||
|
" stm %[ptr]!, {r1, r2, r3, r4} \n"
|
||||||
|
: [ptr] "+l" (src)
|
||||||
|
: [reg] "i" (&CMAC->CM_CRYPTO_KEY_31_0_REG)
|
||||||
|
: "r1", "r2", "r3", "r4", "memory");
|
||||||
|
|
||||||
|
CMAC->CM_EV_SET_REG = CMAC_CM_EV_SET_REG_EV_CRYPTO_START_Msk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_resolv_proc_enable(void)
|
||||||
|
{
|
||||||
|
assert(!g_ble_hw_resolv_proc.f_active);
|
||||||
|
|
||||||
|
CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_SW_REQ_ABORT_Msk;
|
||||||
|
|
||||||
|
CMAC->CM_CRYPTO_CTRL_REG = CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ECB_ENC_EN_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_IN_SEL_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_OUT_SEL_Msk |
|
||||||
|
CMAC_CM_CRYPTO_CTRL_REG_CM_CRYPTO_ENC_DECN_Msk;
|
||||||
|
|
||||||
|
CMAC->CM_CRYPTO_IN_ADR2_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_prand_in;
|
||||||
|
CMAC->CM_CRYPTO_OUT_ADR_REG = (uint32_t)g_ble_hw_resolv_proc.crypto_e_out;
|
||||||
|
|
||||||
|
g_ble_hw_resolv_proc.irk = g_ble_hw_resolv_list.irk;
|
||||||
|
g_ble_hw_resolv_proc.irk_end = g_ble_hw_resolv_list.irk +
|
||||||
|
g_ble_hw_resolv_list.count;
|
||||||
|
g_ble_hw_resolv_proc.f_configured = 1;
|
||||||
|
g_ble_hw_resolv_proc.f_active = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It would be better to enable IRQ in ble_hw_resolv_proc_start, but this
|
||||||
|
* would introduce a bit of latency when starting resolving procedure and
|
||||||
|
* we need to save every us possible there in order to be able to resolve
|
||||||
|
* RPA on time.
|
||||||
|
*/
|
||||||
|
NVIC_ClearPendingIRQ(CRYPTO_IRQn);
|
||||||
|
NVIC_EnableIRQ(CRYPTO_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_resolv_proc_disable(void)
|
||||||
|
{
|
||||||
|
g_ble_hw_resolv_proc.f_configured = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_active = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_match = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_done = 1;
|
||||||
|
|
||||||
|
NVIC_DisableIRQ(CRYPTO_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_hw_resolv_proc_start(const uint8_t *addr)
|
||||||
|
{
|
||||||
|
assert(g_ble_hw_resolv_proc.f_configured);
|
||||||
|
|
||||||
|
/* crypto_prand_in is already zeroed so prand is properly padded */
|
||||||
|
g_ble_hw_resolv_proc.crypto_prand_in[3] = get_be24(&addr[3]) << 8;
|
||||||
|
g_ble_hw_resolv_proc.hash = get_be24(&addr[0]);
|
||||||
|
|
||||||
|
g_ble_hw_resolv_proc.f_match = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_done = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_active = 1;
|
||||||
|
|
||||||
|
ble_hw_resolv_proc_next();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CRYPTO_IRQHandler(void)
|
||||||
|
{
|
||||||
|
uint32_t hash;
|
||||||
|
|
||||||
|
CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_CRYPTO_Msk;
|
||||||
|
|
||||||
|
hash = g_ble_hw_resolv_proc.crypto_e_out[3] >> 8;
|
||||||
|
if (g_ble_hw_resolv_proc.hash == hash) {
|
||||||
|
g_ble_hw_resolv_proc.f_active = 0;
|
||||||
|
g_ble_hw_resolv_proc.f_match = 1;
|
||||||
|
g_ble_hw_resolv_proc.f_done = 1;
|
||||||
|
} else {
|
||||||
|
g_ble_hw_resolv_proc.irk++;
|
||||||
|
ble_hw_resolv_proc_next();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 _BLE_HW_PRIV_H_
|
||||||
|
#define _BLE_HW_PRIV_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void ble_hw_resolv_proc_enable(void);
|
||||||
|
void ble_hw_resolv_proc_disable(void);
|
||||||
|
void ble_hw_resolv_proc_start(const uint8_t *addr);
|
||||||
|
|
||||||
|
#endif /* _BLE_HW_PRIV_H_ */
|
1798
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_phy.c
Normal file
1798
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_phy.c
Normal file
File diff suppressed because it is too large
Load Diff
747
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_rf.c
Normal file
747
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/src/ble_rf.c
Normal file
@ -0,0 +1,747 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mcu/mcu.h"
|
||||||
|
#include "mcu/cmac_timer.h"
|
||||||
|
#include "controller/ble_phy.h"
|
||||||
|
#include "cmac_driver/cmac_shared.h"
|
||||||
|
#include "ble_rf_priv.h"
|
||||||
|
|
||||||
|
#define RF_CALIBRATION_0 (0x01)
|
||||||
|
#define RF_CALIBRATION_1 (0x02)
|
||||||
|
#define RF_CALIBRATION_2 (0x04)
|
||||||
|
|
||||||
|
static const int8_t g_ble_rf_power_lvls[] = {
|
||||||
|
-18, -12, -8, -6, -3, -2, -1, 0, 1, 2, 3, 4, 4, 5, 6
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ble_phy_rf_data {
|
||||||
|
uint8_t tx_power_cfg0;
|
||||||
|
uint8_t tx_power_cfg1;
|
||||||
|
uint8_t tx_power_cfg2;
|
||||||
|
uint8_t tx_power_cfg3;
|
||||||
|
uint32_t cal_res_1;
|
||||||
|
uint32_t cal_res_2;
|
||||||
|
uint32_t trim_val1_tx_1;
|
||||||
|
uint32_t trim_val1_tx_2;
|
||||||
|
uint32_t trim_val2_tx;
|
||||||
|
uint32_t trim_val2_rx;
|
||||||
|
uint8_t calibrate_req;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ble_phy_rf_data g_ble_phy_rf_data;
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
get_reg32(uint32_t addr)
|
||||||
|
{
|
||||||
|
volatile uint32_t *reg = (volatile uint32_t *)addr;
|
||||||
|
|
||||||
|
return *reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
get_reg32_bits(uint32_t addr, uint32_t mask)
|
||||||
|
{
|
||||||
|
volatile uint32_t *reg = (volatile uint32_t *)addr;
|
||||||
|
|
||||||
|
return (*reg & mask) >> __builtin_ctz(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg8(uint32_t addr, uint8_t val)
|
||||||
|
{
|
||||||
|
volatile uint8_t *reg = (volatile uint8_t *)addr;
|
||||||
|
|
||||||
|
*reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg16(uint32_t addr, uint16_t val)
|
||||||
|
{
|
||||||
|
volatile uint16_t *reg = (volatile uint16_t *)addr;
|
||||||
|
|
||||||
|
*reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg32(uint32_t addr, uint32_t val)
|
||||||
|
{
|
||||||
|
volatile uint32_t *reg = (volatile uint32_t *)addr;
|
||||||
|
|
||||||
|
*reg = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg32_bits(uint32_t addr, uint32_t mask, uint32_t val)
|
||||||
|
{
|
||||||
|
volatile uint32_t *reg = (volatile uint32_t *)addr;
|
||||||
|
|
||||||
|
*reg = (*reg & (~mask)) | (val << __builtin_ctz(mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg32_mask(uint32_t addr, uint32_t mask, uint32_t val)
|
||||||
|
{
|
||||||
|
volatile uint32_t *reg = (volatile uint32_t *)addr;
|
||||||
|
|
||||||
|
*reg = (*reg & (~mask)) | (val & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_reg16_mask(uint32_t addr, uint16_t mask, uint16_t val)
|
||||||
|
{
|
||||||
|
volatile uint16_t *reg = (volatile uint16_t *)addr;
|
||||||
|
|
||||||
|
*reg = (*reg & (~mask)) | (val & mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delay_us(uint32_t delay_us)
|
||||||
|
{
|
||||||
|
while (delay_us--) {
|
||||||
|
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||||
|
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||||
|
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||||
|
__NOP(); __NOP(); __NOP(); __NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_apply_trim(volatile uint32_t *tv, unsigned len)
|
||||||
|
{
|
||||||
|
while (len) {
|
||||||
|
*(volatile uint32_t *)tv[0] = tv[1];
|
||||||
|
len -= 2;
|
||||||
|
tv += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_apply_calibration(void)
|
||||||
|
{
|
||||||
|
set_reg32(0x40020094, g_ble_phy_rf_data.cal_res_1);
|
||||||
|
if (g_ble_phy_rf_data.cal_res_2) {
|
||||||
|
set_reg32_bits(0x40022018, 0xff800000, g_ble_phy_rf_data.cal_res_2);
|
||||||
|
set_reg32_bits(0x40022018, 0x00007fc0, g_ble_phy_rf_data.cal_res_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_ldo_on(void)
|
||||||
|
{
|
||||||
|
set_reg8(0x40020004, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_ldo_off(void)
|
||||||
|
{
|
||||||
|
set_reg8(0x40020004, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_rfcu_enable(void)
|
||||||
|
{
|
||||||
|
set_reg32_bits(0x50000010, 0x00000020, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_rfcu_disable(void)
|
||||||
|
{
|
||||||
|
set_reg32_bits(0x50000010, 0x00000020, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_rfcu_apply_recommended_settings(void)
|
||||||
|
{
|
||||||
|
set_reg16_mask(0x400200a0, 0x0001, 0x0001);
|
||||||
|
set_reg16_mask(0x40021020, 0x03f0, 0x02f5);
|
||||||
|
set_reg32_mask(0x40021018, 0x001fffff, 0x005a5809);
|
||||||
|
set_reg32_mask(0x4002101c, 0x00001e01, 0x0040128c);
|
||||||
|
set_reg32_mask(0x40021004, 0xffffff1f, 0x64442404);
|
||||||
|
set_reg32_mask(0x40021008, 0xfcfcffff, 0x6b676665);
|
||||||
|
set_reg32_mask(0x4002100c, 0x00fcfcfc, 0x9793736f);
|
||||||
|
set_reg32_mask(0x40021010, 0x1f1f1c1f, 0x04072646);
|
||||||
|
set_reg32_mask(0x40020000, 0x001ff000, 0x0f099820);
|
||||||
|
set_reg16_mask(0x40020348, 0x00ff, 0x0855);
|
||||||
|
set_reg16(0x40020350, 0x0234);
|
||||||
|
set_reg16(0x40020354, 0x0a34);
|
||||||
|
set_reg16(0x40020358, 0x0851);
|
||||||
|
set_reg16(0x4002035c, 0x0a26);
|
||||||
|
set_reg16(0x40020360, 0x0858);
|
||||||
|
set_reg16(0x4002102c, 0xdfe7);
|
||||||
|
set_reg32_mask(0x4002103c, 0x00c00000, 0x0024a19f);
|
||||||
|
set_reg16_mask(0x40021000, 0x0008, 0x000b);
|
||||||
|
set_reg16_mask(0x40020238, 0x03e0, 0x02c0);
|
||||||
|
set_reg16_mask(0x4002023c, 0x03e0, 0x02c0);
|
||||||
|
set_reg16_mask(0x40020244, 0x03e0, 0x0250);
|
||||||
|
set_reg16_mask(0x40020248, 0x03e0, 0x02a0);
|
||||||
|
set_reg16_mask(0x4002024c, 0x03e0, 0x02c0);
|
||||||
|
set_reg16_mask(0x40020288, 0x03e0, 0x0300);
|
||||||
|
set_reg16_mask(0x4002029c, 0x001f, 0x0019);
|
||||||
|
set_reg16_mask(0x4002003c, 0x6000, 0x0788);
|
||||||
|
set_reg16_mask(0x40020074, 0x7f00, 0x2007);
|
||||||
|
set_reg32_mask(0x40020080, 0x00333330, 0x00222224);
|
||||||
|
set_reg32_mask(0x40020068, 0x00000f0f, 0x00000f0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_rfcu_apply_settings(void)
|
||||||
|
{
|
||||||
|
ble_rf_apply_trim(g_cmac_shared_data.trim.rfcu,
|
||||||
|
g_cmac_shared_data.trim.rfcu_len);
|
||||||
|
ble_rf_rfcu_apply_recommended_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_synth_enable(void)
|
||||||
|
{
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ble_rf_synth_disable(void)
|
||||||
|
{
|
||||||
|
set_reg8(0x40020005, 0);
|
||||||
|
__NOP();
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ble_rf_synth_is_enabled(void)
|
||||||
|
{
|
||||||
|
return get_reg32_bits(0x40020004, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_synth_apply_recommended_settings(void)
|
||||||
|
{
|
||||||
|
set_reg32_mask(0x40022048, 0x0000000c, 0x000000d5);
|
||||||
|
set_reg32_mask(0x40022050, 0x00000300, 0x00000300);
|
||||||
|
set_reg16_mask(0x40022024, 0x0001, 0x0001);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_synth_apply_settings(void)
|
||||||
|
{
|
||||||
|
ble_rf_apply_trim(g_cmac_shared_data.trim.synth,
|
||||||
|
g_cmac_shared_data.trim.synth_len);
|
||||||
|
ble_rf_synth_apply_recommended_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_calibration_0(void)
|
||||||
|
{
|
||||||
|
uint32_t bkp[10];
|
||||||
|
|
||||||
|
bkp[0] = get_reg32(0x40020208);
|
||||||
|
bkp[1] = get_reg32(0x40020250);
|
||||||
|
bkp[2] = get_reg32(0x40020254);
|
||||||
|
bkp[3] = get_reg32(0x40021028);
|
||||||
|
bkp[4] = get_reg32(0x40020020);
|
||||||
|
bkp[5] = get_reg32(0x40020294);
|
||||||
|
bkp[6] = get_reg32(0x4002103C);
|
||||||
|
bkp[7] = get_reg32(0x400200A8);
|
||||||
|
bkp[8] = get_reg32(0x40020000);
|
||||||
|
bkp[9] = get_reg32(0x40022000);
|
||||||
|
|
||||||
|
set_reg32_bits(0x40020000, 0x00000002, 0);
|
||||||
|
set_reg32_bits(0x40022000, 0x00000001, 0);
|
||||||
|
set_reg32_mask(0x4002103C, 0x00201c00, 0x00001c00);
|
||||||
|
set_reg32_bits(0x400200A8, 0x00000001, 1);
|
||||||
|
set_reg8(0x40020006, 1);
|
||||||
|
set_reg32(0x40020208, 0);
|
||||||
|
set_reg32(0x40020250, 0);
|
||||||
|
set_reg32(0x40020254, 0);
|
||||||
|
set_reg32(0x40021028, 0x00F8A494);
|
||||||
|
set_reg32(0x40020020, 8);
|
||||||
|
set_reg32(0x40020294, 0);
|
||||||
|
set_reg32(0x40020024, 0);
|
||||||
|
|
||||||
|
delay_us(5);
|
||||||
|
if (get_reg32_bits(0x40020020, 0x00000002)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_reg32_bits(0x40020020, 0x00000001, 1);
|
||||||
|
delay_us(15);
|
||||||
|
if (!get_reg32_bits(0x40020020, 0x00000001)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay_us(300);
|
||||||
|
if (get_reg32_bits(0x40020020, 0x00000001)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
set_reg32(0x40020024, 0);
|
||||||
|
set_reg32(0x40020208, bkp[0]);
|
||||||
|
set_reg32(0x40020250, bkp[1]);
|
||||||
|
set_reg32(0x40020254, bkp[2]);
|
||||||
|
set_reg32(0x40021028, bkp[3]);
|
||||||
|
set_reg32(0x40020020, bkp[4]);
|
||||||
|
set_reg32(0x40020294, bkp[5]);
|
||||||
|
set_reg32(0x4002103C, bkp[6]);
|
||||||
|
set_reg32(0x400200A8, bkp[7]);
|
||||||
|
set_reg32(0x40020000, bkp[8]);
|
||||||
|
set_reg32(0x40022000, bkp[9]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_calibration_1(void)
|
||||||
|
{
|
||||||
|
uint32_t bkp[12];
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
bkp[0] = get_reg32(0x40020020);
|
||||||
|
bkp[1] = get_reg32(0x40020208);
|
||||||
|
bkp[2] = get_reg32(0x40020250);
|
||||||
|
bkp[3] = get_reg32(0x40020254);
|
||||||
|
bkp[4] = get_reg32(0x40020218);
|
||||||
|
bkp[5] = get_reg32(0x4002021c);
|
||||||
|
bkp[6] = get_reg32(0x40020220);
|
||||||
|
bkp[7] = get_reg32(0x40020270);
|
||||||
|
bkp[8] = get_reg32(0x4002027c);
|
||||||
|
bkp[9] = get_reg32(0x4002101c);
|
||||||
|
bkp[10] = get_reg32(0x40020000);
|
||||||
|
bkp[11] = get_reg32(0x40022000);
|
||||||
|
|
||||||
|
set_reg32(0x4002103c, 0x0124a21f);
|
||||||
|
set_reg32(0x40020208, 0);
|
||||||
|
set_reg32(0x40020250, 0);
|
||||||
|
set_reg32(0x40020254, 0);
|
||||||
|
set_reg32(0x40020218, 0);
|
||||||
|
set_reg32(0x4002021c, 0);
|
||||||
|
set_reg32(0x40020220, 0);
|
||||||
|
set_reg32(0x40020270, 0);
|
||||||
|
set_reg32(0x4002027c, 0);
|
||||||
|
set_reg32(0x40020000, 0x0f168820);
|
||||||
|
set_reg32_bits(0x40022000, 0x00000001, 0);
|
||||||
|
set_reg32_bits(0x4002101c, 0x00001e00, 0);
|
||||||
|
set_reg32_bits(0x4002001c, 0x0000003f, 47);
|
||||||
|
set_reg8(0x40020006, 1);
|
||||||
|
set_reg32(0x40020020, 16);
|
||||||
|
set_reg32_bits(0x4002003c, 0x00000800, 1);
|
||||||
|
set_reg32(0x40020024, 0);
|
||||||
|
|
||||||
|
delay_us(5);
|
||||||
|
if (get_reg32_bits(0x40020020, 0x00000002)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_reg32_bits(0x40020020, 0x00000001, 1);
|
||||||
|
delay_us(15);
|
||||||
|
if (!get_reg32_bits(0x40020020, 0x00000001)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay_us(300);
|
||||||
|
if (get_reg32_bits(0x40020020, 0x00000001)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = get_reg32(0x40020090);
|
||||||
|
set_reg32_bits(0x40020094, 0x0000000f, val);
|
||||||
|
set_reg32_bits(0x40020094, 0x00000f00, val);
|
||||||
|
set_reg32_bits(0x40020094, 0x000f0000, val);
|
||||||
|
set_reg32_bits(0x40020094, 0x0f000000, val);
|
||||||
|
g_ble_phy_rf_data.cal_res_1 = get_reg32(0x40020094);
|
||||||
|
|
||||||
|
done:
|
||||||
|
set_reg32(0x40020024, 0);
|
||||||
|
set_reg32(0x40020020, bkp[0]);
|
||||||
|
set_reg32(0x40020208, bkp[1]);
|
||||||
|
set_reg32(0x40020250, bkp[2]);
|
||||||
|
set_reg32(0x40020254, bkp[3]);
|
||||||
|
set_reg32(0x40020218, bkp[4]);
|
||||||
|
set_reg32(0x4002021c, bkp[5]);
|
||||||
|
set_reg32(0x40020220, bkp[6]);
|
||||||
|
set_reg32(0x40020270, bkp[7]);
|
||||||
|
set_reg32(0x4002027c, bkp[8]);
|
||||||
|
set_reg32(0x4002101c, bkp[9]);
|
||||||
|
set_reg32(0x40020000, bkp[10]);
|
||||||
|
set_reg32(0x40022000, bkp[11]);
|
||||||
|
set_reg32_bits(0x4002003c, 0x00000800, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_calibration_2(void)
|
||||||
|
{
|
||||||
|
uint32_t bkp[2];
|
||||||
|
uint32_t k1;
|
||||||
|
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
set_reg32(0x40022000, 0x00000300);
|
||||||
|
set_reg32_bits(0x40022004, 0x0000007f, 20);
|
||||||
|
bkp[0] = get_reg32(0x40022040);
|
||||||
|
set_reg32(0x40022040, 0xffffffff);
|
||||||
|
set_reg32_bits(0x40022018, 0x0000003f, 0);
|
||||||
|
set_reg32_bits(0x40022018, 0x00008000, 0);
|
||||||
|
set_reg32_bits(0x4002201c, 0x00000600, 2);
|
||||||
|
set_reg32_bits(0x4002201c, 0x00000070, 4);
|
||||||
|
set_reg32_bits(0x40022030, 0x3f000000, 22);
|
||||||
|
set_reg32_bits(0x40022030, 0x00000fc0, 24);
|
||||||
|
set_reg32_bits(0x40022030, 0x0000003f, 24);
|
||||||
|
set_reg8(0x4002201c, 0x43);
|
||||||
|
set_reg8(0x40020006, 2);
|
||||||
|
delay_us(2);
|
||||||
|
bkp[1] = get_reg32_bits(0x4002024c, 0x000003e0);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, 0);
|
||||||
|
set_reg8(0x40020006, 1);
|
||||||
|
set_reg32_bits(0x400200ac, 0x00000003, 3);
|
||||||
|
delay_us(30);
|
||||||
|
delay_us(100);
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
k1 = get_reg32_bits(0x40022088, 0x000001ff);
|
||||||
|
set_reg32(0x400200ac, 0);
|
||||||
|
delay_us(20);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, bkp[1]);
|
||||||
|
delay_us(10);
|
||||||
|
|
||||||
|
set_reg32_bits(0x40022018, 0xff800000, k1);
|
||||||
|
set_reg32_bits(0x40022018, 0x00007fc0, k1);
|
||||||
|
set_reg8(0x4002201c, 0x41);
|
||||||
|
set_reg32_bits(0x4002201c, 0x00000600, 2);
|
||||||
|
set_reg8(0x40020006, 2);
|
||||||
|
delay_us(2);
|
||||||
|
bkp[1] = get_reg32_bits(0x4002024c, 0x000003e0);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, 0);
|
||||||
|
set_reg8(0x40020006, 1);
|
||||||
|
set_reg32_bits(0x400200ac, 0x00000003, 3);
|
||||||
|
delay_us(30);
|
||||||
|
delay_us(100);
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
k1 = get_reg32_bits(0x40022088, 0x1ff);
|
||||||
|
set_reg32(0x400200ac, 0);
|
||||||
|
delay_us(20);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, bkp[1]);
|
||||||
|
delay_us(10);
|
||||||
|
|
||||||
|
set_reg32_bits(0x40022018, 0xff800000, k1);
|
||||||
|
set_reg32_bits(0x40022018, 0x00007fc0, k1);
|
||||||
|
set_reg8(0x4002201c, 0x41);
|
||||||
|
set_reg32_bits(0x4002201c, 0x00000600, 2);
|
||||||
|
set_reg8(0x40020006, 2);
|
||||||
|
delay_us(2);
|
||||||
|
bkp[1] = get_reg32_bits(0x4002024c, 0x000003e0);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, 0);
|
||||||
|
set_reg8(0x40020006, 1);
|
||||||
|
set_reg32_bits(0x400200ac, 0x00000003, 3);
|
||||||
|
delay_us(30);
|
||||||
|
delay_us(100);
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
k1 = get_reg32_bits(0x40022088, 0x000001ff);
|
||||||
|
set_reg32_bits(0x40022018, 0xff800000, k1);
|
||||||
|
set_reg32_bits(0x40022018, 0x00007fc0, k1);
|
||||||
|
set_reg32_bits(0x4002201c, 0x00000001, 0);
|
||||||
|
set_reg32(0x40022040, bkp[0]);
|
||||||
|
set_reg32_bits(0x40022018, 0x0000003f, 0x1c);
|
||||||
|
set_reg32_bits(0x40022018, 0x00008000, 0);
|
||||||
|
set_reg32_bits(0x40022030, 0x3f000000, 28);
|
||||||
|
set_reg32_bits(0x40022030, 0x00000fc0, 30);
|
||||||
|
set_reg32_bits(0x40022030, 0x0000003f, 30);
|
||||||
|
set_reg32(0x400200ac, 0);
|
||||||
|
delay_us(20);
|
||||||
|
set_reg32_bits(0x4002024c, 0x000003e0, bkp[1]);
|
||||||
|
delay_us(10);
|
||||||
|
|
||||||
|
g_ble_phy_rf_data.cal_res_2 = k1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_rf_calibrate_int(uint8_t mask)
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
ble_rf_enable();
|
||||||
|
delay_us(20);
|
||||||
|
|
||||||
|
ble_rf_synth_disable();
|
||||||
|
ble_rf_synth_enable();
|
||||||
|
ble_rf_synth_apply_settings();
|
||||||
|
set_reg8(0x40020005, 1);
|
||||||
|
|
||||||
|
if (mask & RF_CALIBRATION_0) {
|
||||||
|
ble_rf_calibration_0();
|
||||||
|
}
|
||||||
|
if (mask & RF_CALIBRATION_1) {
|
||||||
|
ble_rf_calibration_1();
|
||||||
|
}
|
||||||
|
if (mask & RF_CALIBRATION_2) {
|
||||||
|
ble_rf_calibration_2();
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_disable();
|
||||||
|
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
|
||||||
|
g_cmac_shared_data.debug.cal_res_1 = g_ble_phy_rf_data.cal_res_1;
|
||||||
|
g_cmac_shared_data.debug.cal_res_2 = g_ble_phy_rf_data.cal_res_2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ble_rf_try_recalibrate(uint32_t idle_time_us)
|
||||||
|
{
|
||||||
|
/* Run recalibration if we have at least 1ms of time to spare and RF is
|
||||||
|
* currently disabled. Calibration is much shorter than 1ms, but that gives
|
||||||
|
* us good margin to make sure we can finish before next event.
|
||||||
|
*/
|
||||||
|
if (!g_ble_phy_rf_data.calibrate_req || (idle_time_us < 1000) ||
|
||||||
|
ble_rf_is_enabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_calibrate_int(RF_CALIBRATION_2);
|
||||||
|
|
||||||
|
g_ble_phy_rf_data.calibrate_req = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
ble_rf_find_trim_reg(volatile uint32_t *tv, unsigned len, uint32_t reg)
|
||||||
|
{
|
||||||
|
while (len) {
|
||||||
|
if (tv[0] == reg) {
|
||||||
|
return tv[1];
|
||||||
|
}
|
||||||
|
len -= 2;
|
||||||
|
tv += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_init(void)
|
||||||
|
{
|
||||||
|
static bool done = false;
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
ble_rf_disable();
|
||||||
|
|
||||||
|
if (done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu_mode1,
|
||||||
|
g_cmac_shared_data.trim.rfcu_mode1_len,
|
||||||
|
0x4002004c);
|
||||||
|
g_ble_phy_rf_data.trim_val1_tx_1 = val;
|
||||||
|
|
||||||
|
val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu_mode2,
|
||||||
|
g_cmac_shared_data.trim.rfcu_mode2_len,
|
||||||
|
0x4002004c);
|
||||||
|
g_ble_phy_rf_data.trim_val1_tx_2 = val;
|
||||||
|
|
||||||
|
if (!g_ble_phy_rf_data.trim_val1_tx_1 || !g_ble_phy_rf_data.trim_val1_tx_2) {
|
||||||
|
val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.rfcu,
|
||||||
|
g_cmac_shared_data.trim.rfcu_len,
|
||||||
|
0x4002004c);
|
||||||
|
if (!val) {
|
||||||
|
val = 0x0300;
|
||||||
|
}
|
||||||
|
g_ble_phy_rf_data.trim_val1_tx_1 = val;
|
||||||
|
g_ble_phy_rf_data.trim_val1_tx_2 = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = ble_rf_find_trim_reg(g_cmac_shared_data.trim.synth,
|
||||||
|
g_cmac_shared_data.trim.synth_len,
|
||||||
|
0x40022038);
|
||||||
|
if (!val) {
|
||||||
|
val = 0x0198ff03;
|
||||||
|
}
|
||||||
|
g_ble_phy_rf_data.trim_val2_rx = val;
|
||||||
|
g_ble_phy_rf_data.trim_val2_tx = val;
|
||||||
|
set_reg32_bits((uint32_t)&g_ble_phy_rf_data.trim_val2_tx, 0x0001ff00, 0x87);
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
|
||||||
|
g_cmac_shared_data.debug.trim_val1_tx_1 = g_ble_phy_rf_data.trim_val1_tx_1;
|
||||||
|
g_cmac_shared_data.debug.trim_val1_tx_2 = g_ble_phy_rf_data.trim_val1_tx_2;
|
||||||
|
g_cmac_shared_data.debug.trim_val2_tx = g_ble_phy_rf_data.trim_val2_tx;
|
||||||
|
g_cmac_shared_data.debug.trim_val2_rx = g_ble_phy_rf_data.trim_val2_rx;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ble_rf_rfcu_enable();
|
||||||
|
ble_rf_rfcu_apply_settings();
|
||||||
|
g_ble_phy_rf_data.tx_power_cfg1 = get_reg32_bits(0x500000a4, 0xf0);
|
||||||
|
g_ble_phy_rf_data.tx_power_cfg2 = get_reg32_bits(0x40020238, 0x000003e0);
|
||||||
|
g_ble_phy_rf_data.tx_power_cfg3 = 0;
|
||||||
|
ble_rf_rfcu_disable();
|
||||||
|
|
||||||
|
ble_rf_calibrate_int(RF_CALIBRATION_0 | RF_CALIBRATION_1 | RF_CALIBRATION_2);
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_enable(void)
|
||||||
|
{
|
||||||
|
if (ble_rf_is_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_rfcu_enable();
|
||||||
|
ble_rf_rfcu_apply_settings();
|
||||||
|
ble_rf_ldo_on();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_configure(void)
|
||||||
|
{
|
||||||
|
if (ble_rf_synth_is_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_synth_enable();
|
||||||
|
ble_rf_synth_apply_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_stop(void)
|
||||||
|
{
|
||||||
|
ble_rf_synth_disable();
|
||||||
|
set_reg8(0x40020006, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_disable(void)
|
||||||
|
{
|
||||||
|
ble_rf_stop();
|
||||||
|
ble_rf_ldo_off();
|
||||||
|
ble_rf_rfcu_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ble_rf_is_enabled(void)
|
||||||
|
{
|
||||||
|
return get_reg32_bits(0x40020008, 5) == 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_calibrate_req(void)
|
||||||
|
{
|
||||||
|
g_ble_phy_rf_data.calibrate_req = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_setup_tx(uint8_t rf_chan, uint8_t phy_mode)
|
||||||
|
{
|
||||||
|
set_reg32_bits(0x40020000, 0x0f000000, g_ble_phy_rf_data.tx_power_cfg0);
|
||||||
|
set_reg32_bits(0x500000a4, 0x000000f0, g_ble_phy_rf_data.tx_power_cfg1);
|
||||||
|
set_reg32_bits(0x40020238, 0x000003e0, g_ble_phy_rf_data.tx_power_cfg2);
|
||||||
|
set_reg32_bits(0x40020234, 0x000003e0, g_ble_phy_rf_data.tx_power_cfg3);
|
||||||
|
|
||||||
|
if (g_ble_phy_rf_data.tx_power_cfg0 < 13) {
|
||||||
|
set_reg32(0x4002004c, g_ble_phy_rf_data.trim_val1_tx_1);
|
||||||
|
} else {
|
||||||
|
set_reg32(0x4002004c, g_ble_phy_rf_data.trim_val1_tx_2);
|
||||||
|
}
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
set_reg8(0x40022004, rf_chan);
|
||||||
|
if (phy_mode == BLE_PHY_MODE_2M) {
|
||||||
|
#if MYNEWT_VAL(BLE_PHY_RF_HP_MODE)
|
||||||
|
set_reg32(0x40022000, 0x00000303);
|
||||||
|
#else
|
||||||
|
set_reg32(0x40022000, 0x00000003);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if MYNEWT_VAL(BLE_PHY_RF_HP_MODE)
|
||||||
|
set_reg32(0x40022000, 0x00000300);
|
||||||
|
#else
|
||||||
|
set_reg32(0x40022000, 0x00000000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_apply_calibration();
|
||||||
|
|
||||||
|
set_reg32_bits(0x40022050, 0x00000200, 1);
|
||||||
|
set_reg32_bits(0x40022050, 0x00000100, 0);
|
||||||
|
set_reg32_bits(0x40022048, 0x01ffff00, 0x7700);
|
||||||
|
set_reg32(0x40022038, g_ble_phy_rf_data.trim_val2_tx);
|
||||||
|
|
||||||
|
set_reg8(0x40020006, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_setup_rx(uint8_t rf_chan, uint8_t phy_mode)
|
||||||
|
{
|
||||||
|
set_reg32_bits(0x500000a4, 0x000000f0, g_ble_phy_rf_data.tx_power_cfg1);
|
||||||
|
set_reg8(0x40020005, 3);
|
||||||
|
set_reg8(0x40022004, rf_chan);
|
||||||
|
if (phy_mode == BLE_PHY_MODE_2M) {
|
||||||
|
#if MYNEWT_VAL(BLE_PHY_RF_HP_MODE)
|
||||||
|
set_reg32(0x40022000, 0x00000303);
|
||||||
|
set_reg32(0x40020000, 0x0f11b823);
|
||||||
|
set_reg32(0x4002103c, 0x0125261b);
|
||||||
|
#else
|
||||||
|
set_reg32(0x40022000, 0x00000003);
|
||||||
|
set_reg32(0x40020000, 0x0f0c2803);
|
||||||
|
set_reg32(0x4002103c, 0x0125a61b);
|
||||||
|
#endif
|
||||||
|
set_reg32(0x40021020, 0x000002f5);
|
||||||
|
set_reg32(0x4002102c, 0x0000d1d5);
|
||||||
|
} else {
|
||||||
|
#if MYNEWT_VAL(BLE_PHY_RF_HP_MODE)
|
||||||
|
set_reg32(0x40022000, 0x00000300);
|
||||||
|
set_reg32(0x40020000, 0x0f099820);
|
||||||
|
set_reg32(0x4002103c, 0x0124a21f);
|
||||||
|
#else
|
||||||
|
set_reg32(0x40022000, 0x00000000);
|
||||||
|
set_reg32(0x40020000, 0x0f062800);
|
||||||
|
set_reg32(0x4002103c, 0x01051e1f);
|
||||||
|
#endif
|
||||||
|
set_reg32(0x40021020, 0x000002f5);
|
||||||
|
set_reg32(0x4002102c, 0x0000dfe7);
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_rf_apply_calibration();
|
||||||
|
|
||||||
|
set_reg32_bits(0x40022050, 0x00000200, 1);
|
||||||
|
set_reg32_bits(0x40022050, 0x00000100, 1);
|
||||||
|
set_reg32_bits(0x40022048, 0x01ffff00, 0);
|
||||||
|
set_reg32(0x40022038, g_ble_phy_rf_data.trim_val2_rx);
|
||||||
|
|
||||||
|
set_reg8(0x40020006, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ble_rf_set_tx_power(int dbm)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(g_ble_rf_power_lvls); i++) {
|
||||||
|
if (g_ble_rf_power_lvls[i] >= dbm) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ble_phy_rf_data.tx_power_cfg0 = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t
|
||||||
|
ble_rf_get_rssi(void)
|
||||||
|
{
|
||||||
|
return (501 * get_reg32_bits(0x40021038, 0x000003ff) - 493000) / 4096;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 _BLE_RF_PRIV_H_
|
||||||
|
#define _BLE_RF_PRIV_H_
|
||||||
|
|
||||||
|
void ble_rf_init(void);
|
||||||
|
void ble_rf_enable(void);
|
||||||
|
void ble_rf_stop(void);
|
||||||
|
void ble_rf_disable(void);
|
||||||
|
bool ble_rf_is_enabled(void);
|
||||||
|
void ble_rf_configure(void);
|
||||||
|
|
||||||
|
void ble_rf_calibrate(void);
|
||||||
|
|
||||||
|
void ble_rf_setup_tx(uint8_t rf_chan, uint8_t mode);
|
||||||
|
void ble_rf_setup_rx(uint8_t rf_chan, uint8_t mode);
|
||||||
|
|
||||||
|
void ble_rf_set_tx_power(int dbm);
|
||||||
|
int8_t ble_rf_get_rssi(void);
|
||||||
|
|
||||||
|
#endif /* _BLE_RF_PRIV_H_ */
|
29
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/syscfg.yml
Normal file
29
src/libs/mynewt-nimble/nimble/drivers/dialog_cmac/syscfg.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
syscfg.defs:
|
||||||
|
BLE_PHY_RF_HP_MODE:
|
||||||
|
description: Enable high-performance RF mode.
|
||||||
|
value: 1
|
||||||
|
|
||||||
|
BLE_PHY_DEBUG_DSER:
|
||||||
|
description: Enable DSER output from PHY
|
||||||
|
value: 0
|
||||||
|
|
||||||
|
syscfg.restrictions:
|
||||||
|
- BLE_LL_RFMGMT_ENABLE_TIME == 0 || BLE_LL_RFMGMT_ENABLE_TIME >= 20
|
@ -20,6 +20,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "syscfg/syscfg.h"
|
#include "syscfg/syscfg.h"
|
||||||
#include "os/os.h"
|
#include "os/os.h"
|
||||||
#include "nimble/ble.h"
|
#include "nimble/ble.h"
|
||||||
@ -32,6 +34,9 @@
|
|||||||
/* We use this to keep track of which entries are set to valid addresses */
|
/* We use this to keep track of which entries are set to valid addresses */
|
||||||
static uint8_t g_ble_hw_whitelist_mask;
|
static uint8_t g_ble_hw_whitelist_mask;
|
||||||
|
|
||||||
|
static ble_rng_isr_cb_t rng_cb;
|
||||||
|
static bool rng_started;
|
||||||
|
|
||||||
/* Returns public device address or -1 if not present */
|
/* Returns public device address or -1 if not present */
|
||||||
int
|
int
|
||||||
ble_hw_get_public_addr(ble_addr_t *addr)
|
ble_hw_get_public_addr(ble_addr_t *addr)
|
||||||
@ -143,7 +148,8 @@ ble_hw_encrypt_block(struct ble_encryption_block *ecb)
|
|||||||
int
|
int
|
||||||
ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
|
ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
|
||||||
{
|
{
|
||||||
return -1;
|
rng_cb = cb;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,7 +160,15 @@ ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
|
|||||||
int
|
int
|
||||||
ble_hw_rng_start(void)
|
ble_hw_rng_start(void)
|
||||||
{
|
{
|
||||||
return -1;
|
rng_started = true;
|
||||||
|
|
||||||
|
if (rng_cb) {
|
||||||
|
while (rng_started) {
|
||||||
|
rng_cb(rand());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,7 +179,8 @@ ble_hw_rng_start(void)
|
|||||||
int
|
int
|
||||||
ble_hw_rng_stop(void)
|
ble_hw_rng_stop(void)
|
||||||
{
|
{
|
||||||
return -1;
|
rng_started = false;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,7 +191,7 @@ ble_hw_rng_stop(void)
|
|||||||
uint8_t
|
uint8_t
|
||||||
ble_hw_rng_read(void)
|
ble_hw_rng_read(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return rand();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 H_BLE_XCVR_
|
||||||
|
#define H_BLE_XCVR_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XCVR_RX_RADIO_RAMPUP_USECS (40)
|
||||||
|
#define XCVR_TX_RADIO_RAMPUP_USECS (40)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: we have to account for the RTC output compare issue. We want it to be
|
||||||
|
* 5 ticks.
|
||||||
|
*/
|
||||||
|
#define XCVR_PROC_DELAY_USECS (153)
|
||||||
|
#define XCVR_RX_START_DELAY_USECS (XCVR_RX_RADIO_RAMPUP_USECS)
|
||||||
|
#define XCVR_TX_START_DELAY_USECS (XCVR_TX_RADIO_RAMPUP_USECS)
|
||||||
|
#define XCVR_TX_SCHED_DELAY_USECS (XCVR_TX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
|
||||||
|
#define XCVR_RX_SCHED_DELAY_USECS (XCVR_RX_START_DELAY_USECS + XCVR_PROC_DELAY_USECS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define HW whitelist size. This is the total possible whitelist size;
|
||||||
|
* not necessarily the size that will be used (may be smaller)
|
||||||
|
*/
|
||||||
|
#define BLE_HW_WHITE_LIST_SIZE (8)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* H_BLE_XCVR_ */
|
31
src/libs/mynewt-nimble/nimble/drivers/nrf5340/pkg.yml
Normal file
31
src/libs/mynewt-nimble/nimble/drivers/nrf5340/pkg.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
pkg.name: nimble/drivers/nrf5340
|
||||||
|
pkg.description: BLE driver for nRF5340 systems.
|
||||||
|
pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
|
||||||
|
pkg.homepage: "http://mynewt.apache.org/"
|
||||||
|
pkg.keywords:
|
||||||
|
- ble
|
||||||
|
- bluetooth
|
||||||
|
|
||||||
|
pkg.apis: ble_driver
|
||||||
|
pkg.deps:
|
||||||
|
- nimble
|
||||||
|
- nimble/controller
|
475
src/libs/mynewt-nimble/nimble/drivers/nrf5340/src/ble_hw.c
Normal file
475
src/libs/mynewt-nimble/nimble/drivers/nrf5340/src/ble_hw.c
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syscfg/syscfg.h>
|
||||||
|
#include <os/os.h>
|
||||||
|
#include <nimble/ble.h>
|
||||||
|
#include <nimble/nimble_opt.h>
|
||||||
|
#include <controller/ble_hw.h>
|
||||||
|
|
||||||
|
#include <ble/xcvr.h>
|
||||||
|
#include <mcu/cmsis_nvic.h>
|
||||||
|
#include <os/os_trace_api.h>
|
||||||
|
|
||||||
|
/* Total number of resolving list elements */
|
||||||
|
#define BLE_HW_RESOLV_LIST_SIZE (16)
|
||||||
|
|
||||||
|
/* We use this to keep track of which entries are set to valid addresses */
|
||||||
|
static uint8_t g_ble_hw_whitelist_mask;
|
||||||
|
|
||||||
|
/* Random number generator isr callback */
|
||||||
|
static ble_rng_isr_cb_t ble_rng_isr_cb;
|
||||||
|
|
||||||
|
/* If LL privacy is enabled, allocate memory for AAR */
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||||
|
|
||||||
|
/* The NRF5340 supports up to 16 IRK entries */
|
||||||
|
#if (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE) < 16)
|
||||||
|
#define NRF_IRK_LIST_ENTRIES (MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE))
|
||||||
|
#else
|
||||||
|
#define NRF_IRK_LIST_ENTRIES (16)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* NOTE: each entry is 16 bytes long. */
|
||||||
|
uint32_t g_nrf_irk_list[NRF_IRK_LIST_ENTRIES * 4];
|
||||||
|
|
||||||
|
/* Current number of IRK entries */
|
||||||
|
uint8_t g_nrf_num_irks;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Returns public device address or -1 if not present */
|
||||||
|
int
|
||||||
|
ble_hw_get_public_addr(ble_addr_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t addr_high;
|
||||||
|
uint32_t addr_low;
|
||||||
|
|
||||||
|
/* Does FICR have a public address */
|
||||||
|
if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy into device address. We can do this because we know platform */
|
||||||
|
addr_low = NRF_FICR_NS->DEVICEADDR[0];
|
||||||
|
addr_high = NRF_FICR_NS->DEVICEADDR[1];
|
||||||
|
memcpy(addr->val, &addr_low, 4);
|
||||||
|
memcpy(&addr->val[4], &addr_high, 2);
|
||||||
|
addr->type = BLE_ADDR_PUBLIC;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns random static address or -1 if not present */
|
||||||
|
int
|
||||||
|
ble_hw_get_static_addr(ble_addr_t *addr)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if ((NRF_FICR_NS->DEVICEADDRTYPE & 1) == 1) {
|
||||||
|
memcpy(addr->val, (void *)&NRF_FICR_NS->DEVICEADDR[0], 4);
|
||||||
|
memcpy(&addr->val[4], (void *)&NRF_FICR_NS->DEVICEADDR[1], 2);
|
||||||
|
addr->val[5] |= 0xc0;
|
||||||
|
addr->type = BLE_ADDR_RANDOM;
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the whitelist
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_clear(void)
|
||||||
|
{
|
||||||
|
NRF_RADIO_NS->DACNF = 0;
|
||||||
|
g_ble_hw_whitelist_mask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a device to the hw whitelist
|
||||||
|
*
|
||||||
|
* @param addr
|
||||||
|
* @param addr_type
|
||||||
|
*
|
||||||
|
* @return int 0: success, BLE error code otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_whitelist_add(const uint8_t *addr, uint8_t addr_type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t mask;
|
||||||
|
|
||||||
|
/* Find first ununsed device address match element */
|
||||||
|
mask = 0x01;
|
||||||
|
for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) {
|
||||||
|
if ((mask & g_ble_hw_whitelist_mask) == 0) {
|
||||||
|
NRF_RADIO_NS->DAB[i] = get_le32(addr);
|
||||||
|
NRF_RADIO_NS->DAP[i] = get_le16(addr + 4);
|
||||||
|
if (addr_type == BLE_ADDR_RANDOM) {
|
||||||
|
NRF_RADIO_NS->DACNF |= (mask << 8);
|
||||||
|
}
|
||||||
|
g_ble_hw_whitelist_mask |= mask;
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BLE_ERR_MEM_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a device from the hw whitelist
|
||||||
|
*
|
||||||
|
* @param addr
|
||||||
|
* @param addr_type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_rmv(const uint8_t *addr, uint8_t addr_type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t dap;
|
||||||
|
uint16_t txadd;
|
||||||
|
uint32_t dab;
|
||||||
|
uint32_t mask;
|
||||||
|
|
||||||
|
/* Find first ununsed device address match element */
|
||||||
|
dab = get_le32(addr);
|
||||||
|
dap = get_le16(addr + 4);
|
||||||
|
txadd = NRF_RADIO_NS->DACNF >> 8;
|
||||||
|
mask = 0x01;
|
||||||
|
for (i = 0; i < BLE_HW_WHITE_LIST_SIZE; ++i) {
|
||||||
|
if (mask & g_ble_hw_whitelist_mask) {
|
||||||
|
if ((dab == NRF_RADIO_NS->DAB[i]) && (dap == NRF_RADIO_NS->DAP[i])) {
|
||||||
|
if (addr_type == !!(txadd & mask)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < BLE_HW_WHITE_LIST_SIZE) {
|
||||||
|
g_ble_hw_whitelist_mask &= ~mask;
|
||||||
|
NRF_RADIO_NS->DACNF &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the whitelist in HW
|
||||||
|
*
|
||||||
|
* @return int Number of devices allowed in whitelist
|
||||||
|
*/
|
||||||
|
uint8_t
|
||||||
|
ble_hw_whitelist_size(void)
|
||||||
|
{
|
||||||
|
return BLE_HW_WHITE_LIST_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the whitelisted devices
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_enable(void)
|
||||||
|
{
|
||||||
|
/* Enable the configured device addresses */
|
||||||
|
NRF_RADIO_NS->DACNF |= g_ble_hw_whitelist_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the whitelisted devices
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_whitelist_disable(void)
|
||||||
|
{
|
||||||
|
/* Disable all whitelist devices */
|
||||||
|
NRF_RADIO_NS->DACNF &= 0x0000ff00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean function which returns true ('1') if there is a match on the
|
||||||
|
* whitelist.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_whitelist_match(void)
|
||||||
|
{
|
||||||
|
return NRF_RADIO_NS->EVENTS_DEVMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encrypt data */
|
||||||
|
int
|
||||||
|
ble_hw_encrypt_block(struct ble_encryption_block *ecb)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
uint32_t end;
|
||||||
|
uint32_t err;
|
||||||
|
|
||||||
|
/* Stop ECB */
|
||||||
|
NRF_ECB_NS->TASKS_STOPECB = 1;
|
||||||
|
/* XXX: does task stop clear these counters? Anyway to do this quicker? */
|
||||||
|
NRF_ECB_NS->EVENTS_ENDECB = 0;
|
||||||
|
NRF_ECB_NS->EVENTS_ERRORECB = 0;
|
||||||
|
NRF_ECB_NS->ECBDATAPTR = (uint32_t)ecb;
|
||||||
|
|
||||||
|
/* Start ECB */
|
||||||
|
NRF_ECB_NS->TASKS_STARTECB = 1;
|
||||||
|
|
||||||
|
/* Wait till error or done */
|
||||||
|
rc = 0;
|
||||||
|
while (1) {
|
||||||
|
end = NRF_ECB_NS->EVENTS_ENDECB;
|
||||||
|
err = NRF_ECB_NS->EVENTS_ERRORECB;
|
||||||
|
if (end || err) {
|
||||||
|
if (err) {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Random number generator ISR.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ble_rng_isr(void)
|
||||||
|
{
|
||||||
|
uint8_t rnum;
|
||||||
|
|
||||||
|
os_trace_isr_enter();
|
||||||
|
|
||||||
|
/* No callback? Clear and disable interrupts */
|
||||||
|
if (ble_rng_isr_cb == NULL) {
|
||||||
|
NRF_RNG_NS->INTENCLR = 1;
|
||||||
|
NRF_RNG_NS->EVENTS_VALRDY = 0;
|
||||||
|
(void)NRF_RNG_NS->SHORTS;
|
||||||
|
os_trace_isr_exit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there is a value ready grab it */
|
||||||
|
if (NRF_RNG_NS->EVENTS_VALRDY) {
|
||||||
|
NRF_RNG_NS->EVENTS_VALRDY = 0;
|
||||||
|
rnum = (uint8_t)NRF_RNG_NS->VALUE;
|
||||||
|
(*ble_rng_isr_cb)(rnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
os_trace_isr_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the random number generator
|
||||||
|
*
|
||||||
|
* @param cb
|
||||||
|
* @param bias
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_rng_init(ble_rng_isr_cb_t cb, int bias)
|
||||||
|
{
|
||||||
|
/* Set bias */
|
||||||
|
if (bias) {
|
||||||
|
NRF_RNG_NS->CONFIG = 1;
|
||||||
|
} else {
|
||||||
|
NRF_RNG_NS->CONFIG = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we were passed a function pointer we need to enable the interrupt */
|
||||||
|
if (cb != NULL) {
|
||||||
|
#ifndef RIOT_VERSION
|
||||||
|
NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
|
||||||
|
#endif
|
||||||
|
#if MYNEWT
|
||||||
|
NVIC_SetVector(RNG_IRQn, (uint32_t)ble_rng_isr);
|
||||||
|
#else
|
||||||
|
ble_npl_hw_set_isr(RNG_IRQn, ble_rng_isr);
|
||||||
|
#endif
|
||||||
|
NVIC_EnableIRQ(RNG_IRQn);
|
||||||
|
ble_rng_isr_cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the random number generator
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_rng_start(void)
|
||||||
|
{
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
/* No need for interrupt if there is no callback */
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
NRF_RNG_NS->EVENTS_VALRDY = 0;
|
||||||
|
if (ble_rng_isr_cb) {
|
||||||
|
NRF_RNG_NS->INTENSET = 1;
|
||||||
|
}
|
||||||
|
NRF_RNG_NS->TASKS_START = 1;
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the random generator
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_rng_stop(void)
|
||||||
|
{
|
||||||
|
os_sr_t sr;
|
||||||
|
|
||||||
|
/* No need for interrupt if there is no callback */
|
||||||
|
OS_ENTER_CRITICAL(sr);
|
||||||
|
NRF_RNG_NS->INTENCLR = 1;
|
||||||
|
NRF_RNG_NS->TASKS_STOP = 1;
|
||||||
|
NRF_RNG_NS->EVENTS_VALRDY = 0;
|
||||||
|
OS_EXIT_CRITICAL(sr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the random number generator.
|
||||||
|
*
|
||||||
|
* @return uint8_t
|
||||||
|
*/
|
||||||
|
uint8_t
|
||||||
|
ble_hw_rng_read(void)
|
||||||
|
{
|
||||||
|
uint8_t rnum;
|
||||||
|
|
||||||
|
/* Wait for a sample */
|
||||||
|
while (NRF_RNG_NS->EVENTS_VALRDY == 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NRF_RNG_NS->EVENTS_VALRDY = 0;
|
||||||
|
rnum = (uint8_t)NRF_RNG_NS->VALUE;
|
||||||
|
|
||||||
|
return rnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
|
||||||
|
/**
|
||||||
|
* Clear the resolving list
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_resolv_list_clear(void)
|
||||||
|
{
|
||||||
|
g_nrf_num_irks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a device to the hw resolving list
|
||||||
|
*
|
||||||
|
* @param irk Pointer to IRK to add
|
||||||
|
*
|
||||||
|
* @return int 0: success, BLE error code otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_resolv_list_add(uint8_t *irk)
|
||||||
|
{
|
||||||
|
uint32_t *nrf_entry;
|
||||||
|
|
||||||
|
/* Find first ununsed device address match element */
|
||||||
|
if (g_nrf_num_irks == NRF_IRK_LIST_ENTRIES) {
|
||||||
|
return BLE_ERR_MEM_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy into irk list */
|
||||||
|
nrf_entry = &g_nrf_irk_list[4 * g_nrf_num_irks];
|
||||||
|
memcpy(nrf_entry, irk, 16);
|
||||||
|
|
||||||
|
/* Add to total */
|
||||||
|
++g_nrf_num_irks;
|
||||||
|
return BLE_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a device from the hw resolving list
|
||||||
|
*
|
||||||
|
* @param index Index of IRK to remove
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ble_hw_resolv_list_rmv(int index)
|
||||||
|
{
|
||||||
|
uint32_t *irk_entry;
|
||||||
|
|
||||||
|
if (index < g_nrf_num_irks) {
|
||||||
|
--g_nrf_num_irks;
|
||||||
|
irk_entry = &g_nrf_irk_list[index];
|
||||||
|
if (g_nrf_num_irks > index) {
|
||||||
|
memmove(irk_entry, irk_entry + 4, 16 * (g_nrf_num_irks - index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the resolving list. NOTE: this returns the maximum
|
||||||
|
* allowable entries in the HW. Configuration options may limit this.
|
||||||
|
*
|
||||||
|
* @return int Number of devices allowed in resolving list
|
||||||
|
*/
|
||||||
|
uint8_t
|
||||||
|
ble_hw_resolv_list_size(void)
|
||||||
|
{
|
||||||
|
return BLE_HW_RESOLV_LIST_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to determine if the address received was resolved.
|
||||||
|
*
|
||||||
|
* @return int Negative values indicate unresolved address; positive values
|
||||||
|
* indicate index in resolving list of resolved address.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ble_hw_resolv_list_match(void)
|
||||||
|
{
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
if (NRF_AAR_NS->EVENTS_END) {
|
||||||
|
if (NRF_AAR_NS->EVENTS_RESOLVED) {
|
||||||
|
index = NRF_AAR_NS->STATUS;
|
||||||
|
return (int)index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
1820
src/libs/mynewt-nimble/nimble/drivers/nrf5340/src/ble_phy.c
Normal file
1820
src/libs/mynewt-nimble/nimble/drivers/nrf5340/src/ble_phy.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user