Cleanup make includes and formatting rules (#1860)

* Draft cleanup of the folder definition mess

* Move old startup

* Fixup! broken hacky includes

* Update Makefile

* Update Makefile

* Update Makefile

* Bulk format

* Who knew, header guards are a wise idea

* Squash some sizing warnings

* Drop broken usb stack

* Fix BLE headers to be sensible

* Cleaning up proper c styling

* We have newer clang, it does bracketing now

* Run clang-format brackets

* We can drop the old messy bracket-checker with newer clang format

* WiP formatter

* Align grids of scripts by right side

Massively easier to read in nearly all cases

* Excempt the table for compression from formatter
This commit is contained in:
Ben V. Brown
2023-12-27 09:23:12 +11:00
committed by GitHub
parent 849d1f7d40
commit ec5f07ec0c
248 changed files with 58306 additions and 70269 deletions

View File

@@ -91,21 +91,6 @@ check_style_file()
fi;
ret=1
fi;
# - clang-format has neat option for { } in condition blocks but it's available only since version 15:
# * https://clang.llvm.org/docs/ClangFormatStyleOptions.html#insertbraces
# - since reference env is alpine 3.16 with clang-format 13, implement custom parser to do the similar thing here with grep:
# it used to trace missing { and } for if/else/do/while/for BUT IT'S VERY SPECULATIVE, very-very hacky & dirty.
# - if file is problematic but filename only requested make final grep in pipe silent ... UPD: make code messy but shellcheck happy
if [ -z "${LIST}" ]; then
grep -H -n -e "^ .*if .*)$" -e "^ .*else$" -e "^ .* do$" -e "^ .*while .*)$" -e "^ .*for .*)$" "${src}" | grep -v -e "^.*//" -e "^.*:.*: .*if ((.*[^)])$" | sed 's,^,\n\n,; s,: ,:1: error: probably missing { or } for conditional or loop block:\n>>>,;' | grep -e "^.*$"
else
grep -H -n -e "^ .*if .*)$" -e "^ .*else$" -e "^ .* do$" -e "^ .*while .*)$" -e "^ .*for .*)$" "${src}" | grep -v -e "^.*//" -e "^.*:.*: .*if ((.*[^)])$" | sed 's,^,\n\n,; s,: ,:1: error: probably missing { or } for conditional or loop block:\n>>>,;' | grep -q -e "^.*$"
fi;
if [ "${?}" -ne 1 ]; then
# ... and only print the filename
test -z "${LIST}" || echo "${src}"
ret=1;
fi;
return "${ret}"
}

View File

@@ -1,139 +1,236 @@
# Roughly based on LLVM, tweaked a tad for readability on wide screens
---
Language: Cpp
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AlignArrayOfStructures: Right
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCaseColons: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AllowShortEnumsOnASingleLine: false ### <<< Keeps enums as is
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterAttributes: Never
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 200
CommentPragmas: '^ IWYU pragma:'
ColumnLimit: 200
CommentPragmas: "^ IWYU pragma:"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IfMacros:
- KJ_IF_MAYBE
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: ''
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: ".*"
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: "(Test)?$"
IncludeIsMainSourceRegex: ""
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 2
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
KeepEmptyLinesAtEOF: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
...
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
---

View File

@@ -230,8 +230,9 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
static uint32_t samples[BATTFILTERDEPTH];
static uint8_t index = 0;
if (preFillneeded) {
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++) {
samples[i] = getADC(1);
}
preFillneeded--;
}
if (sample) {
@@ -240,8 +241,9 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
}
uint32_t sum = 0;
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++) {
sum += samples[i];
}
sum /= BATTFILTERDEPTH;
if (divisor == 0) {
@@ -273,8 +275,9 @@ void unstick_I2C() {
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
timeout_cnt++;
if (timeout_cnt > timeout)
if (timeout_cnt > timeout) {
return;
}
}
}

View File

@@ -336,8 +336,8 @@ static void MX_GPIO_Init(void) {
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_10 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12
| GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |
GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : KEY_B_Pin KEY_A_Pin */

View File

@@ -139,8 +139,8 @@ HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
HAL_StatusTypeDef HAL_Init(void) {
/* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) \
|| defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || \
defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
/* Prefetch buffer is not available on value line devices */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
@@ -347,7 +347,8 @@ __weak void HAL_Delay(uint32_t Delay) {
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait) {}
while ((HAL_GetTick() - tickstart) < wait) {
}
}
/**

View File

@@ -620,12 +620,12 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc) {
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_JEOC | ADC_FLAG_EOC | ADC_FLAG_JSTRT | ADC_FLAG_STRT));
/* Reset register CR1 */
CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE | ADC_CR1_AWDIE
| ADC_CR1_EOCIE | ADC_CR1_AWDCH));
CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE |
ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH));
/* Reset register CR2 */
CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA
| ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT | ADC_CR2_ADON));
CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA |
ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT | ADC_CR2_ADON));
/* Reset register SMPR1 */
CLEAR_BIT(hadc->Instance->SMPR1, (ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15 | ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13 | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10));
@@ -1874,8 +1874,8 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
assert_param(IS_ADC_RANGE(AnalogWDGConfig->HighThreshold));
assert_param(IS_ADC_RANGE(AnalogWDGConfig->LowThreshold));
if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC)
|| (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) {
if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||
(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) {
assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
}

View File

@@ -941,8 +941,8 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_I
ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion),
ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion)
| ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion));
ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) |
ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion));
} else {
/* Clear the old SQx bits for the selected rank */
MODIFY_REG(hadc->Instance->JSQR,

View File

@@ -305,9 +305,9 @@ void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init) {
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
MPU->RBAR = MPU_Init->BaseAddress;
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos)
| ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos)
| ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
} else {
MPU->RBAR = 0x00U;
MPU->RASR = 0x00U;

View File

@@ -387,8 +387,8 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) {
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2))) {
if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) ||
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2))) {
/* When HSI is used as system clock it will not disabled */
if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) {
return HAL_ERROR;
@@ -535,8 +535,8 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) {
if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON) {

View File

@@ -454,8 +454,8 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {
/* Check if PLLI2S is enabled */
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) {
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
}
}
@@ -474,8 +474,8 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {
/* Check if PLLI2S is enabled */
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) {
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
}
}
@@ -654,8 +654,8 @@ HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
/* Check the parameters */
@@ -714,8 +714,8 @@ HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
/* Disable the main PLL2. */

View File

@@ -2450,8 +2450,8 @@ HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t Outpu
UNUSED(OutputChannel);
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -2541,8 +2541,8 @@ HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t Ou
UNUSED(OutputChannel);
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -2874,8 +2874,8 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channe
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
}
} else {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
} else {
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
@@ -2997,8 +2997,8 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Cha
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
}
} else {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
} else {
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
@@ -3142,11 +3142,11 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Ch
return HAL_ERROR;
}
} else {
if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
|| (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) {
if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) ||
(complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) {
return HAL_BUSY;
} else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
&& (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) {
} else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY) &&
(complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) {
if ((((pData1 == NULL) || (pData2 == NULL))) && (Length > 0U)) {
return HAL_ERROR;
} else {

View File

@@ -311,8 +311,8 @@ HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) {
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -382,8 +382,8 @@ HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) {
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}

View File

@@ -3,8 +3,8 @@
#include "stm32f1xx.h"
#if !defined(HSI_VALUE)
#define HSI_VALUE \
8000000U /*!< Default value of the Internal oscillator in Hz. \
#define HSI_VALUE \
8000000U /*!< Default value of the Internal oscillator in Hz. \
This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */

View File

@@ -207,8 +207,9 @@ void unstick_I2C() {
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
timeout_cnt++;
if (timeout_cnt > timeout)
if (timeout_cnt > timeout) {
return;
}
}
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.

View File

@@ -0,0 +1,344 @@
/**
******************************************************************************
* @file startup_stm32.s
* @author Ac6
* @version V1.0.0
* @date 12-June-2014
******************************************************************************
*/
.syntax unified
.cpu cortex-m3
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.equ BootRAM, 0xF1E0F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex-M. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTC_Alarm_IRQHandler
.word USBWakeUp_IRQHandler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word BootRAM /* @0x108. This is for boot in RAM mode for
STM32F10x Medium Density devices. */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler
/************************ (C) COPYRIGHT Ac6 *****END OF FILE****/

View File

@@ -155,8 +155,8 @@ HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
HAL_StatusTypeDef HAL_Init(void) {
/* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) \
|| defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || \
defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
/* Prefetch buffer is not available on value line devices */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
@@ -352,7 +352,8 @@ __weak void HAL_Delay(uint32_t Delay) {
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait) {}
while ((HAL_GetTick() - tickstart) < wait) {
}
}
/**

View File

@@ -555,12 +555,12 @@ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc) {
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_JEOC | ADC_FLAG_EOC | ADC_FLAG_JSTRT | ADC_FLAG_STRT));
/* Reset register CR1 */
CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE | ADC_CR1_AWDIE
| ADC_CR1_EOCIE | ADC_CR1_AWDCH));
CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM | ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO | ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE |
ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH));
/* Reset register CR2 */
CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA
| ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT | ADC_CR2_ADON));
CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART | ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA |
ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT | ADC_CR2_ADON));
/* Reset register SMPR1 */
CLEAR_BIT(hadc->Instance->SMPR1, (ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15 | ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13 | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10));
@@ -1194,7 +1194,6 @@ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, ui
/* Set the DMA transfer complete callback */
hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
/* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
/* start (in case of SW start): */
@@ -1352,7 +1351,6 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc) {
}
}
/* Clear regular group conversion flag */
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC);
}
@@ -1393,12 +1391,8 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc) {
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC));
}
}
}
/**
* @}
*/
@@ -1438,7 +1432,7 @@ void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc) {
* @retval HAL status
*/
HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConfTypeDef *sConfig) {
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
@@ -1472,8 +1466,6 @@ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, ADC_ChannelConf
MODIFY_REG(hadc->Instance->SMPR2, ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel), ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel));
}
/* Process unlocked */
__HAL_UNLOCK(hadc);
@@ -1503,8 +1495,8 @@ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, ADC_AnalogWDG
assert_param(IS_ADC_RANGE(AnalogWDGConfig->HighThreshold));
assert_param(IS_ADC_RANGE(AnalogWDGConfig->LowThreshold));
if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC)
|| (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) {
if ((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) ||
(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) {
assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
}
@@ -1712,11 +1704,6 @@ void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) {
}
}
/**
* @}
*/

View File

@@ -661,7 +661,6 @@ HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t
/* Set the DMA transfer complete callback */
hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
/* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
/* start (in case of SW start): */
@@ -899,7 +898,7 @@ __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
* @retval None
*/
HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_InjectionConfTypeDef *sConfigInjected) {
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
@@ -964,8 +963,8 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_I
ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion),
ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion)
| ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion));
ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) |
ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion));
} else {
/* Clear the old SQx bits for the selected rank */
MODIFY_REG(hadc->Instance->JSQR,
@@ -1028,9 +1027,6 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_I
MODIFY_REG(hadc->Instance->SMPR2, ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel), ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel));
}
/* Configure the offset: offset enable/disable, InjectedChannel, offset value */
switch (sConfigInjected->InjectedRank) {
case 1:
@@ -1051,7 +1047,6 @@ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, ADC_I
break;
}
/* Process unlocked */
__HAL_UNLOCK(hadc);

View File

@@ -321,9 +321,9 @@ void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init) {
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
MPU->RBAR = MPU_Init->BaseAddress;
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos)
| ((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos)
| ((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) | ((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) | ((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) | ((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) | ((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) | ((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) | ((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
} else {
MPU->RBAR = 0x00U;
MPU->RASR = 0x00U;

View File

@@ -956,8 +956,6 @@ HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData
/* Clear ADDR flag */
__HAL_I2C_CLEAR_ADDRFLAG(hi2c);
while (hi2c->XferSize > 0U) {
/* Wait until TXE flag is set */
if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) {
@@ -3183,8 +3181,8 @@ void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) {
tmp2 = hi2c->XferCount;
tmp3 = hi2c->State;
tmp4 = hi2c->PreviousState;
if ((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U)
&& ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) {
if ((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) &&
((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) {
} else {
hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
@@ -3717,7 +3715,6 @@ static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) {
return HAL_OK;
}
/**
* @brief Handle ADDR flag for Master
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
@@ -3963,7 +3960,6 @@ static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_
/* Send slave address */
hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress);
}
/* Wait until ADDR flag is set */
if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {
@@ -4012,7 +4008,6 @@ static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t
/* Send slave address */
hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress);
}
/* Wait until ADDR flag is set */
if (I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) {

View File

@@ -360,8 +360,8 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) {
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2))) {
if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) ||
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2))) {
/* When HSI is used as system clock it will not disabled */
if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) {
return HAL_ERROR;
@@ -416,8 +416,8 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) {
if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON) {

View File

@@ -470,8 +470,8 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {
/* Check if PLLI2S is enabled */
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) {
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
}
}
@@ -490,8 +490,8 @@ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {
/* Check if PLLI2S is enabled */
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) {
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
}
}
@@ -670,8 +670,8 @@ HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
/* Check the parameters */
@@ -730,8 +730,8 @@ HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void) {
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
clock (i.e. it is used as PLL clock entry that is used as system clock). */
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
&& ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) &&
((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) {
return HAL_ERROR;
} else {
/* Disable the main PLL2. */

View File

@@ -2450,8 +2450,8 @@ HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t Outpu
UNUSED(OutputChannel);
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -2541,8 +2541,8 @@ HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t Ou
UNUSED(OutputChannel);
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -2874,8 +2874,8 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channe
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
}
} else {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
} else {
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
@@ -2997,8 +2997,8 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Cha
TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY);
}
} else {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
} else {
TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY);
@@ -3142,11 +3142,11 @@ HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Ch
return HAL_ERROR;
}
} else {
if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)
|| (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) {
if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) ||
(complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) {
return HAL_BUSY;
} else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)
&& (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) {
} else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY) &&
(complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) {
if ((((pData1 == NULL) || (pData2 == NULL))) && (Length > 0U)) {
return HAL_ERROR;
} else {

View File

@@ -311,8 +311,8 @@ HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) {
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}
@@ -382,8 +382,8 @@ HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) {
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
/* Check the TIM channels state */
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)
|| (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) ||
(complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) {
return HAL_ERROR;
}

View File

@@ -208,7 +208,8 @@ static void prvTaskExitError(void) {
// therefore not output an 'unreachable code' warning for code that appears
// after it. */
// }
for (;;) {}
for (;;) {
}
}
/*-----------------------------------------------------------*/

View File

@@ -3,8 +3,8 @@
#include "stm32f1xx.h"
#if !defined(HSI_VALUE)
#define HSI_VALUE \
8000000U /*!< Default value of the Internal oscillator in Hz. \
#define HSI_VALUE \
8000000U /*!< Default value of the Internal oscillator in Hz. \
This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */

View File

@@ -145,11 +145,13 @@ void perform_i2c_step() {
if (currentState.numberOfBytes == 1) {
/* disable acknowledge */
i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
}
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
/* wait for the byte to be received */
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
}
/* read the byte received from the EEPROM */
*currentState.buffer = i2c_data_receive(I2C0);
while (i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
@@ -163,10 +165,12 @@ void perform_i2c_step() {
} else if (currentState.numberOfBytes == 2) {
/* disable acknowledge */
i2c_master_addressing(I2C0, currentState.deviceAddress, I2C_RECEIVER);
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
}
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
/* wait for the byte to be received */
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
}
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
@@ -175,7 +179,8 @@ void perform_i2c_step() {
currentState.buffer++;
/* wait for the byte to be received */
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
}
/* read the byte received from the EEPROM */
*currentState.buffer = i2c_data_receive(I2C0);
while (i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
@@ -204,20 +209,23 @@ void perform_i2c_step() {
if (3 == currentState.numberOfBytes) {
/* wait until BTC bit is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {
}
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
} else if (2 == currentState.numberOfBytes) {
/* wait until BTC bit is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC)) {
}
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
/* send a stop condition to I2C bus */
i2c_stop_on_bus(I2C0);
}
/* wait until RBNE bit is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {}
while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) {
}
/* read a byte from the EEPROM */
*currentState.buffer = i2c_data_receive(I2C0);
@@ -296,8 +304,9 @@ bool perform_i2c_transaction(uint16_t DevAddress, uint16_t memory_address, uint8
}
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_buffer, uint16_t number_of_byte) {
if (!lock())
if (!lock()) {
return false;
}
bool res = perform_i2c_transaction(DevAddress, read_address, p_buffer, number_of_byte, false, false);
if (!res) {
I2C_Unstick();
@@ -307,8 +316,9 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_b
}
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_buffer, uint16_t number_of_byte) {
if (!lock())
if (!lock()) {
return false;
}
bool res = perform_i2c_transaction(DevAddress, MemAddress, p_buffer, number_of_byte, true, false);
if (!res) {
I2C_Unstick();
@@ -349,8 +359,9 @@ bool FRToSI2C::writeRegistersBulk(const uint8_t address, const I2C_REG *register
bool FRToSI2C::wakePart(uint16_t DevAddress) {
// wakepart is a special case where only the device address is sent
if (!lock())
if (!lock()) {
return false;
}
bool res = perform_i2c_transaction(DevAddress, 0, NULL, 0, false, true);
if (!res) {
I2C_Unstick();

View File

@@ -46,8 +46,8 @@ static uint16_t USBFS_TX_FIFO_SIZE[USBFS_MAX_EP_COUNT] = {(uint16_t)TX0_FIFO_FS_
#elif defined(USB_HS_CORE)
uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_EP_COUNT]
= {(uint16_t)TX0_FIFO_HS_SIZE, (uint16_t)TX1_FIFO_HS_SIZE, (uint16_t)TX2_FIFO_HS_SIZE, (uint16_t)TX3_FIFO_HS_SIZE, (uint16_t)TX4_FIFO_HS_SIZE, (uint16_t)TX5_FIFO_HS_SIZE};
uint16_t USBHS_TX_FIFO_SIZE[USBHS_MAX_EP_COUNT] = {(uint16_t)TX0_FIFO_HS_SIZE, (uint16_t)TX1_FIFO_HS_SIZE, (uint16_t)TX2_FIFO_HS_SIZE,
(uint16_t)TX3_FIFO_HS_SIZE, (uint16_t)TX4_FIFO_HS_SIZE, (uint16_t)TX5_FIFO_HS_SIZE};
#endif /* USBFS_CORE */

View File

@@ -32,7 +32,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSI
OF SUCH DAMAGE.
*/
#include "gd32vf103_libopt.h"
//#include "usbd_conf.h"
// #include "usbd_conf.h"
#include "drv_usbd_int.h"
#include "usbd_transc.h"
@@ -45,8 +45,8 @@ static uint32_t usbd_int_suspend(usb_core_driver *udev);
static uint32_t usbd_emptytxfifo_write(usb_core_driver *udev, uint32_t ep_num);
static const uint8_t USB_SPEED[4]
= {[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = USB_SPEED_HIGH, [DSTAT_EM_FS_PHY_30MHZ_60MHZ] = USB_SPEED_FULL, [DSTAT_EM_FS_PHY_48MHZ] = USB_SPEED_FULL, [DSTAT_EM_LS_PHY_6MHZ] = USB_SPEED_LOW};
static const uint8_t USB_SPEED[4] = {
[DSTAT_EM_HS_PHY_30MHZ_60MHZ] = USB_SPEED_HIGH, [DSTAT_EM_FS_PHY_30MHZ_60MHZ] = USB_SPEED_FULL, [DSTAT_EM_FS_PHY_48MHZ] = USB_SPEED_FULL, [DSTAT_EM_LS_PHY_6MHZ] = USB_SPEED_LOW};
__IO uint8_t setupc_flag = 0U;
@@ -230,7 +230,8 @@ void usbd_isr(usb_core_driver *udev) {
/* OTG mode interrupt */
if (intr & GINTF_OTGIF) {
if (udev->regs.gr->GOTGINTF & GOTGINTF_SESEND) {}
if (udev->regs.gr->GOTGINTF & GOTGINTF_SESEND) {
}
/* Clear OTG interrupt */
udev->regs.gr->GINTF = GINTF_OTGIF;

View File

@@ -70,8 +70,8 @@ static usb_reqsta (*_std_dev_req[])(usb_core_driver *udev, usb_req *req) = {
};
/* get standard descriptor handler */
static uint8_t *(*std_desc_get[])(usb_core_driver *udev, uint8_t index, uint16_t *len)
= {[USB_DESCTYPE_DEV - 1] = _usb_dev_desc_get, [USB_DESCTYPE_CONFIG - 1] = _usb_config_desc_get, [USB_DESCTYPE_STR - 1] = _usb_str_desc_get};
static uint8_t *(*std_desc_get[])(usb_core_driver *udev, uint8_t index,
uint16_t *len) = {[USB_DESCTYPE_DEV - 1] = _usb_dev_desc_get, [USB_DESCTYPE_CONFIG - 1] = _usb_config_desc_get, [USB_DESCTYPE_STR - 1] = _usb_str_desc_get};
/*!
\brief handle USB standard device request

View File

@@ -72,8 +72,8 @@ usbh_status usbh_devdesc_get(usb_core_driver *pudev, usbh_host *puhost, uint8_t
usbh_control *usb_ctl = &puhost->control;
if (CTL_IDLE == usb_ctl->ctl_state) {
usb_ctl->setup.req
= (usb_req){.bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, .bRequest = USB_GET_DESCRIPTOR, .wValue = USBH_DESC(USB_DESCTYPE_DEV), .wIndex = 0U, .wLength = len};
usb_ctl->setup.req =
(usb_req){.bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, .bRequest = USB_GET_DESCRIPTOR, .wValue = USBH_DESC(USB_DESCTYPE_DEV), .wIndex = 0U, .wLength = len};
usbh_ctlstate_config(puhost, pudev->host.rx_buf, len);
}
@@ -102,8 +102,8 @@ usbh_status usbh_cfgdesc_get(usb_core_driver *pudev, usbh_host *puhost, uint16_t
usbh_control *usb_ctl = &puhost->control;
if (CTL_IDLE == usb_ctl->ctl_state) {
usb_ctl->setup.req
= (usb_req){.bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, .bRequest = USB_GET_DESCRIPTOR, .wValue = USBH_DESC(USB_DESCTYPE_CONFIG), .wIndex = 0U, .wLength = len};
usb_ctl->setup.req =
(usb_req){.bmRequestType = USB_TRX_IN | USB_RECPTYPE_DEV | USB_REQTYPE_STRD, .bRequest = USB_GET_DESCRIPTOR, .wValue = USBH_DESC(USB_DESCTYPE_CONFIG), .wIndex = 0U, .wLength = len};
usbh_ctlstate_config(puhost, pudev->host.rx_buf, len);
}
@@ -266,13 +266,15 @@ usbh_status usbh_clrfeature(usb_core_driver *pudev, usbh_host *puhost, uint8_t e
\retval operation status
*/
static void usbh_devdesc_parse(usb_desc_dev *dev_desc, uint8_t *buf, uint16_t len) {
*dev_desc = (usb_desc_dev){.header = {.bLength = *(uint8_t *)(buf + 0U), .bDescriptorType = *(uint8_t *)(buf + 1U)},
*dev_desc = (usb_desc_dev){
.header = {.bLength = *(uint8_t *)(buf + 0U), .bDescriptorType = *(uint8_t *)(buf + 1U)},
.bcdUSB = BYTE_SWAP(buf + 2U),
.bDeviceClass = *(uint8_t *)(buf + 4U),
.bDeviceSubClass = *(uint8_t *)(buf + 5U),
.bDeviceProtocol = *(uint8_t *)(buf + 6U),
.bMaxPacketSize0 = *(uint8_t *)(buf + 7U)};
.bcdUSB = BYTE_SWAP(buf + 2U),
.bDeviceClass = *(uint8_t *)(buf + 4U),
.bDeviceSubClass = *(uint8_t *)(buf + 5U),
.bDeviceProtocol = *(uint8_t *)(buf + 6U),
.bMaxPacketSize0 = *(uint8_t *)(buf + 7U)
};
if (len > 8U) {
/* for 1st time after device connection, host may issue only 8 bytes for device descriptor length */
@@ -295,19 +297,20 @@ static void usbh_devdesc_parse(usb_desc_dev *dev_desc, uint8_t *buf, uint16_t le
*/
static void usbh_cfgdesc_parse(usb_desc_config *cfg_desc, uint8_t *buf) {
/* parse configuration descriptor */
*cfg_desc = (usb_desc_config) {
.header = {
.bLength = *(uint8_t *)(buf + 0U),
.bDescriptorType = *(uint8_t *)(buf + 1U),
},
*cfg_desc = (usb_desc_config){
.header =
{
.bLength = *(uint8_t *)(buf + 0U),
.bDescriptorType = *(uint8_t *)(buf + 1U),
},
.wTotalLength = BYTE_SWAP(buf + 2U),
.bNumInterfaces = *(uint8_t *)(buf + 4U),
.bConfigurationValue = *(uint8_t *)(buf + 5U),
.iConfiguration = *(uint8_t *)(buf + 6U),
.bmAttributes = *(uint8_t *)(buf + 7U),
.bMaxPower = *(uint8_t *)(buf + 8U)
};
.wTotalLength = BYTE_SWAP(buf + 2U),
.bNumInterfaces = *(uint8_t *)(buf + 4U),
.bConfigurationValue = *(uint8_t *)(buf + 5U),
.iConfiguration = *(uint8_t *)(buf + 6U),
.bmAttributes = *(uint8_t *)(buf + 7U),
.bMaxPower = *(uint8_t *)(buf + 8U)
};
}
/*!
@@ -318,7 +321,7 @@ static void usbh_cfgdesc_parse(usb_desc_config *cfg_desc, uint8_t *buf) {
\retval operation status
*/
static void usbh_cfgset_parse(usb_dev_prop *udev, uint8_t *buf) {
usb_desc_ep * ep = NULL;
usb_desc_ep *ep = NULL;
usb_desc_itf *itf = NULL, itf_value;
usb_desc_header *pdesc = (usb_desc_header *)buf;
@@ -388,20 +391,21 @@ static void usbh_cfgset_parse(usb_dev_prop *udev, uint8_t *buf) {
\retval operation status
*/
static void usbh_itfdesc_parse(usb_desc_itf *itf_desc, uint8_t *buf) {
*itf_desc = (usb_desc_itf) {
.header = {
.bLength = *(uint8_t *)(buf + 0U),
.bDescriptorType = *(uint8_t *)(buf + 1U),
},
*itf_desc = (usb_desc_itf){
.header =
{
.bLength = *(uint8_t *)(buf + 0U),
.bDescriptorType = *(uint8_t *)(buf + 1U),
},
.bInterfaceNumber = *(uint8_t *)(buf + 2U),
.bAlternateSetting = *(uint8_t *)(buf + 3U),
.bNumEndpoints = *(uint8_t *)(buf + 4U),
.bInterfaceClass = *(uint8_t *)(buf + 5U),
.bInterfaceSubClass = *(uint8_t *)(buf + 6U),
.bInterfaceProtocol = *(uint8_t *)(buf + 7U),
.iInterface = *(uint8_t *)(buf + 8U)
};
.bInterfaceNumber = *(uint8_t *)(buf + 2U),
.bAlternateSetting = *(uint8_t *)(buf + 3U),
.bNumEndpoints = *(uint8_t *)(buf + 4U),
.bInterfaceClass = *(uint8_t *)(buf + 5U),
.bInterfaceSubClass = *(uint8_t *)(buf + 6U),
.bInterfaceProtocol = *(uint8_t *)(buf + 7U),
.iInterface = *(uint8_t *)(buf + 8U)
};
}
/*!
@@ -412,12 +416,14 @@ static void usbh_itfdesc_parse(usb_desc_itf *itf_desc, uint8_t *buf) {
\retval operation status
*/
static void usbh_epdesc_parse(usb_desc_ep *ep_desc, uint8_t *buf) {
*ep_desc = (usb_desc_ep){.header = {.bLength = *(uint8_t *)(buf + 0U), .bDescriptorType = *(uint8_t *)(buf + 1U)},
*ep_desc = (usb_desc_ep){
.header = {.bLength = *(uint8_t *)(buf + 0U), .bDescriptorType = *(uint8_t *)(buf + 1U)},
.bEndpointAddress = *(uint8_t *)(buf + 2U),
.bmAttributes = *(uint8_t *)(buf + 3U),
.wMaxPacketSize = BYTE_SWAP(buf + 4U),
.bInterval = *(uint8_t *)(buf + 6U)};
.bEndpointAddress = *(uint8_t *)(buf + 2U),
.bmAttributes = *(uint8_t *)(buf + 3U),
.wMaxPacketSize = BYTE_SWAP(buf + 4U),
.bInterval = *(uint8_t *)(buf + 6U)
};
}
/*!

View File

@@ -199,11 +199,13 @@ void adc_calibration_enable(uint32_t adc_periph) {
/* reset the selected ADC1 calibration registers */
ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_RSTCLB;
/* check the RSTCLB bit state */
while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {}
while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {
}
/* enable ADC calibration process */
ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
/* check the CLB bit state */
while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {}
while ((uint32_t)RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {
}
}
/*!

View File

@@ -37,8 +37,9 @@ OF SUCH DAMAGE.
#include "gd32vf103_dma.h"
#include "gd32vf103_rcu.h"
#define DMA_WRONG_HANDLE \
while (1) {}
#define DMA_WRONG_HANDLE \
while (1) { \
}
/* check whether peripheral matches channels or not */
static ErrStatus dma_periph_and_channel_check(uint32_t dma_periph, dma_channel_enum channelx);

View File

@@ -114,14 +114,14 @@ void exmc_norsram_init(exmc_norsram_parameter_struct *exmc_norsram_init_struct)
/* clear relative bits */
snctl &= ((uint32_t) ~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_NRMUX));
snctl |= (uint32_t)((uint32_t)exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | exmc_norsram_init_struct->memory_type | exmc_norsram_init_struct->databus_width
| exmc_norsram_init_struct->nwait_polarity | ((uint32_t)exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET)
| ((uint32_t)exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | ((uint32_t)exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET);
snctl |= (uint32_t)((uint32_t)exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) | exmc_norsram_init_struct->memory_type | exmc_norsram_init_struct->databus_width |
exmc_norsram_init_struct->nwait_polarity | ((uint32_t)exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
((uint32_t)exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) | ((uint32_t)exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET);
sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U) & EXMC_SNTCFG_ASET)
| (((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U) << SNTCFG_AHLD_OFFSET) & EXMC_SNTCFG_AHLD)
| (((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U) << SNTCFG_DSET_OFFSET) & EXMC_SNTCFG_DSET)
| (((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U) << SNTCFG_BUSLAT_OFFSET) & EXMC_SNTCFG_BUSLAT);
sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U) & EXMC_SNTCFG_ASET) |
(((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U) << SNTCFG_AHLD_OFFSET) & EXMC_SNTCFG_AHLD) |
(((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U) << SNTCFG_DSET_OFFSET) & EXMC_SNTCFG_DSET) |
(((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U) << SNTCFG_BUSLAT_OFFSET) & EXMC_SNTCFG_BUSLAT);
/* nor flash access enable */
if (EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) {

View File

@@ -188,7 +188,8 @@ void ob_unlock(void) {
}
/* wait until OBWEN bit is set by hardware */
while (RESET == (FMC_CTL & FMC_CTL_OBWEN)) {}
while (RESET == (FMC_CTL & FMC_CTL_OBWEN)) {
}
}
/*!

View File

@@ -54,8 +54,8 @@ void rcu_deinit(void) {
RCU_CTL &= ~RCU_CTL_HXTALBPS;
RCU_CTL &= ~(RCU_CTL_PLL1EN | RCU_CTL_PLL2EN);
/* reset CFG0 register */
RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | RCU_CFG0_USBFSPSC | RCU_CFG0_CKOUT0SEL
| RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4);
RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_ADCPSC | RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0_LSB | RCU_CFG0_PLLMF | RCU_CFG0_USBFSPSC |
RCU_CFG0_CKOUT0SEL | RCU_CFG0_ADCPSC_2 | RCU_CFG0_PLLMF_4);
/* reset INT and CFG1 register */
RCU_INT = 0x00ff0000U;
RCU_CFG1 &= ~(RCU_CFG1_PREDV0 | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PLL2MF | RCU_CFG1_PREDV0SEL | RCU_CFG1_I2S1SEL | RCU_CFG1_I2S2SEL);

View File

@@ -97,7 +97,8 @@ void rtc_prescaler_set(uint32_t psc) {
*/
void rtc_lwoff_wait(void) {
/* loop until LWOFF flag is set */
while (RESET == (RTC_CTL & RTC_CTL_LWOFF)) {}
while (RESET == (RTC_CTL & RTC_CTL_LWOFF)) {
}
}
/*!
@@ -110,7 +111,8 @@ void rtc_register_sync_wait(void) {
/* clear RSYNF flag */
RTC_CTL &= ~RTC_CTL_RSYNF;
/* loop until RSYNF flag is set */
while (RESET == (RTC_CTL & RTC_CTL_RSYNF)) {}
while (RESET == (RTC_CTL & RTC_CTL_RSYNF)) {
}
}
/*!

View File

@@ -482,8 +482,8 @@ void timer_break_struct_para_init(timer_break_parameter_struct *breakpara) {
\retval none
*/
void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct *breakpara) {
TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | ((uint32_t)(breakpara->ideloffstate)) | ((uint32_t)(breakpara->deadtime)) | ((uint32_t)(breakpara->breakpolarity))
| ((uint32_t)(breakpara->outputautostate)) | ((uint32_t)(breakpara->protectmode)) | ((uint32_t)(breakpara->breakstate)));
TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate)) | ((uint32_t)(breakpara->ideloffstate)) | ((uint32_t)(breakpara->deadtime)) | ((uint32_t)(breakpara->breakpolarity)) |
((uint32_t)(breakpara->outputautostate)) | ((uint32_t)(breakpara->protectmode)) | ((uint32_t)(breakpara->breakstate)));
}
/*!

View File

@@ -44,8 +44,9 @@ uint64_t get_timer_value(void) {
while (1) {
uint32_t hi = mtime_hi();
uint32_t lo = mtime_lo();
if (hi == mtime_hi())
if (hi == mtime_hi()) {
return ((uint64_t)hi << 32) | lo;
}
}
}
@@ -278,8 +279,8 @@ void eclic_mode_enable() {
write_csr(CSR_MTVEC, mtvec_value);
#elif defined(__GNUC__)
uint32_t mtvec_value = read_csr(mtvec);
mtvec_value = mtvec_value & 0xFFFFFFC0;
mtvec_value = mtvec_value | 0x00000003;
mtvec_value = mtvec_value & 0xFFFFFFC0;
mtvec_value = mtvec_value | 0x00000003;
write_csr(mtvec, mtvec_value);
#endif
}

View File

@@ -110,7 +110,8 @@ static void system_clock_108m_hxtal(void) {
/* if fail */
if (0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
while (1) {}
while (1) {
}
}
/* HXTAL is stable */
@@ -133,12 +134,14 @@ static void system_clock_108m_hxtal(void) {
/* enable PLL1 */
RCU_CTL |= RCU_CTL_PLL1EN;
/* wait till PLL1 is ready */
while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {}
while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {
}
/* enable PLL1 */
RCU_CTL |= RCU_CTL_PLL2EN;
/* wait till PLL1 is ready */
while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {}
while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {
}
} else if (HXTAL_VALUE == 8000000) {
RCU_CFG1 &= ~(RCU_CFG1_PREDV0SEL | RCU_CFG1_PREDV1 | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV0);
RCU_CFG1 |= (RCU_PREDV0SRC_HXTAL | RCU_PREDV0_DIV2 | RCU_PREDV1_DIV2 | RCU_PLL1_MUL20 | RCU_PLL2_MUL20);
@@ -146,25 +149,29 @@ static void system_clock_108m_hxtal(void) {
/* enable PLL1 */
RCU_CTL |= RCU_CTL_PLL1EN;
/* wait till PLL1 is ready */
while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {}
while (0U == (RCU_CTL & RCU_CTL_PLL1STB)) {
}
/* enable PLL2 */
RCU_CTL |= RCU_CTL_PLL2EN;
/* wait till PLL1 is ready */
while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {}
while (0U == (RCU_CTL & RCU_CTL_PLL2STB)) {
}
}
/* enable PLL */
RCU_CTL |= RCU_CTL_PLLEN;
/* wait until PLL is stable */
while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {}
while (0U == (RCU_CTL & RCU_CTL_PLLSTB)) {
}
/* select PLL as system clock */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLL;
/* wait until PLL is selected as system clock */
while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {}
while (0U == (RCU_CFG0 & RCU_SCSS_PLL)) {
}
}
/*!
@@ -343,8 +350,8 @@ static void system_default_exception_handler(unsigned long mcause, unsigned long
printf("MCAUSE: 0x%lx\r\n", mcause);
printf("MEPC : 0x%lx\r\n", __RV_CSR_READ(CSR_MEPC));
printf("MTVAL : 0x%lx\r\n", __RV_CSR_READ(CSR_MBADADDR));
while (1)
;
while (1) {
}
}
/**

View File

@@ -79,21 +79,21 @@
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#if (configSUPPORT_DYNAMIC_ALLOCATION == 0)
#error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
#endif
/* Block sizes must not get too small. */
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
#define heapMINIMUM_BLOCK_SIZE ((size_t)(xHeapStructSize << 1))
/* Assumes 8bit bytes! */
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
#define heapBITS_PER_BYTE ((size_t)8)
/* Define the linked list structure. This is used to link free blocks in order
* of their memory address. */
typedef struct A_BLOCK_LINK {
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
/*-----------------------------------------------------------*/
@@ -104,13 +104,13 @@ typedef struct A_BLOCK_LINK {
* the block in front it and/or the block behind it if the memory blocks are
* adjacent to each other.
*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert);
/*-----------------------------------------------------------*/
/* The size of the structure placed at the beginning of each allocated memory
* block must by correctly byte aligned. */
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
static const size_t xHeapStructSize = (sizeof(BlockLink_t) + ((size_t)(portBYTE_ALIGNMENT - 1))) & ~((size_t)portBYTE_ALIGNMENT_MASK);
/* Create a couple of list links to mark the start and end of the list. */
static BlockLink_t xStart, *pxEnd = NULL;
@@ -130,13 +130,13 @@ static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize ) {
void *pvPortMalloc(size_t xWantedSize) {
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
/* The heap must be initialised before the first call to
* prvPortMalloc(). */
configASSERT( pxEnd );
configASSERT(pxEnd);
vTaskSuspendAll();
{
@@ -144,17 +144,17 @@ void *pvPortMalloc( size_t xWantedSize ) {
* set. The top bit of the block size member of the BlockLink_t structure
* is used to determine who owns the block - the application or the
* kernel, so it must be free. */
if ( ( xWantedSize & xBlockAllocatedBit ) == 0 ) {
if ((xWantedSize & xBlockAllocatedBit) == 0) {
/* The wanted size is increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if ( xWantedSize > 0 ) {
if (xWantedSize > 0) {
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number
* of bytes. */
if ( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) {
if ((xWantedSize & portBYTE_ALIGNMENT_MASK) != 0x00) {
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
xWantedSize += (portBYTE_ALIGNMENT - (xWantedSize & portBYTE_ALIGNMENT_MASK));
} else {
mtCOVERAGE_TEST_MARKER();
}
@@ -162,23 +162,23 @@ void *pvPortMalloc( size_t xWantedSize ) {
mtCOVERAGE_TEST_MARKER();
}
if ( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) {
if ((xWantedSize > 0) && (xWantedSize <= xFreeBytesRemaining)) {
/* Traverse the list from the start (lowest address) block until
* one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
pxBlock = xStart.pxNextFreeBlock;
while ( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) {
while ((pxBlock->xBlockSize < xWantedSize) && (pxBlock->pxNextFreeBlock != NULL)) {
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the end marker was reached then a block of adequate size
* was not found. */
if ( pxBlock != pxEnd ) {
if (pxBlock != pxEnd) {
/* Return the memory space pointed to - jumping over the
* BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
pvReturn = (void *)(((uint8_t *)pxPreviousBlock->pxNextFreeBlock) + xHeapStructSize);
/* This block is being returned for use so must be taken out
* of the list of free blocks. */
@@ -186,12 +186,12 @@ void *pvPortMalloc( size_t xWantedSize ) {
/* If the block is larger than required it can be split into
* two. */
if ( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) {
if ((pxBlock->xBlockSize - xWantedSize) > heapMINIMUM_BLOCK_SIZE) {
/* This block is to be split into two. Create a new
* block following the number of bytes requested. The void
* cast is used to prevent byte alignment warnings from the
* compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
pxNewBlockLink = (void *)(((uint8_t *)pxBlock) + xWantedSize);
/* Calculate the sizes of two blocks split from the
* single block. */
@@ -199,14 +199,14 @@ void *pvPortMalloc( size_t xWantedSize ) {
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
prvInsertBlockIntoFreeList((pxNewBlockLink));
} else {
mtCOVERAGE_TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if ( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) {
if (xFreeBytesRemaining < xMinimumEverFreeBytesRemaining) {
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
} else {
mtCOVERAGE_TEST_MARKER();
@@ -227,14 +227,14 @@ void *pvPortMalloc( size_t xWantedSize ) {
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize );
traceMALLOC(pvReturn, xWantedSize);
}
( void ) xTaskResumeAll();
(void)xTaskResumeAll();
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
#if (configUSE_MALLOC_FAILED_HOOK == 1)
{
if ( pvReturn == NULL ) {
extern void vApplicationMallocFailedHook( void );
if (pvReturn == NULL) {
extern void vApplicationMallocFailedHook(void);
vApplicationMallocFailedHook();
} else {
mtCOVERAGE_TEST_MARKER();
@@ -246,24 +246,24 @@ void *pvPortMalloc( size_t xWantedSize ) {
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv ) {
uint8_t *puc = ( uint8_t * ) pv;
void vPortFree(void *pv) {
uint8_t *puc = (uint8_t *)pv;
BlockLink_t *pxLink;
if ( pv != NULL ) {
if (pv != NULL) {
/* The memory being freed will have an BlockLink_t structure immediately
* before it. */
puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
pxLink = (void *)puc;
/* Check the block is actually allocated. */
configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
configASSERT( pxLink->pxNextFreeBlock == NULL );
configASSERT((pxLink->xBlockSize & xBlockAllocatedBit) != 0);
configASSERT(pxLink->pxNextFreeBlock == NULL);
if ( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) {
if ( pxLink->pxNextFreeBlock == NULL ) {
if ((pxLink->xBlockSize & xBlockAllocatedBit) != 0) {
if (pxLink->pxNextFreeBlock == NULL) {
/* The block is being returned to the heap - it is no longer
* allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
@@ -272,11 +272,11 @@ void vPortFree( void *pv ) {
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
traceFREE(pv, pxLink->xBlockSize);
prvInsertBlockIntoFreeList(((BlockLink_t *)pxLink));
xNumberOfSuccessfulFrees++;
}
( void ) xTaskResumeAll();
(void)xTaskResumeAll();
} else {
mtCOVERAGE_TEST_MARKER();
}
@@ -287,27 +287,27 @@ void vPortFree( void *pv ) {
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void ) { return xFreeBytesRemaining; }
size_t xPortGetFreeHeapSize(void) { return xFreeBytesRemaining; }
/*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void ) { return xMinimumEverFreeBytesRemaining; }
size_t xPortGetMinimumEverFreeHeapSize(void) { return xMinimumEverFreeBytesRemaining; }
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) {
static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert) {
BlockLink_t *pxIterator;
uint8_t *puc;
/* Iterate through the list until a block is found that has a higher address
* than the block being inserted. */
for ( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) {
for (pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock) {
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator;
puc = (uint8_t *)pxIterator;
if ( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) {
if ((puc + pxIterator->xBlockSize) == (uint8_t *)pxBlockToInsert) {
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
} else {
@@ -316,10 +316,10 @@ static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) {
/* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
puc = (uint8_t *)pxBlockToInsert;
if ( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) {
if ( pxIterator->pxNextFreeBlock != pxEnd ) {
if ((puc + pxBlockToInsert->xBlockSize) == (uint8_t *)pxIterator->pxNextFreeBlock) {
if (pxIterator->pxNextFreeBlock != pxEnd) {
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
@@ -334,7 +334,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) {
* before and the block after, then it's pxNextFreeBlock pointer will have
* already been set, and should not be set here as that would make it point
* to itself. */
if ( pxIterator != pxBlockToInsert ) {
if (pxIterator != pxBlockToInsert) {
pxIterator->pxNextFreeBlock = pxBlockToInsert;
} else {
mtCOVERAGE_TEST_MARKER();
@@ -342,7 +342,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) {
}
/*-----------------------------------------------------------*/
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) {
void vPortDefineHeapRegions(const HeapRegion_t *const pxHeapRegions) {
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
size_t xAlignedHeap;
size_t xTotalRegionSize, xTotalHeapSize = 0;
@@ -351,39 +351,39 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) {
const HeapRegion_t *pxHeapRegion;
/* Can only call once! */
configASSERT( pxEnd == NULL );
configASSERT(pxEnd == NULL);
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
pxHeapRegion = &(pxHeapRegions[xDefinedRegions]);
while ( pxHeapRegion->xSizeInBytes > 0 ) {
while (pxHeapRegion->xSizeInBytes > 0) {
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
/* Ensure the heap region starts on a correctly aligned boundary. */
xAddress = ( size_t ) pxHeapRegion->pucStartAddress;
xAddress = (size_t)pxHeapRegion->pucStartAddress;
if ( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) {
xAddress += ( portBYTE_ALIGNMENT - 1 );
if ((xAddress & portBYTE_ALIGNMENT_MASK) != 0) {
xAddress += (portBYTE_ALIGNMENT - 1);
xAddress &= ~portBYTE_ALIGNMENT_MASK;
/* Adjust the size for the bytes lost to alignment. */
xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress;
xTotalRegionSize -= xAddress - (size_t)pxHeapRegion->pucStartAddress;
}
xAlignedHeap = xAddress;
/* Set xStart if it has not already been set. */
if ( xDefinedRegions == 0 ) {
if (xDefinedRegions == 0) {
/* xStart is used to hold a pointer to the first item in the list of
* free blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
xStart.pxNextFreeBlock = (BlockLink_t *)xAlignedHeap;
xStart.xBlockSize = (size_t)0;
} else {
/* Should only get here if one region has already been added to the
* heap. */
configASSERT( pxEnd != NULL );
configASSERT(pxEnd != NULL);
/* Check blocks are passed in with increasing start addresses. */
configASSERT( xAddress > ( size_t ) pxEnd );
configASSERT(xAddress > (size_t)pxEnd);
}
/* Remember the location of the end marker in the previous region, if
@@ -392,24 +392,24 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) {
/* pxEnd is used to mark the end of the list of free blocks and is
* inserted at the end of the region space. */
xAddress = xAlignedHeap + xTotalRegionSize;
xAddress = xAlignedHeap + xTotalRegionSize;
xAddress -= xHeapStructSize;
xAddress &= ~portBYTE_ALIGNMENT_MASK;
pxEnd = ( BlockLink_t * ) xAddress;
pxEnd = (BlockLink_t *)xAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block in this region that is
* sized to take up the entire heap region minus the space taken by the
* free block structure. */
pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion = (BlockLink_t *)xAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = xAddress - (size_t)pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
/* If this is not the first region that makes up the entire heap space
* then link the previous region to this region. */
if ( pxPreviousFreeBlock != NULL ) {
if (pxPreviousFreeBlock != NULL) {
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
}
@@ -417,21 +417,21 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) {
/* Move onto the next HeapRegion_t structure. */
xDefinedRegions++;
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
pxHeapRegion = &(pxHeapRegions[xDefinedRegions]);
}
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
xFreeBytesRemaining = xTotalHeapSize;
/* Check something was actually defined before it is accessed. */
configASSERT( xTotalHeapSize );
configASSERT(xTotalHeapSize);
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
xBlockAllocatedBit = ((size_t)1) << ((sizeof(size_t) * heapBITS_PER_BYTE) - 1);
}
/*-----------------------------------------------------------*/
void vPortGetHeapStats( HeapStats_t *pxHeapStats ) {
void vPortGetHeapStats(HeapStats_t *pxHeapStats) {
BlockLink_t *pxBlock;
size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
@@ -441,21 +441,21 @@ void vPortGetHeapStats( HeapStats_t *pxHeapStats ) {
/* pxBlock will be NULL if the heap has not been initialised. The heap
* is initialised automatically when the first allocation is made. */
if ( pxBlock != NULL ) {
if (pxBlock != NULL) {
do {
/* Increment the number of blocks and record the largest block seen
* so far. */
xBlocks++;
if ( pxBlock->xBlockSize > xMaxSize ) {
xMaxSize = pxBlock->xBlockSize;
if (pxBlock->xBlockSize > xMaxSize) {
xMaxSize = pxBlock->xBlockSize;
}
/* Heap five will have a zero sized block at the end of each
* each region - the block is only used to link to the next
* heap region so it not a real block. */
if ( pxBlock->xBlockSize != 0 ) {
if ( pxBlock->xBlockSize < xMinSize ) {
if (pxBlock->xBlockSize != 0) {
if (pxBlock->xBlockSize < xMinSize) {
xMinSize = pxBlock->xBlockSize;
}
}
@@ -463,10 +463,10 @@ void vPortGetHeapStats( HeapStats_t *pxHeapStats ) {
/* Move to the next block in the chain until the last block is
* reached. */
pxBlock = pxBlock->pxNextFreeBlock;
} while ( pxBlock != pxEnd );
} while (pxBlock != pxEnd);
}
}
( void ) xTaskResumeAll();
(void)xTaskResumeAll();
pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;

View File

@@ -23,8 +23,8 @@ extern uint8_t _heap_start;
extern uint8_t _heap_size; // @suppress("Type cannot be resolved")
static HeapRegion_t xHeapRegions[] = {
{&_heap_start, (unsigned int)&_heap_size},
{NULL, 0}, /* Terminates the array. */
{NULL, 0} /* Terminates the array. */
{ NULL, 0}, /* Terminates the array. */
{ NULL, 0} /* Terminates the array. */
};
// Functions
@@ -86,8 +86,8 @@ void setup_pwm(void) {
PWM_Channel_Disable(PWM_Channel);
}
const ADC_Chan_Type adc_tip_pos_chans[]
= {TIP_TEMP_ADC_CHANNEL, TMP36_ADC_CHANNEL, TIP_TEMP_ADC_CHANNEL, VIN_ADC_CHANNEL, TIP_TEMP_ADC_CHANNEL, TMP36_ADC_CHANNEL, TIP_TEMP_ADC_CHANNEL, VIN_ADC_CHANNEL};
const ADC_Chan_Type adc_tip_pos_chans[] = {TIP_TEMP_ADC_CHANNEL, TMP36_ADC_CHANNEL, TIP_TEMP_ADC_CHANNEL, VIN_ADC_CHANNEL,
TIP_TEMP_ADC_CHANNEL, TMP36_ADC_CHANNEL, TIP_TEMP_ADC_CHANNEL, VIN_ADC_CHANNEL};
const ADC_Chan_Type adc_tip_neg_chans[] = {ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND};
static_assert(sizeof(adc_tip_pos_chans) == sizeof(adc_tip_neg_chans));

View File

@@ -36,7 +36,8 @@ static uint8_t uart_dbg_disable = 0;
struct heap_info mmheap_root;
static struct heap_region system_mmheap[] = {
{NULL, 0}, {NULL, 0}, /* Terminates the array. */
{NULL, 0},
{NULL, 0}, /* Terminates the array. */
};
__WEAK__ void board_init(void) {}

View File

@@ -203,7 +203,8 @@ void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) { return NULL; }
/* for exit() and abort() */
void __attribute__((noreturn)) _exit(int status) {
while (1) {}
while (1) {
}
}
void _system(const char *s) {}

View File

@@ -1,194 +0,0 @@
/**
* @file uart_interface.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* 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 "bflb_platform.h"
#include "hal_gpio.h"
#include "uart_interface.h"
#include "hal_usb.h"
#include "hal_dma.h"
#define USB_OUT_RINGBUFFER_SIZE (8 * 1024)
#define UART_RX_RINGBUFFER_SIZE (8 * 1024)
#define UART_TX_DMA_SIZE (4095)
uint8_t usb_rx_mem[USB_OUT_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t uart_rx_mem[UART_RX_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t src_buffer[UART_TX_DMA_SIZE] __attribute__((section(".tcm_code")));
struct device *uart1;
struct device *dma_ch2;
Ring_Buffer_Type usb_rx_rb;
Ring_Buffer_Type uart1_rx_rb;
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (state == UART_EVENT_RX_FIFO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RF OV\r\n");
}
} else if (state == UART_EVENT_RTO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RTO OV\r\n");
}
} else if (state == UART_RX_FER_IT) {
MSG("RX ERR\r\n");
}
}
void uart1_init(void)
{
#ifdef UART1_INDEX
uart_register(UART1_INDEX, "uart1");
uart1 = device_find("uart1");
if (uart1) {
// device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
// device_set_callback(uart1, uart_irq_callback);
// device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
}
dma_register(DMA0_CH2_INDEX, "ch2");
dma_ch2 = device_find("ch2");
if (dma_ch2) {
DMA_DEV(dma_ch2)->direction = DMA_MEMORY_TO_PERIPH;
DMA_DEV(dma_ch2)->transfer_mode = DMA_LLI_ONCE_MODE;
DMA_DEV(dma_ch2)->src_req = DMA_REQUEST_NONE;
DMA_DEV(dma_ch2)->dst_req = DMA_REQUEST_UART1_TX;
DMA_DEV(dma_ch2)->src_addr_inc = DMA_ADDR_INCREMENT_ENABLE;
DMA_DEV(dma_ch2)->dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE;
DMA_DEV(dma_ch2)->src_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch2)->dst_burst_size = DMA_BURST_1BYTE;
DMA_DEV(dma_ch2)->src_width = DMA_TRANSFER_WIDTH_8BIT;
DMA_DEV(dma_ch2)->dst_width = DMA_TRANSFER_WIDTH_8BIT;
device_open(dma_ch2, 0);
}
#endif
}
void uart1_config(uint32_t baudrate, uart_databits_t databits, uart_parity_t parity, uart_stopbits_t stopbits)
{
device_close(uart1);
UART_DEV(uart1)->baudrate = baudrate;
UART_DEV(uart1)->stopbits = stopbits;
UART_DEV(uart1)->parity = parity;
UART_DEV(uart1)->databits = (databits - 5);
device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart1, uart_irq_callback);
device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
Ring_Buffer_Reset(&usb_rx_rb);
Ring_Buffer_Reset(&uart1_rx_rb);
}
static uint8_t uart1_dtr;
static uint8_t uart1_rts;
void uart1_set_dtr_rts(uint8_t dtr, uint8_t rts)
{
uart1_dtr = dtr;
uart1_rts = rts;
}
void uart1_dtr_init(void)
{
gpio_set_mode(uart1_dtr, GPIO_OUTPUT_MODE);
}
void uart1_rts_init(void)
{
gpio_set_mode(uart1_rts, GPIO_OUTPUT_MODE);
}
void uart1_dtr_deinit(void)
{
gpio_set_mode(uart1_dtr, GPIO_INPUT_MODE);
}
void uart1_rts_deinit(void)
{
gpio_set_mode(uart1_rts, GPIO_INPUT_MODE);
}
void dtr_pin_set(uint8_t status)
{
gpio_write(uart1_dtr, status);
}
void rts_pin_set(uint8_t status)
{
gpio_write(uart1_rts, status);
}
void ringbuffer_lock()
{
cpu_global_irq_disable();
}
void ringbuffer_unlock()
{
cpu_global_irq_enable();
}
void uart_ringbuffer_init(void)
{
/* init mem for ring_buffer */
memset(usb_rx_mem, 0, USB_OUT_RINGBUFFER_SIZE);
memset(uart_rx_mem, 0, UART_RX_RINGBUFFER_SIZE);
/* init ring_buffer */
Ring_Buffer_Init(&usb_rx_rb, usb_rx_mem, USB_OUT_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
Ring_Buffer_Init(&uart1_rx_rb, uart_rx_mem, UART_RX_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
}
static dma_control_data_t uart_dma_ctrl_cfg = {
.bits.fix_cnt = 0,
.bits.dst_min_mode = 0,
.bits.dst_add_mode = 0,
.bits.SI = 1,
.bits.DI = 0,
.bits.SWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.DWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.SBSize = 0,
.bits.DBSize = 0,
.bits.I = 0,
.bits.TransferSize = 4095
};
static dma_lli_ctrl_t uart_lli_list = {
.src_addr = (uint32_t)src_buffer,
.dst_addr = DMA_ADDR_UART1_TDR,
.nextlli = 0
};
void uart_send_from_ringbuffer(void)
{
if (Ring_Buffer_Get_Length(&usb_rx_rb)) {
if (!dma_channel_check_busy(dma_ch2)) {
uint32_t avalibleCnt = Ring_Buffer_Read(&usb_rx_rb, src_buffer, UART_TX_DMA_SIZE);
if (avalibleCnt) {
dma_channel_stop(dma_ch2);
uart_dma_ctrl_cfg.bits.TransferSize = avalibleCnt;
memcpy(&uart_lli_list.cfg, &uart_dma_ctrl_cfg, sizeof(dma_control_data_t));
dma_channel_update(dma_ch2, (void *)((uint32_t)&uart_lli_list));
dma_channel_start(dma_ch2);
}
}
}
}

View File

@@ -1,44 +0,0 @@
/**
* @file uart_interface.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* 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 __UART_IF_H__
#define __UART_IF_H__
#include "hal_uart.h"
#include "ring_buffer.h"
extern Ring_Buffer_Type usb_rx_rb;
extern Ring_Buffer_Type uart1_rx_rb;
void uart1_init(void);
void uart1_config(uint32_t baudrate, uart_databits_t databits, uart_parity_t parity, uart_stopbits_t stopbits);
void uart1_set_dtr_rts(uint8_t dtr, uint8_t rts);
void uart1_dtr_init(void);
void uart1_rts_init(void);
void uart1_dtr_deinit(void);
void uart1_rts_deinit(void);
void dtr_pin_set(uint8_t status);
void rts_pin_set(uint8_t status);
void uart_ringbuffer_init(void);
void uart_send_from_ringbuffer(void);
#endif

View File

@@ -1,82 +0,0 @@
/**
* @file usb_dc.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* 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 "hal_usb.h"
#include "stdbool.h"
#include "usbd_core.h"
struct device *usb;
#ifdef USB_INDEX
static void usb_dc_event_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
usbd_event_notify_handler(state, args);
}
#endif
struct device *usb_dc_init(void)
{
#ifdef USB_INDEX
usb_dc_register(USB_INDEX, "usb");
usb = device_find("usb");
device_set_callback(usb, usb_dc_event_callback);
device_open(usb, 0);
return usb;
#endif
return NULL;
}
int usbd_set_address(const uint8_t addr)
{
return usb_dc_set_dev_address(addr);
}
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
{
return usb_dc_ep_open(usb, (const struct usb_dc_ep_cfg *)ep_cfg);
}
int usbd_ep_close(const uint8_t ep)
{
return usb_dc_ep_close(ep);
}
int usbd_ep_set_stall(const uint8_t ep)
{
return usb_dc_ep_set_stall(ep);
}
int usbd_ep_clear_stall(const uint8_t ep)
{
return usb_dc_ep_clear_stall(ep);
}
int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
{
return usb_dc_ep_is_stalled(usb, ep, stalled);
}
int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
{
return usb_dc_ep_write(usb, ep, data, data_len, ret_bytes);
}
int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
{
return usb_dc_ep_read(usb, ep, data, max_data_len, read_bytes);
}

View File

@@ -23,28 +23,27 @@
#include "arm_dsp_wrapper.h"
void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize)
{
uint32_t blkCnt = blockSize >> 2u;
void arm_fill_f32(float32_t value, float32_t *pDst, uint32_t blockSize) {
uint32_t blkCnt = blockSize >> 2u;
float32_t in1 = value;
float32_t in2 = value;
float32_t in3 = value;
float32_t in4 = value;
float32_t in1 = value;
float32_t in2 = value;
float32_t in3 = value;
float32_t in4 = value;
while (blkCnt > 0u) {
*pDst++ = in1;
*pDst++ = in2;
*pDst++ = in3;
*pDst++ = in4;
while (blkCnt > 0u) {
*pDst++ = in1;
*pDst++ = in2;
*pDst++ = in3;
*pDst++ = in4;
blkCnt--;
}
blkCnt--;
}
blkCnt = blockSize % 0x4u;
blkCnt = blockSize % 0x4u;
while (blkCnt > 0u) {
*pDst++ = value;
blkCnt--;
}
while (blkCnt > 0u) {
*pDst++ = value;
blkCnt--;
}
}

View File

@@ -38,10 +38,7 @@ dlist_t device_head = DLIST_OBJECT_INIT(device_head);
*
* @return device header
*/
dlist_t *device_get_list_header(void)
{
return &device_head;
}
dlist_t *device_get_list_header(void) { return &device_head; }
/**
* This function registers a device driver with specified name.
@@ -52,25 +49,23 @@ dlist_t *device_get_list_header(void)
*
* @return the error code, DEVICE_EOK on initialization successfully.
*/
int device_register(struct device *dev, const char *name)
{
dlist_t *node;
int device_register(struct device *dev, const char *name) {
dlist_t *node;
dlist_for_each(node, &device_head)
{
struct device *dev_obj;
dev_obj = dlist_entry(node, struct device, list);
dlist_for_each(node, &device_head) {
struct device *dev_obj;
dev_obj = dlist_entry(node, struct device, list);
if (dev_obj == dev) {
return -DEVICE_EEXIST;
}
if (dev_obj == dev) {
return -DEVICE_EEXIST;
}
}
strcpy(dev->name, name);
strcpy(dev->name, name);
dlist_insert_after(&device_head, &(dev->list));
dev->status = DEVICE_REGISTERED;
return DEVICE_EOK;
dlist_insert_after(&device_head, &(dev->list));
dev->status = DEVICE_REGISTERED;
return DEVICE_EOK;
}
/**
@@ -82,17 +77,16 @@ int device_register(struct device *dev, const char *name)
*
* @return the error code, DEVICE_EOK on initialization successfully.
*/
int device_unregister(const char *name)
{
struct device *dev = device_find(name);
int device_unregister(const char *name) {
struct device *dev = device_find(name);
if (!dev) {
return -DEVICE_ENODEV;
}
dev->status = DEVICE_UNREGISTER;
/* remove from old list */
dlist_remove(&(dev->list));
return DEVICE_EOK;
if (!dev) {
return -DEVICE_ENODEV;
}
dev->status = DEVICE_UNREGISTER;
/* remove from old list */
dlist_remove(&(dev->list));
return DEVICE_EOK;
}
/**
@@ -102,20 +96,18 @@ int device_unregister(const char *name)
*
* @return the registered device driver on successful, or NULL on failure.
*/
struct device *device_find(const char *name)
{
struct device *dev;
dlist_t *node;
struct device *device_find(const char *name) {
struct device *dev;
dlist_t *node;
dlist_for_each(node, &device_head)
{
dev = dlist_entry(node, struct device, list);
dlist_for_each(node, &device_head) {
dev = dlist_entry(node, struct device, list);
if (strncmp(dev->name, name, DEVICE_NAME_MAX) == 0) {
return dev;
}
if (strncmp(dev->name, name, DEVICE_NAME_MAX) == 0) {
return dev;
}
return NULL;
}
return NULL;
}
/**
@@ -126,26 +118,25 @@ struct device *device_find(const char *name)
*
* @return the result
*/
int device_open(struct device *dev, uint16_t oflag)
{
int device_open(struct device *dev, uint16_t oflag) {
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
int retval = DEVICE_EOK;
if ((dev->status == DEVICE_REGISTERED) || (dev->status == DEVICE_CLOSED)) {
if (dev_open != NULL) {
retval = dev_open(dev, oflag);
dev->status = DEVICE_OPENED;
dev->oflag |= oflag;
} else {
retval = -DEVICE_EFAULT;
}
if ((dev->status == DEVICE_REGISTERED) || (dev->status == DEVICE_CLOSED)) {
if (dev_open != NULL) {
retval = dev_open(dev, oflag);
dev->status = DEVICE_OPENED;
dev->oflag |= oflag;
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
#else
return dev_open(dev, oflag);
return dev_open(dev, oflag);
#endif
}
/**
@@ -155,26 +146,25 @@ int device_open(struct device *dev, uint16_t oflag)
*
* @return the result
*/
int device_close(struct device *dev)
{
int device_close(struct device *dev) {
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_close != NULL) {
retval = dev_close(dev);
dev->status = DEVICE_CLOSED;
dev->oflag = 0;
} else {
retval = -DEVICE_EFAULT;
}
if (dev->status == DEVICE_OPENED) {
if (dev_close != NULL) {
retval = dev_close(dev);
dev->status = DEVICE_CLOSED;
dev->oflag = 0;
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
#else
return dev_close(dev);
return dev_close(dev);
#endif
}
/**
@@ -186,24 +176,23 @@ int device_close(struct device *dev)
*
* @return the result
*/
int device_control(struct device *dev, int cmd, void *args)
{
int device_control(struct device *dev, int cmd, void *args) {
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
int retval = DEVICE_EOK;
if (dev->status > DEVICE_UNREGISTER) {
if (dev_control != NULL) {
retval = dev_control(dev, cmd, args);
} else {
retval = -DEVICE_EFAULT;
}
if (dev->status > DEVICE_UNREGISTER) {
if (dev_control != NULL) {
retval = dev_control(dev, cmd, args);
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
#else
return dev_control(dev, cmd, args);
return dev_control(dev, cmd, args);
#endif
}
/**
@@ -216,24 +205,23 @@ int device_control(struct device *dev, int cmd, void *args)
*
* @return the actually written size on successful, otherwise negative returned.
*/
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size)
{
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size) {
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_write != NULL) {
retval = dev_write(dev, pos, buffer, size);
} else {
retval = -DEVICE_EFAULT;
}
if (dev->status == DEVICE_OPENED) {
if (dev_write != NULL) {
retval = dev_write(dev, pos, buffer, size);
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
#else
return dev_write(dev, pos, buffer, size);
return dev_write(dev, pos, buffer, size);
#endif
}
/**
@@ -246,24 +234,23 @@ int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t
*
* @return the actually read size on successful, otherwise negative returned.
*/
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
{
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) {
#ifdef DEVICE_CHECK_PARAM
int retval = DEVICE_EOK;
int retval = DEVICE_EOK;
if (dev->status == DEVICE_OPENED) {
if (dev_read != NULL) {
retval = dev_read(dev, pos, buffer, size);
} else {
retval = -DEVICE_EFAULT;
}
if (dev->status == DEVICE_OPENED) {
if (dev_read != NULL) {
retval = dev_read(dev, pos, buffer, size);
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
#else
return dev_read(dev, pos, buffer, size);
return dev_read(dev, pos, buffer, size);
#endif
}
/**
@@ -276,19 +263,18 @@ int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
*
* @return the actually read size on successful, otherwise negative returned.
*/
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event))
{
int retval = DEVICE_EOK;
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event)) {
int retval = DEVICE_EOK;
if (dev->status > DEVICE_UNREGISTER) {
if (callback != NULL) {
dev->callback = callback;
} else {
retval = -DEVICE_EFAULT;
}
if (dev->status > DEVICE_UNREGISTER) {
if (callback != NULL) {
dev->callback = callback;
} else {
retval = -DEVICE_EINVAL;
retval = -DEVICE_EFAULT;
}
} else {
retval = -DEVICE_EINVAL;
}
return retval;
return retval;
}

View File

@@ -24,208 +24,199 @@
#ifndef BFLB_USE_ROM_DRIVER
/****************************************************************************/ /**
* @brief Char memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy(void *dst, const void *src, uint32_t n)
{
const uint8_t *p = src;
uint8_t *q = dst;
* @brief Char memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy(void *dst, const void *src, uint32_t n) {
const uint8_t *p = src;
uint8_t *q = dst;
while (n--) {
*q++ = *p++;
}
while (n--) {
*q++ = *p++;
}
return dst;
return dst;
}
/****************************************************************************/ /**
* @brief Word memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memcpy4(uint32_t *dst, const uint32_t *src, uint32_t n)
{
const uint32_t *p = src;
uint32_t *q = dst;
* @brief Word memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memcpy4(uint32_t *dst, const uint32_t *src, uint32_t n) {
const uint32_t *p = src;
uint32_t *q = dst;
while (n--) {
*q++ = *p++;
}
while (n--) {
*q++ = *p++;
}
return dst;
return dst;
}
/****************************************************************************/ /**
* @brief Fast memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of bytes
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy_fast(void *pdst, const void *psrc, uint32_t n)
{
uint32_t left, done, i = 0;
uint8_t *dst = (uint8_t *)pdst;
uint8_t *src = (uint8_t *)psrc;
* @brief Fast memcpy
*
* @param dst: Destination
* @param src: Source
* @param n: Count of bytes
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memcpy_fast(void *pdst, const void *psrc, uint32_t n) {
uint32_t left, done, i = 0;
uint8_t *dst = (uint8_t *)pdst;
uint8_t *src = (uint8_t *)psrc;
if (((uint32_t)(uintptr_t)dst & 0x3) == 0 && ((uint32_t)(uintptr_t)src & 0x3) == 0) {
arch_memcpy4((uint32_t *)dst, (const uint32_t *)src, n >> 2);
left = n % 4;
done = n - left;
if (((uint32_t)(uintptr_t)dst & 0x3) == 0 && ((uint32_t)(uintptr_t)src & 0x3) == 0) {
arch_memcpy4((uint32_t *)dst, (const uint32_t *)src, n >> 2);
left = n % 4;
done = n - left;
while (i < left) {
dst[done + i] = src[done + i];
i++;
}
} else {
arch_memcpy(dst, src, n);
while (i < left) {
dst[done + i] = src[done + i];
i++;
}
} else {
arch_memcpy(dst, src, n);
}
return dst;
return dst;
}
/****************************************************************************/ /**
* @brief char memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memset(void *s, uint8_t c, uint32_t n)
{
uint8_t *p = (uint8_t *)s;
* @brief char memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of char
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ void *ATTR_TCM_SECTION arch_memset(void *s, uint8_t c, uint32_t n) {
uint8_t *p = (uint8_t *)s;
while (n > 0) {
*p++ = (uint8_t)c;
--n;
}
while (n > 0) {
*p++ = (uint8_t)c;
--n;
}
return s;
return s;
}
/****************************************************************************/ /**
* @brief Word memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memset4(uint32_t *dst, const uint32_t val, uint32_t n)
{
uint32_t *q = dst;
* @brief Word memset
*
* @param dst: Destination
* @param val: Value to set
* @param n: Count of words
*
* @return Destination pointer
*
*******************************************************************************/
__WEAK__ uint32_t *ATTR_TCM_SECTION arch_memset4(uint32_t *dst, const uint32_t val, uint32_t n) {
uint32_t *q = dst;
while (n--) {
*q++ = val;
}
while (n--) {
*q++ = val;
}
return dst;
return dst;
}
/****************************************************************************/ /**
* @brief string compare
*
* @param s1: string 1
* @param s2: string 2
* @param n: Count of chars
*
* @return compare result
*
*******************************************************************************/
__WEAK__ int ATTR_TCM_SECTION arch_memcmp(const void *s1, const void *s2, uint32_t n)
{
const unsigned char *c1 = s1, *c2 = s2;
int d = 0;
* @brief string compare
*
* @param s1: string 1
* @param s2: string 2
* @param n: Count of chars
*
* @return compare result
*
*******************************************************************************/
__WEAK__ int ATTR_TCM_SECTION arch_memcmp(const void *s1, const void *s2, uint32_t n) {
const unsigned char *c1 = s1, *c2 = s2;
int d = 0;
while (n--) {
d = (int)*c1++ - (int)*c2++;
while (n--) {
d = (int)*c1++ - (int)*c2++;
if (d) {
break;
}
if (d) {
break;
}
}
return d;
return d;
}
#endif
void memcopy_to_fifo(void *fifo_addr, uint8_t *data, uint32_t length)
{
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
void memcopy_to_fifo(void *fifo_addr, uint8_t *data, uint32_t length) {
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
while (length--) {
*p = *q++;
}
while (length--) {
*p = *q++;
}
}
void fifocopy_to_mem(void *fifo_addr, uint8_t *data, uint32_t length)
{
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
void fifocopy_to_mem(void *fifo_addr, uint8_t *data, uint32_t length) {
uint8_t *p = (uint8_t *)fifo_addr;
uint8_t *q = data;
while (length--) {
*q++ = *p;
}
while (length--) {
*q++ = *p;
}
}
/****************************************************************************/ /**
* @brief get u64 first number 1 from right to left
*
* @param val: target value
* @param bit: first 1 in bit
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
int arch_ffsll(uint64_t *val, uint32_t *bit)
{
if (!*val) {
return ERROR;
}
* @brief get u64 first number 1 from right to left
*
* @param val: target value
* @param bit: first 1 in bit
*
* @return SUCCESS or ERROR
*
*******************************************************************************/
int arch_ffsll(uint64_t *val, uint32_t *bit) {
if (!*val) {
return ERROR;
}
*bit = __builtin_ffsll(*val) - 1;
*val &= ~((1ULL) << (*bit));
return 0;
*bit = __builtin_ffsll(*val) - 1;
*val &= ~((1ULL) << (*bit));
return 0;
}
int arch_ctzll(uint64_t *val, uint32_t *bit)
{
if (!*val)
return -1;
int arch_ctzll(uint64_t *val, uint32_t *bit) {
if (!*val) {
return -1;
}
*bit = __builtin_ctzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
*bit = __builtin_ctzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
}
int arch_clzll(uint64_t *val, uint32_t *bit)
{
if (!*val)
return -1;
int arch_clzll(uint64_t *val, uint32_t *bit) {
if (!*val) {
return -1;
}
*bit = __builtin_clzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
*bit = __builtin_clzll(*val);
*val &= ~((1ULL) << (*bit));
return 0;
}
#ifdef DEBUG
@@ -238,11 +229,10 @@ int arch_clzll(uint64_t *val, uint32_t *bit)
* @return None
*******************************************************************************/
void check_failed(uint8_t *file, uint32_t line)
{
/* Infinite loop */
while (1)
;
void check_failed(uint8_t *file, uint32_t line) {
/* Infinite loop */
while (1) {
}
}
#endif /* DEBUG */

View File

@@ -1,42 +1,42 @@
/**
******************************************************************************
* @file partition.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
******************************************************************************
* @file partition.c
* @version V1.0
* @date
* @brief This file is the standard driver c file
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
#include "partition.h"
#include "softcrc.h"
#include "bflb_platform.h"
#include "softcrc.h"
/** @addtogroup BFLB_Common_Driver
* @{
@@ -61,9 +61,9 @@
/** @defgroup PARTITION_Private_Variables
* @{
*/
p_pt_table_flash_erase gp_pt_table_flash_erase = NULL;
p_pt_table_flash_write gp_pt_table_flash_write = NULL;
p_pt_table_flash_read gp_pt_table_flash_read = NULL;
p_pt_table_flash_erase gp_pt_table_flash_erase = NULL;
p_pt_table_flash_write gp_pt_table_flash_write = NULL;
p_pt_table_flash_read gp_pt_table_flash_read = NULL;
pt_table_iap_param_type p_iap_param;
/*@} end of group PARTITION_Private_Variables */
@@ -86,44 +86,42 @@ extern int main(void);
*/
/****************************************************************************/ /**
* @brief Judge partition table valid
*
* @param ptStuff: Partition table stuff pointer
*
* @return 0 for invalid and 1 for valid
*
*******************************************************************************/
static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff)
{
pt_table_config *pt_table = &pt_stuff->pt_table;
pt_table_entry_config *pt_entries = pt_stuff->pt_entries;
uint32_t *p_crc32;
uint32_t entriesLen = sizeof(pt_table_entry_config) * pt_table->entryCnt;
* @brief Judge partition table valid
*
* @param ptStuff: Partition table stuff pointer
*
* @return 0 for invalid and 1 for valid
*
*******************************************************************************/
static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff) {
pt_table_config *pt_table = &pt_stuff->pt_table;
pt_table_entry_config *pt_entries = pt_stuff->pt_entries;
uint32_t *p_crc32;
uint32_t entriesLen = sizeof(pt_table_entry_config) * pt_table->entryCnt;
if (pt_table->magicCode == BFLB_PT_MAGIC_CODE) {
if (pt_table->entryCnt > PT_ENTRY_MAX) {
MSG("PT Entry Count Error\r\n");
return 0;
}
if (pt_table->crc32 !=
BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4)) {
MSG("PT CRC Error\r\n");
return 0;
}
/* ToDo it is a trap here, when entryCnt > 8, crc32 will overflow, comment by zhangcheng */
p_crc32 = (uint32_t *)((uintptr_t)pt_entries + entriesLen);
if (*p_crc32 != BFLB_Soft_CRC32((uint8_t *)pt_entries, entriesLen)) {
MSG("PT Entry CRC Error\r\n");
return 0;
}
return 1;
if (pt_table->magicCode == BFLB_PT_MAGIC_CODE) {
if (pt_table->entryCnt > PT_ENTRY_MAX) {
MSG("PT Entry Count Error\r\n");
return 0;
}
return 0;
if (pt_table->crc32 != BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4)) {
MSG("PT CRC Error\r\n");
return 0;
}
/* ToDo it is a trap here, when entryCnt > 8, crc32 will overflow, comment by zhangcheng */
p_crc32 = (uint32_t *)((uintptr_t)pt_entries + entriesLen);
if (*p_crc32 != BFLB_Soft_CRC32((uint8_t *)pt_entries, entriesLen)) {
MSG("PT Entry CRC Error\r\n");
return 0;
}
return 1;
}
return 0;
}
/*@} end of group PARTITION_Private_Functions */
@@ -133,408 +131,392 @@ static uint8_t pt_table_valid(pt_table_stuff_config *pt_stuff)
*/
/****************************************************************************/ /**
* @brief Register partition flash read write erase fucntion
*
* @param erase: Flash erase function
* @param write: Flash write function
* @param read: Flash read function
*
* @return None
*
*******************************************************************************/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read)
{
gp_pt_table_flash_erase = erase;
gp_pt_table_flash_write = write;
gp_pt_table_flash_read = read;
* @brief Register partition flash read write erase fucntion
*
* @param erase: Flash erase function
* @param write: Flash write function
* @param read: Flash read function
*
* @return None
*
*******************************************************************************/
void pt_table_set_flash_operation(p_pt_table_flash_erase erase, p_pt_table_flash_write write, p_pt_table_flash_read read) {
gp_pt_table_flash_erase = erase;
gp_pt_table_flash_write = write;
gp_pt_table_flash_read = read;
}
/****************************************************************************/ /**
* @brief Get active partition table whole stuff
*
* @param ptStuff[2]: Partition table stuff pointer
*
* @return Active partition table ID
*
*******************************************************************************/
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2])
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_id_type activePtID;
* @brief Get active partition table whole stuff
*
* @param ptStuff[2]: Partition table stuff pointer
*
* @return Active partition table ID
*
*******************************************************************************/
pt_table_id_type pt_table_get_active_partition_need_lock(pt_table_stuff_config ptStuff[2]) {
uint32_t pt_valid[2] = {0, 0};
pt_table_id_type activePtID;
if (ptStuff == NULL) {
return PT_TABLE_ID_INVALID;
}
if (ptStuff == NULL) {
return PT_TABLE_ID_INVALID;
}
activePtID = PT_TABLE_ID_INVALID;
activePtID = PT_TABLE_ID_INVALID;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&ptStuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&ptStuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&ptStuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&ptStuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&ptStuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&ptStuff[1]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&ptStuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&ptStuff[1]);
if (pt_valid[0] == 1 && pt_valid[1] == 1) {
if (ptStuff[0].pt_table.age >= ptStuff[1].pt_table.age) {
activePtID = PT_TABLE_ID_0;
} else {
activePtID = PT_TABLE_ID_1;
}
} else if (pt_valid[0] == 1) {
activePtID = PT_TABLE_ID_0;
} else if (pt_valid[1] == 1) {
activePtID = PT_TABLE_ID_1;
}
return activePtID;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry ID
*
* @param ptStuff: Partition table stuff pointer
* @param type: Type of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff,
pt_table_entry_type type,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (pt_stuff->pt_entries[i].type == type) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry name
*
* @param ptStuff: Partition table stuff pointer
* @param name: Name of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff,
uint8_t *name,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
uint32_t len = strlen((char *)name);
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (strlen((char *)pt_stuff->pt_entries[i].name) == len &&
memcmp((char *)pt_stuff->pt_entries[i].name, (char *)name, len) == 0) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Update partition entry
*
* @param targetTableID: Target partition table to update
* @param ptStuff: Partition table stuff pointer
* @param ptEntry: Partition entry pointer to update
*
* @return Partition update result
*
*******************************************************************************/
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id,
pt_table_stuff_config *pt_stuff,
pt_table_entry_config *pt_entry)
{
uint32_t i = 0;
BL_Err_Type ret;
uint32_t write_addr;
uint32_t entries_len;
pt_table_config *pt_table;
pt_table_entry_config *pt_entries;
uint32_t *crc32;
if (pt_entry == NULL || pt_stuff == NULL) {
return PT_ERROR_PARAMETER;
}
pt_table = &pt_stuff->pt_table;
pt_entries = pt_stuff->pt_entries;
if (target_table_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (target_table_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
if (pt_valid[0] == 1 && pt_valid[1] == 1) {
if (ptStuff[0].pt_table.age >= ptStuff[1].pt_table.age) {
activePtID = PT_TABLE_ID_0;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
activePtID = PT_TABLE_ID_1;
}
} else if (pt_valid[0] == 1) {
activePtID = PT_TABLE_ID_0;
} else if (pt_valid[1] == 1) {
activePtID = PT_TABLE_ID_1;
}
return activePtID;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry ID
*
* @param ptStuff: Partition table stuff pointer
* @param type: Type of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_id(pt_table_stuff_config *pt_stuff, pt_table_entry_type type, pt_table_entry_config *pt_entry) {
uint32_t i = 0;
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (pt_stuff->pt_entries[i].type == type) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Get partition entry according to entry name
*
* @param ptStuff: Partition table stuff pointer
* @param name: Name of partition entry
* @param ptEntry: Partition entry pointer to store read data
*
* @return PT_ERROR_SUCCESS or PT_ERROR_ENTRY_NOT_FOUND or PT_ERROR_PARAMETER
*
*******************************************************************************/
pt_table_error_type pt_table_get_active_entries_by_name(pt_table_stuff_config *pt_stuff, uint8_t *name, pt_table_entry_config *pt_entry) {
uint32_t i = 0;
uint32_t len = strlen((char *)name);
if (pt_stuff == NULL || pt_entry == NULL) {
return PT_ERROR_PARAMETER;
}
for (i = 0; i < pt_stuff->pt_table.entryCnt; i++) {
if (strlen((char *)pt_stuff->pt_entries[i].name) == len && memcmp((char *)pt_stuff->pt_entries[i].name, (char *)name, len) == 0) {
ARCH_MemCpy_Fast(pt_entry, &pt_stuff->pt_entries[i], sizeof(pt_table_entry_config));
return PT_ERROR_SUCCESS;
}
}
return PT_ERROR_ENTRY_NOT_FOUND;
}
/****************************************************************************/ /**
* @brief Update partition entry
*
* @param targetTableID: Target partition table to update
* @param ptStuff: Partition table stuff pointer
* @param ptEntry: Partition entry pointer to update
*
* @return Partition update result
*
*******************************************************************************/
pt_table_error_type pt_table_update_entry(pt_table_id_type target_table_id, pt_table_stuff_config *pt_stuff, pt_table_entry_config *pt_entry) {
uint32_t i = 0;
BL_Err_Type ret;
uint32_t write_addr;
uint32_t entries_len;
pt_table_config *pt_table;
pt_table_entry_config *pt_entries;
uint32_t *crc32;
if (pt_entry == NULL || pt_stuff == NULL) {
return PT_ERROR_PARAMETER;
}
pt_table = &pt_stuff->pt_table;
pt_entries = pt_stuff->pt_entries;
if (target_table_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (target_table_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
for (i = 0; i < pt_table->entryCnt; i++) {
if (pt_entries[i].type == pt_entry->type) {
ARCH_MemCpy_Fast(&pt_entries[i], pt_entry, sizeof(pt_table_entry_config));
break;
}
}
if (i == pt_table->entryCnt) {
/* Not found this entry ,add new one */
if (pt_table->entryCnt < PT_ENTRY_MAX) {
ARCH_MemCpy_Fast(&pt_entries[pt_table->entryCnt], pt_entry, sizeof(pt_table_entry_config));
pt_table->entryCnt++;
} else {
return PT_ERROR_ENTRY_UPDATE_FAIL;
}
}
/* Prepare write back to flash */
/* Update age */
pt_table->age++;
pt_table->crc32 = BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4);
/* Update entries CRC */
entries_len = pt_table->entryCnt * sizeof(pt_table_entry_config);
crc32 = (uint32_t *)((uintptr_t)pt_entries + entries_len);
*crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_entries[0], entries_len);
/* Write back to flash */
/* Erase flash first */
// ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) + entries_len + 4 - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config) + entries_len + 4);
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_WRITE;
}
/* Write flash */
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)pt_stuff, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
/****************************************************************************/ /**
* @brief Create partition entry
*
* @param ptID: Partition table ID
*
* @return Partition create result
*
*******************************************************************************/
pt_table_error_type pt_table_create(pt_table_id_type pt_id) {
uint32_t write_addr;
BL_Err_Type ret;
pt_table_config pt_table;
if (pt_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (pt_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
/* Prepare write back to flash */
pt_table.magicCode = BFLB_PT_MAGIC_CODE;
pt_table.version = 0;
pt_table.entryCnt = 0;
pt_table.age = 0;
pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_table, sizeof(pt_table_config) - 4);
/* Write back to flash */
// ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)&pt_table, sizeof(pt_table_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_dump(void) {
uint32_t pt_valid[2] = {0, 0};
pt_table_stuff_config pt_stuff[2];
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if (pt_valid[0]) {
MSG("PT TABLE0 valid\r\n");
} else {
MSG("PT TABLE0 invalid\r\n");
}
if (pt_valid[1]) {
MSG("PT TABLE1 valid\r\n");
} else {
MSG("PT TABLE1 invalid\r\n");
}
for (int i = 0; i < 2; i++) {
if (pt_valid[i] == 1) {
MSG("ptStuff[%d].pt_table.magicCode 0x%08x\r\n", i, pt_stuff[i].pt_table.magicCode);
MSG("ptStuff[%d].pt_table.version 0x%08x\r\n", i, pt_stuff[i].pt_table.version);
MSG("ptStuff[%d].pt_table.entryCnt 0x%08x\r\n", i, pt_stuff[i].pt_table.entryCnt);
MSG("ptStuff[%d].pt_table.age 0x%08x\r\n", i, pt_stuff[i].pt_table.age);
MSG("ptStuff[%d].pt_table.crc32 0x%08x\r\n", i, pt_stuff[i].pt_table.crc32);
for (int j = 0; j < pt_stuff[i].pt_table.entryCnt; j++) {
MSG("ptStuff[%d].pt_entries[%d].type 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].type);
MSG("ptStuff[%d].pt_entries[%d].device 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].device);
MSG("ptStuff[%d].pt_entries[%d].active_index 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].active_index);
MSG("ptStuff[%d].pt_entries[%d].Address[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[0]);
MSG("ptStuff[%d].pt_entries[%d].Address[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[1]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[0]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[1]);
MSG("ptStuff[%d].pt_entries[%d].len 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].len);
MSG("ptStuff[%d].pt_entries[%d].age 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].age);
}
}
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para) {
uint32_t pt_valid[2] = {0, 0};
pt_table_stuff_config pt_stuff[2];
uint8_t active_index;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if ((pt_valid[0] == 1) && (pt_valid[1] == 1)) {
if (pt_stuff[0].pt_table.age >= pt_stuff[1].pt_table.age) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
}
for (i = 0; i < pt_table->entryCnt; i++) {
if (pt_entries[i].type == pt_entry->type) {
ARCH_MemCpy_Fast(&pt_entries[i], pt_entry, sizeof(pt_table_entry_config));
break;
}
}
} else if (pt_valid[1] == 1) {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
} else if (pt_valid[0] == 1) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
return PT_ERROR_TABLE_NOT_VALID;
}
if (i == pt_table->entryCnt) {
/* Not found this entry ,add new one */
if (pt_table->entryCnt < PT_ENTRY_MAX) {
ARCH_MemCpy_Fast(&pt_entries[pt_table->entryCnt], pt_entry, sizeof(pt_table_entry_config));
pt_table->entryCnt++;
} else {
return PT_ERROR_ENTRY_UPDATE_FAIL;
}
}
MSG("inactive_table_index %d, inactive index %d , IAP start addr %08x \r\n", para->inactive_table_index, para->inactive_index, para->iap_start_addr);
return PT_ERROR_SUCCESS;
}
/* Prepare write back to flash */
/* Update age */
pt_table->age++;
pt_table->crc32 = BFLB_Soft_CRC32((uint8_t *)pt_table, sizeof(pt_table_config) - 4);
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para) {
pt_table_stuff_config pt_stuff, pt_stuff_write;
int32_t ret;
uint32_t *p_crc32;
uint32_t entries_len;
/* Update entries CRC */
entries_len = pt_table->entryCnt * sizeof(pt_table_entry_config);
crc32 = (uint32_t *)((uintptr_t)pt_entries + entries_len);
*crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_entries[0], entries_len);
if (para->inactive_table_index == 1) {
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
} else if (para->inactive_table_index == 0) {
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
}
/* Write back to flash */
/* Erase flash first */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) + entries_len + 4 - 1);
ret = gp_pt_table_flash_erase(write_addr, sizeof(pt_table_config) + entries_len + 4);
ARCH_MemCpy_Fast((void *)&pt_stuff_write, (void *)&pt_stuff, sizeof(pt_table_stuff_config));
pt_stuff_write.pt_table.age += 1;
pt_stuff_write.pt_entries[0].active_index = !(pt_stuff_write.pt_entries[0].active_index & 0x01);
pt_stuff_write.pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_stuff_write, sizeof(pt_table_config) - 4);
entries_len = sizeof(pt_table_entry_config) * pt_stuff_write.pt_table.entryCnt;
// pt_stuff_write.crc32 = BFLB_Soft_CRC32((uint8_t*)pt_stuff_write.pt_entries,entries_len);
p_crc32 = (uint32_t *)((uintptr_t)pt_stuff_write.pt_entries + entries_len);
*p_crc32 = BFLB_Soft_CRC32((uint8_t *)pt_stuff_write.pt_entries, entries_len);
if (para->inactive_table_index == 1) {
// ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, BFLB_PT_TABLE1_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_WRITE;
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
/* Write flash */
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)pt_stuff, sizeof(pt_table_stuff_config));
ret = gp_pt_table_flash_write(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
return PT_ERROR_SUCCESS;
}
/****************************************************************************/ /**
* @brief Create partition entry
*
* @param ptID: Partition table ID
*
* @return Partition create result
*
*******************************************************************************/
pt_table_error_type pt_table_create(pt_table_id_type pt_id)
{
uint32_t write_addr;
BL_Err_Type ret;
pt_table_config pt_table;
if (pt_id == PT_TABLE_ID_INVALID) {
return PT_ERROR_TABLE_NOT_VALID;
}
if (pt_id == PT_TABLE_ID_0) {
write_addr = BFLB_PT_TABLE0_ADDRESS;
} else {
write_addr = BFLB_PT_TABLE1_ADDRESS;
}
/* Prepare write back to flash */
pt_table.magicCode = BFLB_PT_MAGIC_CODE;
pt_table.version = 0;
pt_table.entryCnt = 0;
pt_table.age = 0;
pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_table, sizeof(pt_table_config) - 4);
/* Write back to flash */
//ret = gp_pt_table_flash_erase(write_addr, write_addr + sizeof(pt_table_config) - 1);
ret = gp_pt_table_flash_erase(write_addr,sizeof(pt_table_config));
} else if (para->inactive_table_index == 0) {
// ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, BFLB_PT_TABLE0_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(write_addr, (uint8_t *)&pt_table, sizeof(pt_table_config));
ret = gp_pt_table_flash_write(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_dump(void)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if (pt_valid[0]) {
MSG("PT TABLE0 valid\r\n");
} else {
MSG("PT TABLE0 invalid\r\n");
}
if (pt_valid[1]) {
MSG("PT TABLE1 valid\r\n");
} else {
MSG("PT TABLE1 invalid\r\n");
}
for (int i = 0; i < 2; i++) {
if (pt_valid[i] == 1) {
MSG("ptStuff[%d].pt_table.magicCode 0x%08x\r\n", i, pt_stuff[i].pt_table.magicCode);
MSG("ptStuff[%d].pt_table.version 0x%08x\r\n", i, pt_stuff[i].pt_table.version);
MSG("ptStuff[%d].pt_table.entryCnt 0x%08x\r\n", i, pt_stuff[i].pt_table.entryCnt);
MSG("ptStuff[%d].pt_table.age 0x%08x\r\n", i, pt_stuff[i].pt_table.age);
MSG("ptStuff[%d].pt_table.crc32 0x%08x\r\n", i, pt_stuff[i].pt_table.crc32);
for (int j = 0; j < pt_stuff[i].pt_table.entryCnt; j++) {
MSG("ptStuff[%d].pt_entries[%d].type 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].type);
MSG("ptStuff[%d].pt_entries[%d].device 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].device);
MSG("ptStuff[%d].pt_entries[%d].active_index 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].active_index);
MSG("ptStuff[%d].pt_entries[%d].Address[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[0]);
MSG("ptStuff[%d].pt_entries[%d].Address[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].start_address[1]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[0] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[0]);
MSG("ptStuff[%d].pt_entries[%d].maxLen[1] 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].max_len[1]);
MSG("ptStuff[%d].pt_entries[%d].len 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].len);
MSG("ptStuff[%d].pt_entries[%d].age 0x%08x\r\n", i, j, pt_stuff[i].pt_entries[j].age);
}
}
}
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_get_iap_para(pt_table_iap_param_type *para)
{
uint32_t pt_valid[2] = { 0, 0 };
pt_table_stuff_config pt_stuff[2];
uint8_t active_index;
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff[0], sizeof(pt_table_stuff_config));
pt_valid[0] = pt_table_valid(&pt_stuff[0]);
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff[1], sizeof(pt_table_stuff_config));
pt_valid[1] = pt_table_valid(&pt_stuff[1]);
if ((pt_valid[0] == 1) && (pt_valid[1] == 1)) {
if (pt_stuff[0].pt_table.age >= pt_stuff[1].pt_table.age) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
}
} else if (pt_valid[1] == 1) {
active_index = pt_stuff[1].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[1].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 0;
} else if (pt_valid[0] == 1) {
active_index = pt_stuff[0].pt_entries[0].active_index;
para->iap_write_addr = para->iap_start_addr = pt_stuff[0].pt_entries[0].start_address[!(active_index & 0x01)];
para->inactive_index = !(active_index & 0x01);
para->inactive_table_index = 1;
} else {
return PT_ERROR_TABLE_NOT_VALID;
}
MSG("inactive_table_index %d, inactive index %d , IAP start addr %08x \r\n", para->inactive_table_index, para->inactive_index, para->iap_start_addr);
return PT_ERROR_SUCCESS;
}
pt_table_error_type pt_table_set_iap_para(pt_table_iap_param_type *para)
{
pt_table_stuff_config pt_stuff, pt_stuff_write;
int32_t ret;
uint32_t *p_crc32;
uint32_t entries_len;
if (para->inactive_table_index == 1) {
gp_pt_table_flash_read(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
} else if (para->inactive_table_index == 0) {
gp_pt_table_flash_read(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff, sizeof(pt_table_stuff_config));
}
ARCH_MemCpy_Fast((void *)&pt_stuff_write, (void *)&pt_stuff, sizeof(pt_table_stuff_config));
pt_stuff_write.pt_table.age += 1;
pt_stuff_write.pt_entries[0].active_index = !(pt_stuff_write.pt_entries[0].active_index & 0x01);
pt_stuff_write.pt_table.crc32 = BFLB_Soft_CRC32((uint8_t *)&pt_stuff_write, sizeof(pt_table_config) - 4);
entries_len = sizeof(pt_table_entry_config) * pt_stuff_write.pt_table.entryCnt;
//pt_stuff_write.crc32 = BFLB_Soft_CRC32((uint8_t*)pt_stuff_write.pt_entries,entries_len);
p_crc32 = (uint32_t *)((uintptr_t)pt_stuff_write.pt_entries + entries_len);
*p_crc32 = BFLB_Soft_CRC32((uint8_t *)pt_stuff_write.pt_entries, entries_len);
if (para->inactive_table_index == 1) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, BFLB_PT_TABLE1_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE1_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE1_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
} else if (para->inactive_table_index == 0) {
//ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, BFLB_PT_TABLE0_ADDRESS + sizeof(pt_table_stuff_config) - 1);
ret = gp_pt_table_flash_erase(BFLB_PT_TABLE0_ADDRESS, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Erase error\r\n");
return PT_ERROR_FALSH_ERASE;
}
ret = gp_pt_table_flash_write(BFLB_PT_TABLE0_ADDRESS, (uint8_t *)&pt_stuff_write, sizeof(pt_table_stuff_config));
if (ret != SUCCESS) {
MSG_ERR("Flash Write error\r\n");
return PT_ERROR_FALSH_WRITE;
}
}
MSG("Update pt_table suss\r\n");
return PT_ERROR_SUCCESS;
MSG("Update pt_table suss\r\n");
return PT_ERROR_SUCCESS;
}
/*@} end of group PARTITION_Public_Functions */

View File

@@ -23,46 +23,43 @@
#include "pid.h"
void pid_init(pid_alg_t *pid)
{
pid->set_val = 0.0f;
pid->out_val = 0.0f;
void pid_init(pid_alg_t *pid) {
pid->set_val = 0.0f;
pid->out_val = 0.0f;
pid->last_error = 0.0f;
pid->prev_error = 0.0f;
pid->last_error = 0.0f;
pid->prev_error = 0.0f;
pid->kp = 3.0f;
pid->ki = 0.0f;
pid->kd = 0.0f;
pid->kp = 3.0f;
pid->ki = 0.0f;
pid->kd = 0.0f;
pid->i_error = 0.0f;
pid->sum_error = 0.0f;
pid->i_error = 0.0f;
pid->sum_error = 0.0f;
pid->max_val = 32;
pid->min_val = -32;
pid->max_val = 32;
pid->min_val = -32;
}
// standard pid
float standard_pid_cal(pid_alg_t *pid, float next_val)
{
pid->set_val = next_val;
pid->i_error = pid->set_val - pid->out_val;
pid->sum_error += pid->i_error;
pid->out_val = pid->kp * pid->i_error + pid->ki * pid->sum_error + pid->kd * (pid->i_error - pid->last_error);
pid->last_error = pid->i_error;
float standard_pid_cal(pid_alg_t *pid, float next_val) {
pid->set_val = next_val;
pid->i_error = pid->set_val - pid->out_val;
pid->sum_error += pid->i_error;
pid->out_val = pid->kp * pid->i_error + pid->ki * pid->sum_error + pid->kd * (pid->i_error - pid->last_error);
pid->last_error = pid->i_error;
return pid->out_val;
return pid->out_val;
}
// increment pid
float increment_pid_cal(pid_alg_t *pid, float next_val)
{
pid->set_val = next_val;
pid->i_error = pid->set_val - pid->out_val;
float increment = pid->kp * (pid->i_error - pid->prev_error) + pid->ki * pid->i_error + pid->kd * (pid->i_error - 2 * pid->prev_error + pid->last_error);
pid->out_val += increment;
pid->last_error = pid->prev_error;
pid->prev_error = pid->i_error;
float increment_pid_cal(pid_alg_t *pid, float next_val) {
pid->set_val = next_val;
pid->i_error = pid->set_val - pid->out_val;
float increment = pid->kp * (pid->i_error - pid->prev_error) + pid->ki * pid->i_error + pid->kd * (pid->i_error - 2 * pid->prev_error + pid->last_error);
pid->out_val += increment;
pid->last_error = pid->prev_error;
pid->prev_error = pid->i_error;
return pid->out_val;
return pid->out_val;
}

View File

@@ -28,167 +28,103 @@
// we use 0x8005 here and
const uint8_t chCRCHTalbe[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};
const uint8_t chCRCLTalbe[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len)
{
uint8_t chCRCHi = 0xFF;
uint8_t chCRCLo = 0xFF;
uint16_t wIndex;
uint8_t *data = (uint8_t *)dataIn;
uint16_t BFLB_Soft_CRC16(void *dataIn, uint32_t len) {
uint8_t chCRCHi = 0xFF;
uint8_t chCRCLo = 0xFF;
uint16_t wIndex;
uint8_t *data = (uint8_t *)dataIn;
while (len--) {
wIndex = chCRCLo ^ *data++;
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];
chCRCHi = chCRCLTalbe[wIndex];
}
while (len--) {
wIndex = chCRCLo ^ *data++;
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];
chCRCHi = chCRCLTalbe[wIndex];
}
return ((chCRCHi << 8) | chCRCLo);
return ((chCRCHi << 8) | chCRCLo);
}
/*
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
*/
const uint32_t crc32Tab[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
uint32_t BFLB_Soft_CRC32_Table(void *dataIn, uint32_t len)
{
uint32_t crc = 0;
uint8_t *data = (uint8_t *)dataIn;
uint32_t BFLB_Soft_CRC32_Table(void *dataIn, uint32_t len) {
uint32_t crc = 0;
uint8_t *data = (uint8_t *)dataIn;
crc = crc ^ 0xffffffff;
crc = crc ^ 0xffffffff;
while (len--) {
crc = crc32Tab[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
}
while (len--) {
crc = crc32Tab[(crc ^ *data++) & 0xFF] ^ (crc >> 8);
}
return crc ^ 0xffffffff;
return crc ^ 0xffffffff;
}
/******************************************************************************
* Name: CRC-32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
* Poly: 0x4C11DB7
* Init: 0xFFFFFFF
* Refin: True
* Refout: True
* Xorout: 0xFFFFFFF
* Alias: CRC_32/ADCCP
* Use: WinRAR,ect.
*****************************************************************************/
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len)
{
uint8_t i;
uint32_t crc = ~initial; // Initial value
uint8_t *data=(uint8_t *)dataIn;
while(len--){
crc ^= *data++; // crc ^= *data; data++;
for (i = 0; i < 8; ++i){
if (crc & 1){
crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7
}else{
crc = (crc >> 1);
}
}
* Name: CRC-32 x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
* Poly: 0x4C11DB7
* Init: 0xFFFFFFF
* Refin: True
* Refout: True
* Xorout: 0xFFFFFFF
* Alias: CRC_32/ADCCP
* Use: WinRAR,ect.
*****************************************************************************/
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32_Ex(uint32_t initial, void *dataIn, uint32_t len) {
uint8_t i;
uint32_t crc = ~initial; // Initial value
uint8_t *data = (uint8_t *)dataIn;
while (len--) {
crc ^= *data++; // crc ^= *data; data++;
for (i = 0; i < 8; ++i) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xEDB88320; // 0xEDB88320= reverse 0x04C11DB7
} else {
crc = (crc >> 1);
}
}
return ~crc;
}
return ~crc;
}
#ifndef BFLB_USE_ROM_DRIVER
__WEAK__
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32(void *dataIn, uint32_t len)
{
return BFLB_Soft_CRC32_Ex(0,dataIn,len);
}
uint32_t ATTR_TCM_SECTION BFLB_Soft_CRC32(void *dataIn, uint32_t len) { return BFLB_Soft_CRC32_Ex(0, dataIn, len); }
#endif

View File

@@ -23,114 +23,107 @@
#include "timestamp.h"
#define FOUR_YEAR_DAY ((365 << 2) + 1) //The total number of days in a 4-year cycle
#define TIMEZONE (8) //Beijing time Zone adjustment
#define FOUR_YEAR_DAY ((365 << 2) + 1) // The total number of days in a 4-year cycle
#define TIMEZONE (8) // Beijing time Zone adjustment
#define SEC_NUM_PER_DAY (24 * 60 * 60)
#define SEC_NUM_PER_HOUR (60 * 60)
#define SEC_NUM_PER_MINUTE (60)
static uint8_t month_day[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //平年
static uint8_t Leap_month_day[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //闰年
static uint8_t month_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 平年
static uint8_t Leap_month_day[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 闰年
/**
* @bref judge if it is a leap year
* @para year to be judge
* @return 1leap year 0 nonleap year
*/
bool check_leap_year(uint16_t year)
{
if (year % 4) {
return false;
* @bref judge if it is a leap year
* @para year to be judge
* @return 1leap year 0 nonleap year
*/
bool check_leap_year(uint16_t year) {
if (year % 4) {
return false;
} else {
if ((year % 100 == 0) && (year % 400 != 0)) {
return false;
} else {
if ((year % 100 == 0) && (year % 400 != 0)) {
return false;
} else {
return true;
}
return true;
}
}
}
void cal_weekday(rtc_time *beijing_time)
{
uint32_t y,m,d,w;
void cal_weekday(rtc_time *beijing_time) {
uint32_t y, m, d, w;
y=beijing_time->year;
m=beijing_time->month;
d=beijing_time->day;
y = beijing_time->year;
m = beijing_time->month;
d = beijing_time->day;
if((m==1)||(m==2))
{
m+=12;
y--;
}
/*
把一月和二月看成是上一年的十三月和十四月如果是2004-1-10则换算成2003-13-10来代入公式计算。
以公元元年为参考公元元年1月1日为星期一</PRE><PRE>程序如下:
利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)
*/
w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
if ((m == 1) || (m == 2)) {
m += 12;
y--;
}
/*
把一月和二月看成是上一年的十三月和十四月如果是2004-1-10则换算成2003-13-10来代入公式计算。
以公元元年为参考公元元年1月1日为星期一</PRE><PRE>程序如下:
利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)
*/
w = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400 + 1) % 7;
beijing_time->week=(uint8_t)w;
beijing_time->week = (uint8_t)w;
}
void unixtime2bejingtime(uint32_t unixtime, rtc_time *beijing_time)
{
uint32_t totle_day_num;
uint32_t current_sec_num;
void unixtime2bejingtime(uint32_t unixtime, rtc_time *beijing_time) {
uint32_t totle_day_num;
uint32_t current_sec_num;
uint16_t remain_day;
uint16_t remain_day;
uint16_t temp_year;
uint16_t temp_year;
uint8_t *p = NULL;
uint8_t *p = NULL;
totle_day_num = unixtime / SEC_NUM_PER_DAY; //The total number of days
current_sec_num = unixtime % SEC_NUM_PER_DAY; //The number of seconds this day
totle_day_num = unixtime / SEC_NUM_PER_DAY; // The total number of days
current_sec_num = unixtime % SEC_NUM_PER_DAY; // The number of seconds this day
/* use the number of seconds this day, To calculate hour\minute\second */
beijing_time->hour = current_sec_num / SEC_NUM_PER_HOUR;
beijing_time->minute = (current_sec_num % SEC_NUM_PER_HOUR) / SEC_NUM_PER_MINUTE;
beijing_time->second = (current_sec_num % SEC_NUM_PER_HOUR) % SEC_NUM_PER_MINUTE;
/* use the number of seconds this day, To calculate hour\minute\second */
beijing_time->hour = current_sec_num / SEC_NUM_PER_HOUR;
beijing_time->minute = (current_sec_num % SEC_NUM_PER_HOUR) / SEC_NUM_PER_MINUTE;
beijing_time->second = (current_sec_num % SEC_NUM_PER_HOUR) % SEC_NUM_PER_MINUTE;
/* Adjust the time zone and check whether the date is +1 */
beijing_time->hour += 8;
if (beijing_time->hour > 23) {
beijing_time->hour -= 24;
totle_day_num++;
}
/* Adjust the time zone and check whether the date is +1 */
beijing_time->hour += 8;
if (beijing_time->hour > 23) {
beijing_time->hour -= 24;
totle_day_num++;
}
/* calculate year */
beijing_time->year = 1970 + (totle_day_num / FOUR_YEAR_DAY) * 4; // 4-year as a cycle
remain_day = totle_day_num % FOUR_YEAR_DAY; // remaining day nym( < 4 year )
/* calculate year */
beijing_time->year = 1970 + (totle_day_num / FOUR_YEAR_DAY) * 4; // 4-year as a cycle
remain_day = totle_day_num % FOUR_YEAR_DAY; //remaining day nym( < 4 year )
/* calculate year & day */
/* calculate year & day */
temp_year = check_leap_year(beijing_time->year) ? 366 : 365;
while (remain_day >= temp_year) {
beijing_time->year++;
remain_day -= temp_year;
temp_year = check_leap_year(beijing_time->year) ? 366 : 365;
while (remain_day >= temp_year) {
beijing_time->year++;
remain_day -= temp_year;
temp_year = check_leap_year(beijing_time->year) ? 366 : 365;
}
}
/* Calculate specific dates(month\day)*/
p = check_leap_year(beijing_time->year) ? Leap_month_day : month_day;
remain_day++; //The actual day starts at 1
beijing_time->month = 0;
while (remain_day > *(p + beijing_time->month)) {
remain_day -= *(p + beijing_time->month);
beijing_time->month++;
}
/* Calculate specific dates(month\day)*/
p = check_leap_year(beijing_time->year) ? Leap_month_day : month_day;
remain_day++; // The actual day starts at 1
beijing_time->month = 0;
while (remain_day > *(p + beijing_time->month)) {
remain_day -= *(p + beijing_time->month);
beijing_time->month++;
}
beijing_time->month++; //The actual month starts at 1
beijing_time->day = remain_day;
beijing_time->month++; // The actual month starts at 1
beijing_time->day = remain_day;
/*利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)*/
beijing_time->week =
beijing_time->day + 2 * beijing_time->month + 3 * (beijing_time->month + 1) / 5 + beijing_time->year + beijing_time->year / 4 - beijing_time->year / 100 + beijing_time->year / 400;
/*利用基姆拉尔森计算日期公式 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)*/
beijing_time->week = beijing_time->day + 2*beijing_time->month + 3*(beijing_time->month+1)/5 + \
beijing_time->year + beijing_time->year/4 - beijing_time->year/100 +beijing_time->year/400 ;
cal_weekday(beijing_time);
cal_weekday(beijing_time);
}

View File

@@ -1,323 +1,318 @@
/*****************************************************************************************
*
* @file bl_hci_wrapper.c
*
* @brief Bouffalo Lab hci wrapper functions
*
* Copyright (C) Bouffalo Lab 2018
*
* History: 2018-08 crealted by llgong @ Shanghai
*
*****************************************************************************************/
*
* @file bl_hci_wrapper.c
*
* @brief Bouffalo Lab hci wrapper functions
*
* Copyright (C) Bouffalo Lab 2018
*
* History: 2018-08 crealted by llgong @ Shanghai
*
*****************************************************************************************/
#include <string.h>
#include <log.h>
#include "hci_host.h"
#include "bl_hci_wrapper.h"
#include "hci_driver.h"
#include "../common/include/errno.h"
#include "byteorder.h"
#include "hci_driver.h"
#include "hci_host.h"
#include "hci_onchip.h"
#include <log.h>
#include <string.h>
#define DATA_MSG_CNT 10
struct rx_msg_struct data_msg[DATA_MSG_CNT];
struct k_queue msg_queue;
struct k_queue msg_queue;
#if defined(BFLB_BLE_NOTIFY_ADV_DISCARDED)
extern void ble_controller_notify_adv_discarded(uint8_t *adv_bd_addr, uint8_t adv_type);
#endif
struct rx_msg_struct *bl_find_valid_data_msg()
{
struct rx_msg_struct empty_msg;
memset(&empty_msg, 0, sizeof(struct rx_msg_struct));
struct rx_msg_struct *bl_find_valid_data_msg() {
struct rx_msg_struct empty_msg;
memset(&empty_msg, 0, sizeof(struct rx_msg_struct));
for (int i = 0; i < DATA_MSG_CNT; i++) {
if (!memcmp(&data_msg[i], &empty_msg, sizeof(struct rx_msg_struct))) {
return (data_msg + i);
}
for (int i = 0; i < DATA_MSG_CNT; i++) {
if (!memcmp(&data_msg[i], &empty_msg, sizeof(struct rx_msg_struct))) {
return (data_msg + i);
}
}
return NULL;
return NULL;
}
int bl_onchiphci_send_2_controller(struct net_buf *buf)
{
uint16_t opcode;
uint16_t dest_id = 0x00;
uint8_t buf_type;
uint8_t pkt_type;
hci_pkt_struct pkt;
int bl_onchiphci_send_2_controller(struct net_buf *buf) {
uint16_t opcode;
uint16_t dest_id = 0x00;
uint8_t buf_type;
uint8_t pkt_type;
hci_pkt_struct pkt;
buf_type = bt_buf_get_type(buf);
switch (buf_type) {
case BT_BUF_CMD: {
struct bt_hci_cmd_hdr *chdr;
buf_type = bt_buf_get_type(buf);
switch (buf_type) {
case BT_BUF_CMD: {
struct bt_hci_cmd_hdr *chdr;
if (buf->len < sizeof(struct bt_hci_cmd_hdr)) {
return -EINVAL;
}
chdr = (void *)buf->data;
if (buf->len < chdr->param_len) {
return -EINVAL;
}
pkt_type = BT_HCI_CMD;
opcode = sys_le16_to_cpu(chdr->opcode);
//move buf to the payload
net_buf_pull(buf, sizeof(struct bt_hci_cmd_hdr));
switch (opcode) {
//ble refer to hci_cmd_desc_tab_le, for the ones of which dest_ll is BLE_CTRL
case BT_HCI_OP_LE_CONN_UPDATE:
case BT_HCI_OP_LE_READ_CHAN_MAP:
case BT_HCI_OP_LE_READ_REMOTE_FEATURES:
case BT_HCI_OP_LE_START_ENCRYPTION:
case BT_HCI_OP_LE_LTK_REQ_REPLY:
case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY:
case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY:
case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY:
case BT_HCI_OP_LE_SET_DATA_LEN:
case BT_HCI_OP_LE_READ_PHY:
case BT_HCI_OP_LE_SET_PHY:
//bredr identify link id, according to dest_id
case BT_HCI_OP_READ_REMOTE_FEATURES:
case BT_HCI_OP_READ_REMOTE_EXT_FEATURES:
case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE: {
//dest_id is connectin handle
dest_id = buf->data[0];
}
default:
break;
}
pkt.p.hci_cmd.opcode = opcode;
pkt.p.hci_cmd.param_len = chdr->param_len;
pkt.p.hci_cmd.params = buf->data;
break;
}
case BT_BUF_ACL_OUT: {
struct bt_hci_acl_hdr *acl;
//connhandle +l2cap field
uint16_t connhdl_l2cf, tlt_len;
if (buf->len < sizeof(struct bt_hci_acl_hdr)) {
return -EINVAL;
}
pkt_type = BT_HCI_ACL_DATA;
acl = (void *)buf->data;
tlt_len = sys_le16_to_cpu(acl->len);
connhdl_l2cf = sys_le16_to_cpu(acl->handle);
//move buf to the payload
net_buf_pull(buf, sizeof(struct bt_hci_acl_hdr));
if (buf->len < tlt_len) {
return -EINVAL;
}
//get connection_handle
dest_id = bt_acl_handle(connhdl_l2cf);
pkt.p.acl_data.conhdl = dest_id;
pkt.p.acl_data.pb_bc_flag = bt_acl_flags(connhdl_l2cf);
pkt.p.acl_data.len = tlt_len;
pkt.p.acl_data.buffer = (uint8_t *)buf->data;
break;
}
default:
return -EINVAL;
if (buf->len < sizeof(struct bt_hci_cmd_hdr)) {
return -EINVAL;
}
return bt_onchiphci_send(pkt_type, dest_id, &pkt);
}
chdr = (void *)buf->data;
void bl_packet_to_host(uint8_t pkt_type, uint16_t src_id, uint8_t *param, uint8_t param_len, struct net_buf *buf)
{
uint16_t tlt_len;
bool prio = true;
uint8_t nb_h2c_cmd_pkts = 0x01;
uint8_t *buf_data = net_buf_tail(buf);
bt_buf_set_rx_adv(buf, false);
switch (pkt_type) {
case BT_HCI_CMD_CMP_EVT: {
tlt_len = BT_HCI_EVT_CC_PARAM_OFFSET + param_len;
*buf_data++ = BT_HCI_EVT_CMD_COMPLETE;
*buf_data++ = BT_HCI_CCEVT_HDR_PARLEN + param_len;
*buf_data++ = nb_h2c_cmd_pkts;
sys_put_le16(src_id, buf_data);
buf_data += 2;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_CMD_STAT_EVT: {
tlt_len = BT_HCI_CSEVT_LEN;
*buf_data++ = BT_HCI_EVT_CMD_STATUS;
*buf_data++ = BT_HCI_CSVT_PARLEN;
*buf_data++ = *(uint8_t *)param;
*buf_data++ = nb_h2c_cmd_pkts;
sys_put_le16(src_id, buf_data);
break;
}
case BT_HCI_LE_EVT: {
prio = false;
bt_buf_set_type(buf, BT_BUF_EVT);
if (param[0] == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
bt_buf_set_rx_adv(buf, true);
}
tlt_len = BT_HCI_EVT_LE_PARAM_OFFSET + param_len;
*buf_data++ = BT_HCI_EVT_LE_META_EVENT;
*buf_data++ = param_len;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_EVT: {
if (src_id != BT_HCI_EVT_NUM_COMPLETED_PACKETS) {
prio = false;
}
bt_buf_set_type(buf, BT_BUF_EVT);
tlt_len = BT_HCI_EVT_LE_PARAM_OFFSET + param_len;
*buf_data++ = src_id;
*buf_data++ = param_len;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_ACL_DATA: {
prio = false;
bt_buf_set_type(buf, BT_BUF_ACL_IN);
tlt_len = bt_onchiphci_hanlde_rx_acl(param, buf_data);
break;
}
default: {
net_buf_unref(buf);
return;
}
if (buf->len < chdr->param_len) {
return -EINVAL;
}
net_buf_add(buf, tlt_len);
if (prio) {
bt_recv_prio(buf);
} else {
hci_driver_enque_recvq(buf);
pkt_type = BT_HCI_CMD;
opcode = sys_le16_to_cpu(chdr->opcode);
// move buf to the payload
net_buf_pull(buf, sizeof(struct bt_hci_cmd_hdr));
switch (opcode) {
// ble refer to hci_cmd_desc_tab_le, for the ones of which dest_ll is BLE_CTRL
case BT_HCI_OP_LE_CONN_UPDATE:
case BT_HCI_OP_LE_READ_CHAN_MAP:
case BT_HCI_OP_LE_READ_REMOTE_FEATURES:
case BT_HCI_OP_LE_START_ENCRYPTION:
case BT_HCI_OP_LE_LTK_REQ_REPLY:
case BT_HCI_OP_LE_LTK_REQ_NEG_REPLY:
case BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY:
case BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY:
case BT_HCI_OP_LE_SET_DATA_LEN:
case BT_HCI_OP_LE_READ_PHY:
case BT_HCI_OP_LE_SET_PHY:
// bredr identify link id, according to dest_id
case BT_HCI_OP_READ_REMOTE_FEATURES:
case BT_HCI_OP_READ_REMOTE_EXT_FEATURES:
case BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE: {
// dest_id is connectin handle
dest_id = buf->data[0];
}
default:
break;
}
pkt.p.hci_cmd.opcode = opcode;
pkt.p.hci_cmd.param_len = chdr->param_len;
pkt.p.hci_cmd.params = buf->data;
break;
}
case BT_BUF_ACL_OUT: {
struct bt_hci_acl_hdr *acl;
// connhandle +l2cap field
uint16_t connhdl_l2cf, tlt_len;
if (buf->len < sizeof(struct bt_hci_acl_hdr)) {
return -EINVAL;
}
pkt_type = BT_HCI_ACL_DATA;
acl = (void *)buf->data;
tlt_len = sys_le16_to_cpu(acl->len);
connhdl_l2cf = sys_le16_to_cpu(acl->handle);
// move buf to the payload
net_buf_pull(buf, sizeof(struct bt_hci_acl_hdr));
if (buf->len < tlt_len) {
return -EINVAL;
}
// get connection_handle
dest_id = bt_acl_handle(connhdl_l2cf);
pkt.p.acl_data.conhdl = dest_id;
pkt.p.acl_data.pb_bc_flag = bt_acl_flags(connhdl_l2cf);
pkt.p.acl_data.len = tlt_len;
pkt.p.acl_data.buffer = (uint8_t *)buf->data;
break;
}
default:
return -EINVAL;
}
return bt_onchiphci_send(pkt_type, dest_id, &pkt);
}
void bl_trigger_queued_msg()
{
struct net_buf *buf = NULL;
struct rx_msg_struct *msg = NULL;
void bl_packet_to_host(uint8_t pkt_type, uint16_t src_id, uint8_t *param, uint8_t param_len, struct net_buf *buf) {
uint16_t tlt_len;
bool prio = true;
uint8_t nb_h2c_cmd_pkts = 0x01;
do {
unsigned int lock = irq_lock();
uint8_t *buf_data = net_buf_tail(buf);
bt_buf_set_rx_adv(buf, false);
if (k_queue_is_empty(&msg_queue)) {
break;
}
switch (pkt_type) {
case BT_HCI_CMD_CMP_EVT: {
tlt_len = BT_HCI_EVT_CC_PARAM_OFFSET + param_len;
*buf_data++ = BT_HCI_EVT_CMD_COMPLETE;
*buf_data++ = BT_HCI_CCEVT_HDR_PARLEN + param_len;
*buf_data++ = nb_h2c_cmd_pkts;
sys_put_le16(src_id, buf_data);
buf_data += 2;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_CMD_STAT_EVT: {
tlt_len = BT_HCI_CSEVT_LEN;
*buf_data++ = BT_HCI_EVT_CMD_STATUS;
*buf_data++ = BT_HCI_CSVT_PARLEN;
*buf_data++ = *(uint8_t *)param;
*buf_data++ = nb_h2c_cmd_pkts;
sys_put_le16(src_id, buf_data);
break;
}
case BT_HCI_LE_EVT: {
prio = false;
bt_buf_set_type(buf, BT_BUF_EVT);
if (param[0] == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
bt_buf_set_rx_adv(buf, true);
}
tlt_len = BT_HCI_EVT_LE_PARAM_OFFSET + param_len;
*buf_data++ = BT_HCI_EVT_LE_META_EVENT;
*buf_data++ = param_len;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_EVT: {
if (src_id != BT_HCI_EVT_NUM_COMPLETED_PACKETS) {
prio = false;
}
bt_buf_set_type(buf, BT_BUF_EVT);
tlt_len = BT_HCI_EVT_LE_PARAM_OFFSET + param_len;
*buf_data++ = src_id;
*buf_data++ = param_len;
memcpy(buf_data, param, param_len);
break;
}
case BT_HCI_ACL_DATA: {
prio = false;
bt_buf_set_type(buf, BT_BUF_ACL_IN);
tlt_len = bt_onchiphci_hanlde_rx_acl(param, buf_data);
break;
}
default: {
net_buf_unref(buf);
return;
}
}
if (bt_buf_get_rx_avail_cnt() <= CONFIG_BT_RX_BUF_RSV_COUNT)
break;
net_buf_add(buf, tlt_len);
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (!buf) {
break;
}
msg = k_fifo_get(&msg_queue, K_NO_WAIT);
BT_ASSERT(msg);
bl_packet_to_host(msg->pkt_type, msg->src_id, msg->param, msg->param_len, buf);
irq_unlock(lock);
if (msg->param) {
k_free(msg->param);
}
memset(msg, 0, sizeof(struct rx_msg_struct));
} while (buf);
if (prio) {
bt_recv_prio(buf);
} else {
hci_driver_enque_recvq(buf);
}
}
static void bl_onchiphci_rx_packet_handler(uint8_t pkt_type, uint16_t src_id, uint8_t *param, uint8_t param_len)
{
struct net_buf *buf = NULL;
struct rx_msg_struct *rx_msg = NULL;
void bl_trigger_queued_msg() {
struct net_buf *buf = NULL;
struct rx_msg_struct *msg = NULL;
if (pkt_type == BT_HCI_CMD_CMP_EVT || pkt_type == BT_HCI_CMD_STAT_EVT) {
buf = bt_buf_get_cmd_complete(K_FOREVER);
do {
unsigned int lock = irq_lock();
if (k_queue_is_empty(&msg_queue)) {
break;
}
if (bt_buf_get_rx_avail_cnt() <= CONFIG_BT_RX_BUF_RSV_COUNT) {
break;
}
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (!buf) {
break;
}
msg = k_fifo_get(&msg_queue, K_NO_WAIT);
BT_ASSERT(msg);
bl_packet_to_host(msg->pkt_type, msg->src_id, msg->param, msg->param_len, buf);
irq_unlock(lock);
if (msg->param) {
k_free(msg->param);
}
memset(msg, 0, sizeof(struct rx_msg_struct));
} while (buf);
}
static void bl_onchiphci_rx_packet_handler(uint8_t pkt_type, uint16_t src_id, uint8_t *param, uint8_t param_len) {
struct net_buf *buf = NULL;
struct rx_msg_struct *rx_msg = NULL;
if (pkt_type == BT_HCI_CMD_CMP_EVT || pkt_type == BT_HCI_CMD_STAT_EVT) {
buf = bt_buf_get_cmd_complete(K_FOREVER);
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
} else if (pkt_type == BT_HCI_LE_EVT && param[0] == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
if (bt_buf_get_rx_avail_cnt() <= CONFIG_BT_RX_BUF_RSV_COUNT) {
BT_INFO("Discard adv report.");
#if defined(BFLB_BLE_NOTIFY_ADV_DISCARDED)
ble_controller_notify_adv_discarded(&param[4], param[2]);
#endif
return;
}
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (buf) {
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
}
return;
} else {
if (pkt_type != BT_HCI_ACL_DATA) {
/* Using the reserved buf (CONFIG_BT_RX_BUF_RSV_COUNT) firstly. */
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (buf) {
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
} else if (pkt_type == BT_HCI_LE_EVT && param[0] == BT_HCI_EVT_LE_ADVERTISING_REPORT) {
if (bt_buf_get_rx_avail_cnt() <= CONFIG_BT_RX_BUF_RSV_COUNT) {
BT_INFO("Discard adv report.");
#if defined(BFLB_BLE_NOTIFY_ADV_DISCARDED)
ble_controller_notify_adv_discarded(&param[4], param[2]);
#endif
return;
}
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (buf)
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
}
}
rx_msg = bl_find_valid_data_msg();
}
BT_ASSERT(rx_msg);
rx_msg->pkt_type = pkt_type;
rx_msg->src_id = src_id;
rx_msg->param_len = param_len;
if (param_len) {
rx_msg->param = k_malloc(param_len);
memcpy(rx_msg->param, param, param_len);
}
k_fifo_put(&msg_queue, rx_msg);
bl_trigger_queued_msg();
}
uint8_t bl_onchiphci_interface_init(void) {
for (int i = 0; i < DATA_MSG_CNT; i++) {
memset(data_msg + i, 0, sizeof(struct rx_msg_struct));
}
k_queue_init(&msg_queue, DATA_MSG_CNT);
return bt_onchiphci_interface_init(bl_onchiphci_rx_packet_handler);
}
void bl_onchiphci_interface_deinit(void) {
struct rx_msg_struct *msg;
do {
msg = k_fifo_get(&msg_queue, K_NO_WAIT);
if (msg) {
if (msg->param) {
k_free(msg->param);
}
} else {
if (pkt_type != BT_HCI_ACL_DATA) {
/* Using the reserved buf (CONFIG_BT_RX_BUF_RSV_COUNT) firstly. */
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
if (buf) {
bl_packet_to_host(pkt_type, src_id, param, param_len, buf);
return;
}
}
rx_msg = bl_find_valid_data_msg();
break;
}
} while (1);
BT_ASSERT(rx_msg);
rx_msg->pkt_type = pkt_type;
rx_msg->src_id = src_id;
rx_msg->param_len = param_len;
if (param_len) {
rx_msg->param = k_malloc(param_len);
memcpy(rx_msg->param, param, param_len);
}
k_fifo_put(&msg_queue, rx_msg);
bl_trigger_queued_msg();
}
uint8_t bl_onchiphci_interface_init(void)
{
for (int i = 0; i < DATA_MSG_CNT; i++) {
memset(data_msg + i, 0, sizeof(struct rx_msg_struct));
}
k_queue_init(&msg_queue, DATA_MSG_CNT);
return bt_onchiphci_interface_init(bl_onchiphci_rx_packet_handler);
}
void bl_onchiphci_interface_deinit(void)
{
struct rx_msg_struct *msg;
do {
msg = k_fifo_get(&msg_queue, K_NO_WAIT);
if (msg) {
if (msg->param) {
k_free(msg->param);
}
} else {
break;
}
} while (1);
k_queue_free(&msg_queue);
k_queue_free(&msg_queue);
}

View File

@@ -17,11 +17,11 @@
*
* (originally from x86's atomic.c)
*/
#include "bl_port.h"
#include <FreeRTOS.h>
#include <include/atomic.h>
#include "bl_port.h"
//#include <toolchain.h>
//#include <arch/cpu.h>
// #include <toolchain.h>
// #include <arch/cpu.h>
/**
*
@@ -43,22 +43,20 @@
* @param new_value value to compare against
* @return Returns 1 if <new_value> is written, 0 otherwise.
*/
int atomic_cas(atomic_t *target, atomic_val_t old_value,
atomic_val_t new_value)
{
unsigned int key;
int ret = 0;
int atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value) {
unsigned int key;
int ret = 0;
key = irq_lock();
key = irq_lock();
if (*target == old_value) {
*target = new_value;
ret = 1;
}
if (*target == old_value) {
*target = new_value;
ret = 1;
}
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -74,19 +72,18 @@ int atomic_cas(atomic_t *target, atomic_val_t old_value,
*
* @return The previous value from <target>
*/
atomic_val_t atomic_add(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target += value;
ret = *target;
*target += value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -102,19 +99,18 @@ atomic_val_t atomic_add(atomic_t *target, atomic_val_t value)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target -= value;
ret = *target;
*target -= value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -128,19 +124,18 @@ atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value)
*
* @return The value from <target> before the increment
*/
atomic_val_t atomic_inc(atomic_t *target)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_inc(atomic_t *target) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
(*target)++;
ret = *target;
(*target)++;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -154,19 +149,18 @@ atomic_val_t atomic_inc(atomic_t *target)
*
* @return The value from <target> prior to the decrement
*/
atomic_val_t atomic_dec(atomic_t *target)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_dec(atomic_t *target) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
(*target)--;
ret = *target;
(*target)--;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -181,10 +175,7 @@ atomic_val_t atomic_dec(atomic_t *target)
*
* @return The value read from <target>
*/
atomic_val_t atomic_get(const atomic_t *target)
{
return *target;
}
atomic_val_t atomic_get(const atomic_t *target) { return *target; }
/**
*
@@ -198,19 +189,18 @@ atomic_val_t atomic_get(const atomic_t *target)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target = value;
ret = *target;
*target = value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -225,19 +215,18 @@ atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_clear(atomic_t *target)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_clear(atomic_t *target) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target = 0;
ret = *target;
*target = 0;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -253,19 +242,18 @@ atomic_val_t atomic_clear(atomic_t *target)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target |= value;
ret = *target;
*target |= value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -281,19 +269,18 @@ atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target ^= value;
ret = *target;
*target ^= value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -309,19 +296,18 @@ atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target &= value;
ret = *target;
*target &= value;
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}
/**
@@ -337,17 +323,16 @@ atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
*
* @return The previous value from <target>
*/
atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) {
unsigned int key;
atomic_val_t ret;
key = irq_lock();
key = irq_lock();
ret = *target;
*target = ~(*target & value);
ret = *target;
*target = ~(*target & value);
irq_unlock(key);
irq_unlock(key);
return ret;
return ret;
}

View File

@@ -6,28 +6,27 @@
#include <util.h>
u8_t u8_to_dec(char *buf, u8_t buflen, u8_t value)
{
u8_t divisor = 100;
u8_t num_digits = 0;
u8_t digit;
u8_t u8_to_dec(char *buf, u8_t buflen, u8_t value) {
u8_t divisor = 100;
u8_t num_digits = 0;
u8_t digit;
while (buflen > 0 && divisor > 0) {
digit = value / divisor;
if (digit != 0 || divisor == 1 || num_digits != 0) {
*buf = (char)digit + '0';
buf++;
buflen--;
num_digits++;
}
value -= digit * divisor;
divisor /= 10;
while (buflen > 0 && divisor > 0) {
digit = value / divisor;
if (digit != 0 || divisor == 1 || num_digits != 0) {
*buf = (char)digit + '0';
buf++;
buflen--;
num_digits++;
}
if (buflen) {
*buf = '\0';
}
value -= digit * divisor;
divisor /= 10;
}
return num_digits;
if (buflen) {
*buf = '\0';
}
return num_digits;
}

View File

@@ -33,8 +33,7 @@ BUILD_ASSERT(CONFIG_BT_CTLR_RX_PRIO < CONFIG_BT_HCI_TX_PRIO);
* since it introduces ISR latency due to outputting log messages with
* interrupts disabled.
*/
#if !defined(CONFIG_TEST) && !defined(CONFIG_ARCH_POSIX) && \
(defined(CONFIG_BT_LL_SW_SPLIT) || defined(CONFIG_BT_LL_SW_LEGACY))
#if !defined(CONFIG_TEST) && !defined(CONFIG_ARCH_POSIX) && (defined(CONFIG_BT_LL_SW_SPLIT) || defined(CONFIG_BT_LL_SW_LEGACY))
BUILD_ASSERT_MSG(!IS_ENABLED(CONFIG_LOG_IMMEDIATE), "Immediate logging not "
"supported with the software Link Layer");
#endif

View File

@@ -4,8 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <stddef.h>
#include <zephyr/types.h>
#include <errno.h>
// #include <sys/util.h>

View File

@@ -12,50 +12,47 @@
* in a single printk call.
*/
#include <stddef.h>
#include <zephyr/types.h>
#include <zephyr.h>
#include <misc/util.h>
#include <bluetooth.h>
#include <hci_host.h>
#include <misc/util.h>
#include <stddef.h>
#include <zephyr.h>
#include <zephyr/types.h>
const char *bt_hex_real(const void *buf, size_t len)
{
static const char hex[] = "0123456789abcdef";
const char *bt_hex_real(const void *buf, size_t len) {
static const char hex[] = "0123456789abcdef";
#if defined(CONFIG_BT_DEBUG_MONITOR)
static char str[255];
static char str[255];
#else
static char str[128];
static char str[128];
#endif
const u8_t *b = buf;
int i;
const u8_t *b = buf;
int i;
len = MIN(len, (sizeof(str) - 1) / 2);
len = MIN(len, (sizeof(str) - 1) / 2);
for (i = 0; i < len; i++) {
str[i * 2] = hex[b[i] >> 4];
str[i * 2 + 1] = hex[b[i] & 0xf];
}
for (i = 0; i < len; i++) {
str[i * 2] = hex[b[i] >> 4];
str[i * 2 + 1] = hex[b[i] & 0xf];
}
str[i * 2] = '\0';
str[i * 2] = '\0';
return str;
return str;
}
const char *bt_addr_str_real(const bt_addr_t *addr)
{
static char str[BT_ADDR_STR_LEN];
const char *bt_addr_str_real(const bt_addr_t *addr) {
static char str[BT_ADDR_STR_LEN];
bt_addr_to_str(addr, str, sizeof(str));
bt_addr_to_str(addr, str, sizeof(str));
return str;
return str;
}
const char *bt_addr_le_str_real(const bt_addr_le_t *addr)
{
static char str[BT_ADDR_LE_STR_LEN];
const char *bt_addr_le_str_real(const bt_addr_le_t *addr) {
static char str[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(addr, str, sizeof(str));
bt_addr_le_to_str(addr, str, sizeof(str));
return str;
return str;
}

View File

@@ -16,225 +16,203 @@
#include <stdio.h>
#include <misc/__assert.h>
#include <misc/dlist.h>
#include <misc/slist.h>
#include <zephyr.h>
#include <zephyr/types.h>
#include <misc/slist.h>
#include <misc/dlist.h>
#include <misc/__assert.h>
struct k_sem g_poll_sem;
void k_poll_event_init(struct k_poll_event *event, u32_t type,
int mode, void *obj)
{
__ASSERT(mode == K_POLL_MODE_NOTIFY_ONLY,
"only NOTIFY_ONLY mode is supported\n");
__ASSERT(type < (1 << _POLL_NUM_TYPES), "invalid type\n");
__ASSERT(obj, "must provide an object\n");
void k_poll_event_init(struct k_poll_event *event, u32_t type, int mode, void *obj) {
__ASSERT(mode == K_POLL_MODE_NOTIFY_ONLY, "only NOTIFY_ONLY mode is supported\n");
__ASSERT(type < (1 << _POLL_NUM_TYPES), "invalid type\n");
__ASSERT(obj, "must provide an object\n");
event->poller = NULL;
/* event->tag is left uninitialized: the user will set it if needed */
event->type = type;
event->state = K_POLL_STATE_NOT_READY;
event->mode = mode;
event->unused = 0;
event->obj = obj;
event->poller = NULL;
/* event->tag is left uninitialized: the user will set it if needed */
event->type = type;
event->state = K_POLL_STATE_NOT_READY;
event->mode = mode;
event->unused = 0;
event->obj = obj;
}
/* must be called with interrupts locked */
static inline int is_condition_met(struct k_poll_event *event, u32_t *state)
{
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
if (k_sem_count_get(event->sem) > 0) {
*state = K_POLL_STATE_SEM_AVAILABLE;
return 1;
}
break;
case K_POLL_TYPE_DATA_AVAILABLE:
if (!k_queue_is_empty(event->queue)) {
*state = K_POLL_STATE_FIFO_DATA_AVAILABLE;
return 1;
}
break;
case K_POLL_TYPE_SIGNAL:
if (event->signal->signaled) {
*state = K_POLL_STATE_SIGNALED;
return 1;
}
break;
case K_POLL_TYPE_IGNORE:
return 0;
default:
__ASSERT(0, "invalid event type (0x%x)\n", event->type);
break;
static inline int is_condition_met(struct k_poll_event *event, u32_t *state) {
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
if (k_sem_count_get(event->sem) > 0) {
*state = K_POLL_STATE_SEM_AVAILABLE;
return 1;
}
break;
case K_POLL_TYPE_DATA_AVAILABLE:
if (!k_queue_is_empty(event->queue)) {
*state = K_POLL_STATE_FIFO_DATA_AVAILABLE;
return 1;
}
break;
case K_POLL_TYPE_SIGNAL:
if (event->signal->signaled) {
*state = K_POLL_STATE_SIGNALED;
return 1;
}
break;
case K_POLL_TYPE_IGNORE:
return 0;
default:
__ASSERT(0, "invalid event type (0x%x)\n", event->type);
break;
}
return 0;
}
static inline void add_event(sys_dlist_t *events, struct k_poll_event *event,
struct _poller *poller)
{
sys_dlist_append(events, &event->_node);
static inline void add_event(sys_dlist_t *events, struct k_poll_event *event, struct _poller *poller) { sys_dlist_append(events, &event->_node); }
/* must be called with interrupts locked */
static inline int register_event(struct k_poll_event *event, struct _poller *poller) {
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
__ASSERT(event->sem, "invalid semaphore\n");
add_event(&event->sem->poll_events, event, poller);
break;
case K_POLL_TYPE_DATA_AVAILABLE:
__ASSERT(event->queue, "invalid queue\n");
add_event(&event->queue->poll_events, event, poller);
break;
case K_POLL_TYPE_SIGNAL:
__ASSERT(event->signal, "invalid poll signal\n");
add_event(&event->signal->poll_events, event, poller);
break;
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
default:
__ASSERT(0, "invalid event type\n");
break;
}
event->poller = poller;
return 0;
}
/* must be called with interrupts locked */
static inline int register_event(struct k_poll_event *event,
struct _poller *poller)
{
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
__ASSERT(event->sem, "invalid semaphore\n");
add_event(&event->sem->poll_events, event, poller);
break;
case K_POLL_TYPE_DATA_AVAILABLE:
__ASSERT(event->queue, "invalid queue\n");
add_event(&event->queue->poll_events, event, poller);
break;
case K_POLL_TYPE_SIGNAL:
__ASSERT(event->signal, "invalid poll signal\n");
add_event(&event->signal->poll_events, event, poller);
break;
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
default:
__ASSERT(0, "invalid event type\n");
break;
}
static inline void clear_event_registration(struct k_poll_event *event) {
event->poller = NULL;
event->poller = poller;
return 0;
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
__ASSERT(event->sem, "invalid semaphore\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_DATA_AVAILABLE:
__ASSERT(event->queue, "invalid queue\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_SIGNAL:
__ASSERT(event->signal, "invalid poll signal\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
default:
__ASSERT(0, "invalid event type\n");
break;
}
}
/* must be called with interrupts locked */
static inline void clear_event_registration(struct k_poll_event *event)
{
event->poller = NULL;
switch (event->type) {
case K_POLL_TYPE_SEM_AVAILABLE:
__ASSERT(event->sem, "invalid semaphore\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_DATA_AVAILABLE:
__ASSERT(event->queue, "invalid queue\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_SIGNAL:
__ASSERT(event->signal, "invalid poll signal\n");
sys_dlist_remove(&event->_node);
break;
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
default:
__ASSERT(0, "invalid event type\n");
break;
}
}
/* must be called with interrupts locked */
static inline void clear_event_registrations(struct k_poll_event *events,
int last_registered,
unsigned int key)
{
for (; last_registered >= 0; last_registered--) {
clear_event_registration(&events[last_registered]);
irq_unlock(key);
key = irq_lock();
}
}
static inline void set_event_ready(struct k_poll_event *event, u32_t state)
{
event->poller = NULL;
event->state |= state;
}
static bool polling_events(struct k_poll_event *events, int num_events,
s32_t timeout, int *last_registered)
{
int rc;
bool polling = true;
unsigned int key;
for (int ii = 0; ii < num_events; ii++) {
u32_t state;
key = irq_lock();
if (is_condition_met(&events[ii], &state)) {
set_event_ready(&events[ii], state);
polling = false;
} else if (timeout != K_NO_WAIT && polling) {
rc = register_event(&events[ii], NULL);
if (rc == 0) {
++(*last_registered);
} else {
__ASSERT(0, "unexpected return code\n");
}
}
irq_unlock(key);
}
return polling;
}
int k_poll(struct k_poll_event *events, int num_events, s32_t timeout)
{
__ASSERT(events, "NULL events\n");
__ASSERT(num_events > 0, "zero events\n");
int last_registered = -1;
unsigned int key;
bool polling = true;
/* find events whose condition is already fulfilled */
polling = polling_events(events, num_events, timeout, &last_registered);
if (polling == false) {
goto exit;
}
k_sem_take(&g_poll_sem, timeout);
last_registered = -1;
polling_events(events, num_events, timeout, &last_registered);
exit:
static inline void clear_event_registrations(struct k_poll_event *events, int last_registered, unsigned int key) {
for (; last_registered >= 0; last_registered--) {
clear_event_registration(&events[last_registered]);
irq_unlock(key);
key = irq_lock();
clear_event_registrations(events, last_registered, key);
}
}
static inline void set_event_ready(struct k_poll_event *event, u32_t state) {
event->poller = NULL;
event->state |= state;
}
static bool polling_events(struct k_poll_event *events, int num_events, s32_t timeout, int *last_registered) {
int rc;
bool polling = true;
unsigned int key;
for (int ii = 0; ii < num_events; ii++) {
u32_t state;
key = irq_lock();
if (is_condition_met(&events[ii], &state)) {
set_event_ready(&events[ii], state);
polling = false;
} else if (timeout != K_NO_WAIT && polling) {
rc = register_event(&events[ii], NULL);
if (rc == 0) {
++(*last_registered);
} else {
__ASSERT(0, "unexpected return code\n");
}
}
irq_unlock(key);
return 0;
}
return polling;
}
int k_poll(struct k_poll_event *events, int num_events, s32_t timeout) {
__ASSERT(events, "NULL events\n");
__ASSERT(num_events > 0, "zero events\n");
int last_registered = -1;
unsigned int key;
bool polling = true;
/* find events whose condition is already fulfilled */
polling = polling_events(events, num_events, timeout, &last_registered);
if (polling == false) {
goto exit;
}
k_sem_take(&g_poll_sem, timeout);
last_registered = -1;
polling_events(events, num_events, timeout, &last_registered);
exit:
key = irq_lock();
clear_event_registrations(events, last_registered, key);
irq_unlock(key);
return 0;
}
/* must be called with interrupts locked */
static int _signal_poll_event(struct k_poll_event *event, u32_t state,
int *must_reschedule)
{
*must_reschedule = 0;
set_event_ready(event, state);
return 0;
static int _signal_poll_event(struct k_poll_event *event, u32_t state, int *must_reschedule) {
*must_reschedule = 0;
set_event_ready(event, state);
return 0;
}
int k_poll_signal_raise(struct k_poll_signal *signal, int result)
{
unsigned int key = irq_lock();
struct k_poll_event *poll_event;
int must_reschedule;
int k_poll_signal_raise(struct k_poll_signal *signal, int result) {
unsigned int key = irq_lock();
struct k_poll_event *poll_event;
int must_reschedule;
signal->result = result;
signal->signaled = 1;
signal->result = result;
signal->signaled = 1;
poll_event = (struct k_poll_event *)sys_dlist_get(&signal->poll_events);
if (!poll_event) {
irq_unlock(key);
return 0;
}
int rc = _signal_poll_event(poll_event, K_POLL_STATE_SIGNALED,
&must_reschedule);
k_sem_give(&g_poll_sem);
poll_event = (struct k_poll_event *)sys_dlist_get(&signal->poll_events);
if (!poll_event) {
irq_unlock(key);
return rc;
return 0;
}
int rc = _signal_poll_event(poll_event, K_POLL_STATE_SIGNALED, &must_reschedule);
k_sem_give(&g_poll_sem);
irq_unlock(key);
return rc;
}

View File

@@ -10,97 +10,91 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <stddef.h>
#include <errno.h>
#include <string.h>
#include <FreeRTOS.h>
#include <errno.h>
#include <include/atomic.h>
#include <misc/util.h>
#include <misc/byteorder.h>
#include <misc/stack.h>
#include <misc/util.h>
#include <stddef.h>
#include <string.h>
#include <zephyr.h>
#include <constants.h>
#include <aes.h>
#include <utils.h>
#include <cmac_mode.h>
#include <../include/bluetooth/crypto.h>
#include <aes.h>
#include <cmac_mode.h>
#include <constants.h>
#include <utils.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_RPA)
#define LOG_MODULE_NAME bt_rpa
#include "log.h"
#if defined(CONFIG_BT_CTLR_PRIVACY) || defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_SMP)
static int ah(const u8_t irk[16], const u8_t r[3], u8_t out[3])
{
u8_t res[16];
int err;
static int ah(const u8_t irk[16], const u8_t r[3], u8_t out[3]) {
u8_t res[16];
int err;
BT_DBG("irk %s", bt_hex(irk, 16));
BT_DBG("r %s", bt_hex(r, 3));
BT_DBG("irk %s", bt_hex(irk, 16));
BT_DBG("r %s", bt_hex(r, 3));
/* r' = padding || r */
memcpy(res, r, 3);
(void)memset(res + 3, 0, 13);
/* r' = padding || r */
memcpy(res, r, 3);
(void)memset(res + 3, 0, 13);
err = bt_encrypt_le(irk, res, res);
if (err) {
return err;
}
err = bt_encrypt_le(irk, res, res);
if (err) {
return err;
}
/* The output of the random address function ah is:
* ah(h, r) = e(k, r') mod 2^24
* The output of the security function e is then truncated to 24 bits
* by taking the least significant 24 bits of the output of e as the
* result of ah.
*/
memcpy(out, res, 3);
/* The output of the random address function ah is:
* ah(h, r) = e(k, r') mod 2^24
* The output of the security function e is then truncated to 24 bits
* by taking the least significant 24 bits of the output of e as the
* result of ah.
*/
memcpy(out, res, 3);
return 0;
return 0;
}
#endif
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CTLR_PRIVACY)
bool bt_rpa_irk_matches(const u8_t irk[16], const bt_addr_t *addr)
{
u8_t hash[3];
int err;
bool bt_rpa_irk_matches(const u8_t irk[16], const bt_addr_t *addr) {
u8_t hash[3];
int err;
BT_DBG("IRK %s bdaddr %s", bt_hex(irk, 16), bt_addr_str(addr));
BT_DBG("IRK %s bdaddr %s", bt_hex(irk, 16), bt_addr_str(addr));
err = ah(irk, addr->val + 3, hash);
if (err) {
return false;
}
err = ah(irk, addr->val + 3, hash);
if (err) {
return false;
}
return !memcmp(addr->val, hash, 3);
return !memcmp(addr->val, hash, 3);
}
#endif
#if defined(CONFIG_BT_PRIVACY) || defined(CONFIG_BT_CTLR_PRIVACY)
int bt_rpa_create(const u8_t irk[16], bt_addr_t *rpa)
{
int err;
int bt_rpa_create(const u8_t irk[16], bt_addr_t *rpa) {
int err;
err = bt_rand(rpa->val + 3, 3);
if (err) {
return err;
}
err = bt_rand(rpa->val + 3, 3);
if (err) {
return err;
}
BT_ADDR_SET_RPA(rpa);
BT_ADDR_SET_RPA(rpa);
err = ah(irk, rpa->val + 3, rpa->val);
if (err) {
return err;
}
err = ah(irk, rpa->val + 3, rpa->val);
if (err) {
return err;
}
BT_DBG("Created RPA %s", bt_addr_str((bt_addr_t *)rpa->val));
BT_DBG("Created RPA %s", bt_addr_str((bt_addr_t *)rpa->val));
return 0;
return 0;
}
#else
int bt_rpa_create(const u8_t irk[16], bt_addr_t *rpa)
{
return -ENOTSUP;
}
int bt_rpa_create(const u8_t irk[16], bt_addr_t *rpa) { return -ENOTSUP; }
#endif /* CONFIG_BT_PRIVACY */

View File

@@ -35,34 +35,16 @@
#include <utils.h>
static const uint8_t inv_sbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0c, 0x7d
};
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k)
{
return tc_aes128_set_encrypt_key(s, k);
}
int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k) { return tc_aes128_set_encrypt_key(s, k); }
#define mult8(a) (_double_byte(_double_byte(_double_byte(a))))
#define mult9(a) (mult8(a) ^ (a))
@@ -70,52 +52,48 @@ int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k)
#define multd(a) (mult8(a) ^ _double_byte(_double_byte(a)) ^ (a))
#define multe(a) (mult8(a) ^ _double_byte(_double_byte(a)) ^ _double_byte(a))
static inline void mult_row_column(uint8_t *out, const uint8_t *in)
{
out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]);
out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]);
out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]);
out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]);
static inline void mult_row_column(uint8_t *out, const uint8_t *in) {
out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]);
out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]);
out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]);
out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]);
}
static inline void inv_mix_columns(uint8_t *s)
{
uint8_t t[Nb * Nk];
static inline void inv_mix_columns(uint8_t *s) {
uint8_t t[Nb * Nk];
mult_row_column(t, s);
mult_row_column(&t[Nb], s + Nb);
mult_row_column(&t[2 * Nb], s + (2 * Nb));
mult_row_column(&t[3 * Nb], s + (3 * Nb));
(void)_copy(s, sizeof(t), t, sizeof(t));
mult_row_column(t, s);
mult_row_column(&t[Nb], s + Nb);
mult_row_column(&t[2 * Nb], s + (2 * Nb));
mult_row_column(&t[3 * Nb], s + (3 * Nb));
(void)_copy(s, sizeof(t), t, sizeof(t));
}
static inline void add_round_key(uint8_t *s, const unsigned int *k)
{
s[0] ^= (uint8_t)(k[0] >> 24);
s[1] ^= (uint8_t)(k[0] >> 16);
s[2] ^= (uint8_t)(k[0] >> 8);
s[3] ^= (uint8_t)(k[0]);
s[4] ^= (uint8_t)(k[1] >> 24);
s[5] ^= (uint8_t)(k[1] >> 16);
s[6] ^= (uint8_t)(k[1] >> 8);
s[7] ^= (uint8_t)(k[1]);
s[8] ^= (uint8_t)(k[2] >> 24);
s[9] ^= (uint8_t)(k[2] >> 16);
s[10] ^= (uint8_t)(k[2] >> 8);
s[11] ^= (uint8_t)(k[2]);
s[12] ^= (uint8_t)(k[3] >> 24);
s[13] ^= (uint8_t)(k[3] >> 16);
s[14] ^= (uint8_t)(k[3] >> 8);
s[15] ^= (uint8_t)(k[3]);
static inline void add_round_key(uint8_t *s, const unsigned int *k) {
s[0] ^= (uint8_t)(k[0] >> 24);
s[1] ^= (uint8_t)(k[0] >> 16);
s[2] ^= (uint8_t)(k[0] >> 8);
s[3] ^= (uint8_t)(k[0]);
s[4] ^= (uint8_t)(k[1] >> 24);
s[5] ^= (uint8_t)(k[1] >> 16);
s[6] ^= (uint8_t)(k[1] >> 8);
s[7] ^= (uint8_t)(k[1]);
s[8] ^= (uint8_t)(k[2] >> 24);
s[9] ^= (uint8_t)(k[2] >> 16);
s[10] ^= (uint8_t)(k[2] >> 8);
s[11] ^= (uint8_t)(k[2]);
s[12] ^= (uint8_t)(k[3] >> 24);
s[13] ^= (uint8_t)(k[3] >> 16);
s[14] ^= (uint8_t)(k[3] >> 8);
s[15] ^= (uint8_t)(k[3]);
}
static inline void inv_sub_bytes(uint8_t *s)
{
unsigned int i;
static inline void inv_sub_bytes(uint8_t *s) {
unsigned int i;
for (i = 0; i < (Nb * Nk); ++i) {
s[i] = inv_sbox[s[i]];
}
for (i = 0; i < (Nb * Nk); ++i) {
s[i] = inv_sbox[s[i]];
}
}
/*
@@ -123,61 +101,59 @@ static inline void inv_sub_bytes(uint8_t *s)
* inv_mix_columns, but performs it here to reduce the number of memory
* operations.
*/
static inline void inv_shift_rows(uint8_t *s)
{
uint8_t t[Nb * Nk];
static inline void inv_shift_rows(uint8_t *s) {
uint8_t t[Nb * Nk];
t[0] = s[0];
t[1] = s[13];
t[2] = s[10];
t[3] = s[7];
t[4] = s[4];
t[5] = s[1];
t[6] = s[14];
t[7] = s[11];
t[8] = s[8];
t[9] = s[5];
t[10] = s[2];
t[11] = s[15];
t[12] = s[12];
t[13] = s[9];
t[14] = s[6];
t[15] = s[3];
(void)_copy(s, sizeof(t), t, sizeof(t));
t[0] = s[0];
t[1] = s[13];
t[2] = s[10];
t[3] = s[7];
t[4] = s[4];
t[5] = s[1];
t[6] = s[14];
t[7] = s[11];
t[8] = s[8];
t[9] = s[5];
t[10] = s[2];
t[11] = s[15];
t[12] = s[12];
t[13] = s[9];
t[14] = s[6];
t[15] = s[3];
(void)_copy(s, sizeof(t), t, sizeof(t));
}
int tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s)
{
uint8_t state[Nk * Nb];
unsigned int i;
int tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) {
uint8_t state[Nk * Nb];
unsigned int i;
if (out == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (in == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
}
if (out == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (in == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
}
(void)_copy(state, sizeof(state), in, sizeof(state));
(void)_copy(state, sizeof(state), in, sizeof(state));
add_round_key(state, s->words + Nb * Nr);
for (i = Nr - 1; i > 0; --i) {
inv_shift_rows(state);
inv_sub_bytes(state);
add_round_key(state, s->words + Nb * i);
inv_mix_columns(state);
}
add_round_key(state, s->words + Nb * Nr);
for (i = Nr - 1; i > 0; --i) {
inv_shift_rows(state);
inv_sub_bytes(state);
add_round_key(state, s->words);
add_round_key(state, s->words + Nb * i);
inv_mix_columns(state);
}
(void)_copy(out, sizeof(state), state, sizeof(state));
inv_shift_rows(state);
inv_sub_bytes(state);
add_round_key(state, s->words);
/*zeroing out the state buffer */
_set(state, TC_ZERO_BYTE, sizeof(state));
(void)_copy(out, sizeof(state), state, sizeof(state));
return TC_CRYPTO_SUCCESS;
/*zeroing out the state buffer */
_set(state, TC_ZERO_BYTE, sizeof(state));
return TC_CRYPTO_SUCCESS;
}

View File

@@ -31,181 +31,152 @@
*/
#include "aes.h"
#include "utils.h"
#include "constants.h"
#include "utils.h"
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16
};
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
static inline unsigned int rotword(unsigned int a)
{
return (((a) >> 24) | ((a) << 8));
}
static inline unsigned int rotword(unsigned int a) { return (((a) >> 24) | ((a) << 8)); }
#define subbyte(a, o) (sbox[((a) >> (o)) & 0xff] << (o))
#define subword(a) (subbyte(a, 24) | subbyte(a, 16) | subbyte(a, 8) | subbyte(a, 0))
int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k)
{
const unsigned int rconst[11] = {
0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
};
unsigned int i;
unsigned int t;
int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) {
const unsigned int rconst[11] = {0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000};
unsigned int i;
unsigned int t;
if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
} else if (k == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
} else if (k == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
}
for (i = 0; i < Nk; ++i) {
s->words[i] = (k[Nb * i] << 24) | (k[Nb * i + 1] << 16) | (k[Nb * i + 2] << 8) | (k[Nb * i + 3]);
}
for (; i < (Nb * (Nr + 1)); ++i) {
t = s->words[i - 1];
if ((i % Nk) == 0) {
t = subword(rotword(t)) ^ rconst[i / Nk];
}
s->words[i] = s->words[i - Nk] ^ t;
}
for (i = 0; i < Nk; ++i) {
s->words[i] = (k[Nb * i] << 24) | (k[Nb * i + 1] << 16) |
(k[Nb * i + 2] << 8) | (k[Nb * i + 3]);
}
for (; i < (Nb * (Nr + 1)); ++i) {
t = s->words[i - 1];
if ((i % Nk) == 0) {
t = subword(rotword(t)) ^ rconst[i / Nk];
}
s->words[i] = s->words[i - Nk] ^ t;
}
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
static inline void add_round_key(uint8_t *s, const unsigned int *k)
{
s[0] ^= (uint8_t)(k[0] >> 24);
s[1] ^= (uint8_t)(k[0] >> 16);
s[2] ^= (uint8_t)(k[0] >> 8);
s[3] ^= (uint8_t)(k[0]);
s[4] ^= (uint8_t)(k[1] >> 24);
s[5] ^= (uint8_t)(k[1] >> 16);
s[6] ^= (uint8_t)(k[1] >> 8);
s[7] ^= (uint8_t)(k[1]);
s[8] ^= (uint8_t)(k[2] >> 24);
s[9] ^= (uint8_t)(k[2] >> 16);
s[10] ^= (uint8_t)(k[2] >> 8);
s[11] ^= (uint8_t)(k[2]);
s[12] ^= (uint8_t)(k[3] >> 24);
s[13] ^= (uint8_t)(k[3] >> 16);
s[14] ^= (uint8_t)(k[3] >> 8);
s[15] ^= (uint8_t)(k[3]);
static inline void add_round_key(uint8_t *s, const unsigned int *k) {
s[0] ^= (uint8_t)(k[0] >> 24);
s[1] ^= (uint8_t)(k[0] >> 16);
s[2] ^= (uint8_t)(k[0] >> 8);
s[3] ^= (uint8_t)(k[0]);
s[4] ^= (uint8_t)(k[1] >> 24);
s[5] ^= (uint8_t)(k[1] >> 16);
s[6] ^= (uint8_t)(k[1] >> 8);
s[7] ^= (uint8_t)(k[1]);
s[8] ^= (uint8_t)(k[2] >> 24);
s[9] ^= (uint8_t)(k[2] >> 16);
s[10] ^= (uint8_t)(k[2] >> 8);
s[11] ^= (uint8_t)(k[2]);
s[12] ^= (uint8_t)(k[3] >> 24);
s[13] ^= (uint8_t)(k[3] >> 16);
s[14] ^= (uint8_t)(k[3] >> 8);
s[15] ^= (uint8_t)(k[3]);
}
static inline void sub_bytes(uint8_t *s)
{
unsigned int i;
static inline void sub_bytes(uint8_t *s) {
unsigned int i;
for (i = 0; i < (Nb * Nk); ++i) {
s[i] = sbox[s[i]];
}
for (i = 0; i < (Nb * Nk); ++i) {
s[i] = sbox[s[i]];
}
}
#define triple(a) (_double_byte(a) ^ (a))
static inline void mult_row_column(uint8_t *out, const uint8_t *in)
{
out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
static inline void mult_row_column(uint8_t *out, const uint8_t *in) {
out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
}
static inline void mix_columns(uint8_t *s)
{
uint8_t t[Nb * Nk];
static inline void mix_columns(uint8_t *s) {
uint8_t t[Nb * Nk];
mult_row_column(t, s);
mult_row_column(&t[Nb], s + Nb);
mult_row_column(&t[2 * Nb], s + (2 * Nb));
mult_row_column(&t[3 * Nb], s + (3 * Nb));
(void)_copy(s, sizeof(t), t, sizeof(t));
mult_row_column(t, s);
mult_row_column(&t[Nb], s + Nb);
mult_row_column(&t[2 * Nb], s + (2 * Nb));
mult_row_column(&t[3 * Nb], s + (3 * Nb));
(void)_copy(s, sizeof(t), t, sizeof(t));
}
/*
* This shift_rows also implements the matrix flip required for mix_columns, but
* performs it here to reduce the number of memory operations.
*/
static inline void shift_rows(uint8_t *s)
{
uint8_t t[Nb * Nk];
static inline void shift_rows(uint8_t *s) {
uint8_t t[Nb * Nk];
t[0] = s[0];
t[1] = s[5];
t[2] = s[10];
t[3] = s[15];
t[4] = s[4];
t[5] = s[9];
t[6] = s[14];
t[7] = s[3];
t[8] = s[8];
t[9] = s[13];
t[10] = s[2];
t[11] = s[7];
t[12] = s[12];
t[13] = s[1];
t[14] = s[6];
t[15] = s[11];
(void)_copy(s, sizeof(t), t, sizeof(t));
t[0] = s[0];
t[1] = s[5];
t[2] = s[10];
t[3] = s[15];
t[4] = s[4];
t[5] = s[9];
t[6] = s[14];
t[7] = s[3];
t[8] = s[8];
t[9] = s[13];
t[10] = s[2];
t[11] = s[7];
t[12] = s[12];
t[13] = s[1];
t[14] = s[6];
t[15] = s[11];
(void)_copy(s, sizeof(t), t, sizeof(t));
}
int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s)
{
uint8_t state[Nk * Nb];
unsigned int i;
int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) {
uint8_t state[Nk * Nb];
unsigned int i;
if (out == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (in == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
}
if (out == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (in == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (s == (TCAesKeySched_t)0) {
return TC_CRYPTO_FAIL;
}
(void)_copy(state, sizeof(state), in, sizeof(state));
add_round_key(state, s->words);
for (i = 0; i < (Nr - 1); ++i) {
sub_bytes(state);
shift_rows(state);
mix_columns(state);
add_round_key(state, s->words + Nb * (i + 1));
}
(void)_copy(state, sizeof(state), in, sizeof(state));
add_round_key(state, s->words);
for (i = 0; i < (Nr - 1); ++i) {
sub_bytes(state);
shift_rows(state);
mix_columns(state);
add_round_key(state, s->words + Nb * (i + 1));
}
(void)_copy(out, sizeof(state), state, sizeof(state));
sub_bytes(state);
shift_rows(state);
add_round_key(state, s->words + Nb * (i + 1));
/* zeroing out the state buffer */
_set(state, TC_ZERO_BYTE, sizeof(state));
(void)_copy(out, sizeof(state), state, sizeof(state));
return TC_CRYPTO_SUCCESS;
/* zeroing out the state buffer */
_set(state, TC_ZERO_BYTE, sizeof(state));
return TC_CRYPTO_SUCCESS;
}

View File

@@ -34,79 +34,60 @@
#include "constants.h"
#include "utils.h"
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched)
{
uint8_t buffer[TC_AES_BLOCK_SIZE];
unsigned int n, m;
int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in, unsigned int inlen, const uint8_t *iv, const TCAesKeySched_t sched) {
uint8_t buffer[TC_AES_BLOCK_SIZE];
unsigned int n, m;
/* input sanity check: */
if (out == (uint8_t *)0 ||
in == (const uint8_t *)0 ||
sched == (TCAesKeySched_t)0 ||
inlen == 0 ||
outlen == 0 ||
(inlen % TC_AES_BLOCK_SIZE) != 0 ||
(outlen % TC_AES_BLOCK_SIZE) != 0 ||
outlen != inlen + TC_AES_BLOCK_SIZE) {
return TC_CRYPTO_FAIL;
/* input sanity check: */
if (out == (uint8_t *)0 || in == (const uint8_t *)0 || sched == (TCAesKeySched_t)0 || inlen == 0 || outlen == 0 || (inlen % TC_AES_BLOCK_SIZE) != 0 || (outlen % TC_AES_BLOCK_SIZE) != 0 ||
outlen != inlen + TC_AES_BLOCK_SIZE) {
return TC_CRYPTO_FAIL;
}
/* copy iv to the buffer */
(void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
/* copy iv to the output buffer */
(void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
out += TC_AES_BLOCK_SIZE;
for (n = m = 0; n < inlen; ++n) {
buffer[m++] ^= *in++;
if (m == TC_AES_BLOCK_SIZE) {
(void)tc_aes_encrypt(buffer, buffer, sched);
(void)_copy(out, TC_AES_BLOCK_SIZE, buffer, TC_AES_BLOCK_SIZE);
out += TC_AES_BLOCK_SIZE;
m = 0;
}
}
/* copy iv to the buffer */
(void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
/* copy iv to the output buffer */
(void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE);
out += TC_AES_BLOCK_SIZE;
for (n = m = 0; n < inlen; ++n) {
buffer[m++] ^= *in++;
if (m == TC_AES_BLOCK_SIZE) {
(void)tc_aes_encrypt(buffer, buffer, sched);
(void)_copy(out, TC_AES_BLOCK_SIZE,
buffer, TC_AES_BLOCK_SIZE);
out += TC_AES_BLOCK_SIZE;
m = 0;
}
}
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, const uint8_t *iv,
const TCAesKeySched_t sched)
{
uint8_t buffer[TC_AES_BLOCK_SIZE];
const uint8_t *p;
unsigned int n, m;
int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in, unsigned int inlen, const uint8_t *iv, const TCAesKeySched_t sched) {
uint8_t buffer[TC_AES_BLOCK_SIZE];
const uint8_t *p;
unsigned int n, m;
/* sanity check the inputs */
if (out == (uint8_t *)0 ||
in == (const uint8_t *)0 ||
sched == (TCAesKeySched_t)0 ||
inlen == 0 ||
outlen == 0 ||
(inlen % TC_AES_BLOCK_SIZE) != 0 ||
(outlen % TC_AES_BLOCK_SIZE) != 0 ||
outlen != inlen) {
return TC_CRYPTO_FAIL;
/* sanity check the inputs */
if (out == (uint8_t *)0 || in == (const uint8_t *)0 || sched == (TCAesKeySched_t)0 || inlen == 0 || outlen == 0 || (inlen % TC_AES_BLOCK_SIZE) != 0 || (outlen % TC_AES_BLOCK_SIZE) != 0 ||
outlen != inlen) {
return TC_CRYPTO_FAIL;
}
/*
* Note that in == iv + ciphertext, i.e. the iv and the ciphertext are
* contiguous. This allows for a very efficient decryption algorithm
* that would not otherwise be possible.
*/
p = iv;
for (n = m = 0; n < outlen; ++n) {
if ((n % TC_AES_BLOCK_SIZE) == 0) {
(void)tc_aes_decrypt(buffer, in, sched);
in += TC_AES_BLOCK_SIZE;
m = 0;
}
*out++ = buffer[m++] ^ *p++;
}
/*
* Note that in == iv + ciphertext, i.e. the iv and the ciphertext are
* contiguous. This allows for a very efficient decryption algorithm
* that would not otherwise be possible.
*/
p = iv;
for (n = m = 0; n < outlen; ++n) {
if ((n % TC_AES_BLOCK_SIZE) == 0) {
(void)tc_aes_decrypt(buffer, in, sched);
in += TC_AES_BLOCK_SIZE;
m = 0;
}
*out++ = buffer[m++] ^ *p++;
}
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}

View File

@@ -36,50 +36,44 @@
#include <stdio.h>
int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce,
unsigned int nlen, unsigned int mlen)
{
/* input sanity check: */
if (c == (TCCcmMode_t)0 ||
sched == (TCAesKeySched_t)0 ||
nonce == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (nlen != 13) {
return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/
} else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) {
return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/
}
int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, unsigned int nlen, unsigned int mlen) {
/* input sanity check: */
if (c == (TCCcmMode_t)0 || sched == (TCAesKeySched_t)0 || nonce == (uint8_t *)0) {
return TC_CRYPTO_FAIL;
} else if (nlen != 13) {
return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/
} else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) {
return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/
}
c->mlen = mlen;
c->sched = sched;
c->nonce = nonce;
c->mlen = mlen;
c->sched = sched;
c->nonce = nonce;
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
/**
* Variation of CBC-MAC mode used in CCM.
*/
static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen,
unsigned int flag, TCAesKeySched_t sched)
{
unsigned int i;
static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen, unsigned int flag, TCAesKeySched_t sched) {
unsigned int i;
if (flag > 0) {
T[0] ^= (uint8_t)(dlen >> 8);
T[1] ^= (uint8_t)(dlen);
dlen += 2;
i = 2;
} else {
i = 0;
}
if (flag > 0) {
T[0] ^= (uint8_t)(dlen >> 8);
T[1] ^= (uint8_t)(dlen);
dlen += 2;
i = 2;
} else {
i = 0;
}
while (i < dlen) {
T[i++ % (Nb * Nk)] ^= *data++;
if (((i % (Nb * Nk)) == 0) || dlen == i) {
(void)tc_aes_encrypt(T, T, sched);
}
while (i < dlen) {
T[i++ % (Nb * Nk)] ^= *data++;
if (((i % (Nb * Nk)) == 0) || dlen == i) {
(void)tc_aes_encrypt(T, T, sched);
}
}
}
/**
@@ -89,175 +83,153 @@ static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen,
* encryption). Besides, it is assumed that the counter is stored in the last
* 2 bytes of the nonce.
*/
static int ccm_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
{
uint8_t buffer[TC_AES_BLOCK_SIZE];
uint8_t nonce[TC_AES_BLOCK_SIZE];
uint16_t block_num;
unsigned int i;
static int ccm_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in, unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched) {
uint8_t buffer[TC_AES_BLOCK_SIZE];
uint8_t nonce[TC_AES_BLOCK_SIZE];
uint16_t block_num;
unsigned int i;
/* input sanity check: */
if (out == (uint8_t *)0 ||
in == (uint8_t *)0 ||
ctr == (uint8_t *)0 ||
sched == (TCAesKeySched_t)0 ||
inlen == 0 ||
outlen == 0 ||
outlen != inlen) {
/* input sanity check: */
if (out == (uint8_t *)0 || in == (uint8_t *)0 || ctr == (uint8_t *)0 || sched == (TCAesKeySched_t)0 || inlen == 0 || outlen == 0 || outlen != inlen) {
return TC_CRYPTO_FAIL;
}
/* copy the counter to the nonce */
(void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
/* select the last 2 bytes of the nonce to be incremented */
block_num = (uint16_t)((nonce[14] << 8) | (nonce[15]));
for (i = 0; i < inlen; ++i) {
if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
block_num++;
nonce[14] = (uint8_t)(block_num >> 8);
nonce[15] = (uint8_t)(block_num);
if (!tc_aes_encrypt(buffer, nonce, sched)) {
return TC_CRYPTO_FAIL;
}
}
/* update the output */
*out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
}
/* copy the counter to the nonce */
(void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
/* update the counter */
ctr[14] = nonce[14];
ctr[15] = nonce[15];
/* select the last 2 bytes of the nonce to be incremented */
block_num = (uint16_t)((nonce[14] << 8) | (nonce[15]));
for (i = 0; i < inlen; ++i) {
if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
block_num++;
nonce[14] = (uint8_t)(block_num >> 8);
nonce[15] = (uint8_t)(block_num);
if (!tc_aes_encrypt(buffer, nonce, sched)) {
return TC_CRYPTO_FAIL;
}
}
/* update the output */
*out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
}
return TC_CRYPTO_SUCCESS;
}
/* update the counter */
ctr[14] = nonce[14];
ctr[15] = nonce[15];
int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen, const uint8_t *associated_data, unsigned int alen, const uint8_t *payload, unsigned int plen, TCCcmMode_t c) {
/* input sanity check: */
if ((out == (uint8_t *)0) || (c == (TCCcmMode_t)0) || ((plen > 0) && (payload == (uint8_t *)0)) || ((alen > 0) && (associated_data == (uint8_t *)0)) ||
(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
(olen < (plen + c->mlen))) { /* invalid output buffer size */
return TC_CRYPTO_FAIL;
}
uint8_t b[Nb * Nk];
uint8_t tag[Nb * Nk];
unsigned int i;
/* GENERATING THE AUTHENTICATION TAG: */
/* formatting the sequence b for authentication: */
b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
for (i = 1; i <= 13; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = (uint8_t)(plen >> 8);
b[15] = (uint8_t)(plen);
/* computing the authentication tag using cbc-mac: */
(void)tc_aes_encrypt(tag, b, c->sched);
if (alen > 0) {
ccm_cbc_mac(tag, associated_data, alen, 1, c->sched);
}
if (plen > 0) {
ccm_cbc_mac(tag, payload, plen, 0, c->sched);
}
/* ENCRYPTION: */
/* formatting the sequence b for encryption: */
b[0] = 1; /* q - 1 = 2 - 1 = 1 */
b[14] = b[15] = TC_ZERO_BYTE;
/* encrypting payload using ctr mode: */
ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/
/* encrypting b and adding the tag to the output: */
(void)tc_aes_encrypt(b, b, c->sched);
out += plen;
for (i = 0; i < c->mlen; ++i) {
*out++ = tag[i] ^ b[i];
}
return TC_CRYPTO_SUCCESS;
}
int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen, const uint8_t *associated_data, unsigned int alen, const uint8_t *payload, unsigned int plen, TCCcmMode_t c) {
/* input sanity check: */
if ((out == (uint8_t *)0) || (c == (TCCcmMode_t)0) || ((plen > 0) && (payload == (uint8_t *)0)) || ((alen > 0) && (associated_data == (uint8_t *)0)) ||
(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
(olen < plen - c->mlen)) { /* invalid output buffer size */
return TC_CRYPTO_FAIL;
}
uint8_t b[Nb * Nk];
uint8_t tag[Nb * Nk];
unsigned int i;
/* DECRYPTION: */
/* formatting the sequence b for decryption: */
b[0] = 1; /* q - 1 = 2 - 1 = 1 */
for (i = 1; i < 14; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */
/* decrypting payload using ctr mode: */
ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);
b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */
/* encrypting b and restoring the tag from input: */
(void)tc_aes_encrypt(b, b, c->sched);
for (i = 0; i < c->mlen; ++i) {
tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
}
/* VERIFYING THE AUTHENTICATION TAG: */
/* formatting the sequence b for authentication: */
b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
for (i = 1; i < 14; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = (uint8_t)((plen - c->mlen) >> 8);
b[15] = (uint8_t)(plen - c->mlen);
/* computing the authentication tag using cbc-mac: */
(void)tc_aes_encrypt(b, b, c->sched);
if (alen > 0) {
ccm_cbc_mac(b, associated_data, alen, 1, c->sched);
}
if (plen > 0) {
ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched);
}
/* comparing the received tag and the computed one: */
if (_compare(b, tag, c->mlen) == 0) {
return TC_CRYPTO_SUCCESS;
}
int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen,
const uint8_t *associated_data,
unsigned int alen, const uint8_t *payload,
unsigned int plen, TCCcmMode_t c)
{
/* input sanity check: */
if ((out == (uint8_t *)0) ||
(c == (TCCcmMode_t)0) ||
((plen > 0) && (payload == (uint8_t *)0)) ||
((alen > 0) && (associated_data == (uint8_t *)0)) ||
(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
(olen < (plen + c->mlen))) { /* invalid output buffer size */
return TC_CRYPTO_FAIL;
}
uint8_t b[Nb * Nk];
uint8_t tag[Nb * Nk];
unsigned int i;
/* GENERATING THE AUTHENTICATION TAG: */
/* formatting the sequence b for authentication: */
b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
for (i = 1; i <= 13; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = (uint8_t)(plen >> 8);
b[15] = (uint8_t)(plen);
/* computing the authentication tag using cbc-mac: */
(void)tc_aes_encrypt(tag, b, c->sched);
if (alen > 0) {
ccm_cbc_mac(tag, associated_data, alen, 1, c->sched);
}
if (plen > 0) {
ccm_cbc_mac(tag, payload, plen, 0, c->sched);
}
/* ENCRYPTION: */
/* formatting the sequence b for encryption: */
b[0] = 1; /* q - 1 = 2 - 1 = 1 */
b[14] = b[15] = TC_ZERO_BYTE;
/* encrypting payload using ctr mode: */
ccm_ctr_mode(out, plen, payload, plen, b, c->sched);
b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/
/* encrypting b and adding the tag to the output: */
(void)tc_aes_encrypt(b, b, c->sched);
out += plen;
for (i = 0; i < c->mlen; ++i) {
*out++ = tag[i] ^ b[i];
}
return TC_CRYPTO_SUCCESS;
}
int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen,
const uint8_t *associated_data,
unsigned int alen, const uint8_t *payload,
unsigned int plen, TCCcmMode_t c)
{
/* input sanity check: */
if ((out == (uint8_t *)0) ||
(c == (TCCcmMode_t)0) ||
((plen > 0) && (payload == (uint8_t *)0)) ||
((alen > 0) && (associated_data == (uint8_t *)0)) ||
(alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */
(plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */
(olen < plen - c->mlen)) { /* invalid output buffer size */
return TC_CRYPTO_FAIL;
}
uint8_t b[Nb * Nk];
uint8_t tag[Nb * Nk];
unsigned int i;
/* DECRYPTION: */
/* formatting the sequence b for decryption: */
b[0] = 1; /* q - 1 = 2 - 1 = 1 */
for (i = 1; i < 14; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */
/* decrypting payload using ctr mode: */
ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched);
b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */
/* encrypting b and restoring the tag from input: */
(void)tc_aes_encrypt(b, b, c->sched);
for (i = 0; i < c->mlen; ++i) {
tag[i] = *(payload + plen - c->mlen + i) ^ b[i];
}
/* VERIFYING THE AUTHENTICATION TAG: */
/* formatting the sequence b for authentication: */
b[0] = ((alen > 0) ? 0x40 : 0) | (((c->mlen - 2) / 2 << 3)) | (1);
for (i = 1; i < 14; ++i) {
b[i] = c->nonce[i - 1];
}
b[14] = (uint8_t)((plen - c->mlen) >> 8);
b[15] = (uint8_t)(plen - c->mlen);
/* computing the authentication tag using cbc-mac: */
(void)tc_aes_encrypt(b, b, c->sched);
if (alen > 0) {
ccm_cbc_mac(b, associated_data, alen, 1, c->sched);
}
if (plen > 0) {
ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched);
}
/* comparing the received tag and the computed one: */
if (_compare(b, tag, c->mlen) == 0) {
return TC_CRYPTO_SUCCESS;
} else {
/* erase the decrypted buffer in case of mac validation failure: */
_set(out, 0, plen - c->mlen);
return TC_CRYPTO_FAIL;
}
} else {
/* erase the decrypted buffer in case of mac validation failure: */
_set(out, 0, plen - c->mlen);
return TC_CRYPTO_FAIL;
}
}

View File

@@ -30,8 +30,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "aes.h"
#include "cmac_mode.h"
#include "aes.h"
#include "constants.h"
#include "utils.h"
@@ -75,178 +75,167 @@ const unsigned char gf_wrap = 0x87;
* effects: doubles the GF(2^n) value pointed to by "in" and places
* the result in the GF(2^n) value pointed to by "out."
*/
void gf_double(uint8_t *out, uint8_t *in)
{
/* start with low order byte */
uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
void gf_double(uint8_t *out, uint8_t *in) {
/* start with low order byte */
uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
/* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
/* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
out += (TC_AES_BLOCK_SIZE - 1);
for (;;) {
*out-- = (*x << 1) ^ carry;
if (x == in) {
break;
}
carry = *x-- >> 7;
out += (TC_AES_BLOCK_SIZE - 1);
for (;;) {
*out-- = (*x << 1) ^ carry;
if (x == in) {
break;
}
carry = *x-- >> 7;
}
}
int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched)
{
/* input sanity check: */
if (s == (TCCmacState_t)0 ||
key == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
}
int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched) {
/* input sanity check: */
if (s == (TCCmacState_t)0 || key == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
}
/* put s into a known state */
_set(s, 0, sizeof(*s));
s->sched = sched;
/* put s into a known state */
_set(s, 0, sizeof(*s));
s->sched = sched;
/* configure the encryption key used by the underlying block cipher */
tc_aes128_set_encrypt_key(s->sched, key);
/* configure the encryption key used by the underlying block cipher */
tc_aes128_set_encrypt_key(s->sched, key);
/* compute s->K1 and s->K2 from s->iv using s->keyid */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
tc_aes_encrypt(s->iv, s->iv, s->sched);
gf_double(s->K1, s->iv);
gf_double(s->K2, s->K1);
/* compute s->K1 and s->K2 from s->iv using s->keyid */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
tc_aes_encrypt(s->iv, s->iv, s->sched);
gf_double(s->K1, s->iv);
gf_double(s->K2, s->K1);
/* reset s->iv to 0 in case someone wants to compute now */
tc_cmac_init(s);
/* reset s->iv to 0 in case someone wants to compute now */
tc_cmac_init(s);
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_erase(TCCmacState_t s) {
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
/* destroy the current state */
_set(s, 0, sizeof(*s));
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_init(TCCmacState_t s) {
/* input sanity check: */
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
/* CMAC starts with an all zero initialization vector */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
/* and the leftover buffer is empty */
_set(s->leftover, 0, TC_AES_BLOCK_SIZE);
s->leftover_offset = 0;
/* Set countdown to max number of calls allowed before re-keying: */
s->countdown = MAX_CALLS;
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) {
unsigned int i;
/* input sanity check: */
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
if (data_length == 0) {
return TC_CRYPTO_SUCCESS;
}
}
if (data == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
}
int tc_cmac_erase(TCCmacState_t s)
{
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
if (s->countdown == 0) {
return TC_CRYPTO_FAIL;
}
s->countdown--;
if (s->leftover_offset > 0) {
/* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
if (data_length < remaining_space) {
/* still not enough data to encrypt this time either */
_copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
s->leftover_offset += data_length;
return TC_CRYPTO_SUCCESS;
}
/* destroy the current state */
_set(s, 0, sizeof(*s));
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_init(TCCmacState_t s)
{
/* input sanity check: */
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
/* CMAC starts with an all zero initialization vector */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
/* and the leftover buffer is empty */
_set(s->leftover, 0, TC_AES_BLOCK_SIZE);
/* leftover block is now full; encrypt it first */
_copy(&s->leftover[s->leftover_offset], remaining_space, data, remaining_space);
data_length -= remaining_space;
data += remaining_space;
s->leftover_offset = 0;
/* Set countdown to max number of calls allowed before re-keying: */
s->countdown = MAX_CALLS;
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length)
{
unsigned int i;
/* input sanity check: */
if (s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
if (data_length == 0) {
return TC_CRYPTO_SUCCESS;
}
if (data == (const uint8_t *)0) {
return TC_CRYPTO_FAIL;
}
if (s->countdown == 0) {
return TC_CRYPTO_FAIL;
}
s->countdown--;
if (s->leftover_offset > 0) {
/* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
if (data_length < remaining_space) {
/* still not enough data to encrypt this time either */
_copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
s->leftover_offset += data_length;
return TC_CRYPTO_SUCCESS;
}
/* leftover block is now full; encrypt it first */
_copy(&s->leftover[s->leftover_offset],
remaining_space,
data,
remaining_space);
data_length -= remaining_space;
data += remaining_space;
s->leftover_offset = 0;
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= s->leftover[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
}
/* CBC encrypt each (except the last) of the data blocks */
while (data_length > TC_AES_BLOCK_SIZE) {
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= data[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
data += TC_AES_BLOCK_SIZE;
data_length -= TC_AES_BLOCK_SIZE;
}
if (data_length > 0) {
/* save leftover data for next time */
_copy(s->leftover, data_length, data, data_length);
s->leftover_offset = data_length;
}
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_final(uint8_t *tag, TCCmacState_t s)
{
uint8_t *k;
unsigned int i;
/* input sanity check: */
if (tag == (uint8_t *)0 ||
s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
if (s->leftover_offset == TC_AES_BLOCK_SIZE) {
/* the last message block is a full-sized block */
k = (uint8_t *)s->K1;
} else {
/* the final message block is not a full-sized block */
size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
_set(&s->leftover[s->leftover_offset], 0, remaining);
s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
k = (uint8_t *)s->K2;
}
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= s->leftover[i] ^ k[i];
s->iv[i] ^= s->leftover[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
}
tc_aes_encrypt(tag, s->iv, s->sched);
/* CBC encrypt each (except the last) of the data blocks */
while (data_length > TC_AES_BLOCK_SIZE) {
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= data[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
data += TC_AES_BLOCK_SIZE;
data_length -= TC_AES_BLOCK_SIZE;
}
/* erasing state: */
tc_cmac_erase(s);
if (data_length > 0) {
/* save leftover data for next time */
_copy(s->leftover, data_length, data, data_length);
s->leftover_offset = data_length;
}
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_final(uint8_t *tag, TCCmacState_t s) {
uint8_t *k;
unsigned int i;
/* input sanity check: */
if (tag == (uint8_t *)0 || s == (TCCmacState_t)0) {
return TC_CRYPTO_FAIL;
}
if (s->leftover_offset == TC_AES_BLOCK_SIZE) {
/* the last message block is a full-sized block */
k = (uint8_t *)s->K1;
} else {
/* the final message block is not a full-sized block */
size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
_set(&s->leftover[s->leftover_offset], 0, remaining);
s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
k = (uint8_t *)s->K2;
}
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= s->leftover[i] ^ k[i];
}
tc_aes_encrypt(tag, s->iv, s->sched);
/* erasing state: */
tc_cmac_erase(s);
return TC_CRYPTO_SUCCESS;
}

View File

@@ -30,57 +30,48 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "constants.h"
#include "ctr_mode.h"
#include "constants.h"
#include "utils.h"
int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in,
unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched)
{
uint8_t buffer[TC_AES_BLOCK_SIZE];
uint8_t nonce[TC_AES_BLOCK_SIZE];
unsigned int block_num;
unsigned int i;
int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in, unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched) {
uint8_t buffer[TC_AES_BLOCK_SIZE];
uint8_t nonce[TC_AES_BLOCK_SIZE];
unsigned int block_num;
unsigned int i;
/* input sanity check: */
if (out == (uint8_t *)0 ||
in == (uint8_t *)0 ||
ctr == (uint8_t *)0 ||
sched == (TCAesKeySched_t)0 ||
inlen == 0 ||
outlen == 0 ||
outlen != inlen) {
/* input sanity check: */
if (out == (uint8_t *)0 || in == (uint8_t *)0 || ctr == (uint8_t *)0 || sched == (TCAesKeySched_t)0 || inlen == 0 || outlen == 0 || outlen != inlen) {
return TC_CRYPTO_FAIL;
}
/* copy the ctr to the nonce */
(void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
/* select the last 4 bytes of the nonce to be incremented */
block_num = (nonce[12] << 24) | (nonce[13] << 16) | (nonce[14] << 8) | (nonce[15]);
for (i = 0; i < inlen; ++i) {
if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
/* encrypt data using the current nonce */
if (tc_aes_encrypt(buffer, nonce, sched)) {
block_num++;
nonce[12] = (uint8_t)(block_num >> 24);
nonce[13] = (uint8_t)(block_num >> 16);
nonce[14] = (uint8_t)(block_num >> 8);
nonce[15] = (uint8_t)(block_num);
} else {
return TC_CRYPTO_FAIL;
}
}
/* update the output */
*out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
}
/* copy the ctr to the nonce */
(void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce));
/* update the counter */
ctr[12] = nonce[12];
ctr[13] = nonce[13];
ctr[14] = nonce[14];
ctr[15] = nonce[15];
/* select the last 4 bytes of the nonce to be incremented */
block_num = (nonce[12] << 24) | (nonce[13] << 16) |
(nonce[14] << 8) | (nonce[15]);
for (i = 0; i < inlen; ++i) {
if ((i % (TC_AES_BLOCK_SIZE)) == 0) {
/* encrypt data using the current nonce */
if (tc_aes_encrypt(buffer, nonce, sched)) {
block_num++;
nonce[12] = (uint8_t)(block_num >> 24);
nonce[13] = (uint8_t)(block_num >> 16);
nonce[14] = (uint8_t)(block_num >> 8);
nonce[15] = (uint8_t)(block_num);
} else {
return TC_CRYPTO_FAIL;
}
}
/* update the output */
*out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++;
}
/* update the counter */
ctr[12] = nonce[12];
ctr[13] = nonce[13];
ctr[14] = nonce[14];
ctr[15] = nonce[15];
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}

View File

@@ -28,8 +28,8 @@
*/
#include "ctr_prng.h"
#include "utils.h"
#include "constants.h"
#include "utils.h"
#include <string.h>
/*
@@ -50,16 +50,15 @@
* @param arr IN/OUT -- array to be incremented
* @param len IN -- size of arr in bytes
*/
static void arrInc(uint8_t arr[], unsigned int len)
{
unsigned int i;
if (0 != arr) {
for (i = len; i > 0U; i--) {
if (++arr[i - 1] != 0U) {
break;
}
}
static void arrInc(uint8_t arr[], unsigned int len) {
unsigned int i;
if (0 != arr) {
for (i = len; i > 0U; i--) {
if (++arr[i - 1] != 0U) {
break;
}
}
}
}
/**
@@ -71,209 +70,192 @@ static void arrInc(uint8_t arr[], unsigned int len)
* @param ctx IN/OUT -- CTR PRNG state
* @param providedData IN -- data used when updating the internal state
*/
static void tc_ctr_prng_update(TCCtrPrng_t *const ctx, uint8_t const *const providedData)
{
if (0 != ctx) {
/* 10.2.1.2 step 1 */
uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
unsigned int len = 0U;
static void tc_ctr_prng_update(TCCtrPrng_t *const ctx, uint8_t const *const providedData) {
if (0 != ctx) {
/* 10.2.1.2 step 1 */
uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
unsigned int len = 0U;
/* 10.2.1.2 step 2 */
while (len < sizeof temp) {
unsigned int blocklen = sizeof(temp) - len;
uint8_t output_block[TC_AES_BLOCK_SIZE];
/* 10.2.1.2 step 2 */
while (len < sizeof temp) {
unsigned int blocklen = sizeof(temp) - len;
uint8_t output_block[TC_AES_BLOCK_SIZE];
/* 10.2.1.2 step 2.1 */
arrInc(ctx->V, sizeof ctx->V);
/* 10.2.1.2 step 2.1 */
arrInc(ctx->V, sizeof ctx->V);
/* 10.2.1.2 step 2.2 */
if (blocklen > TC_AES_BLOCK_SIZE) {
blocklen = TC_AES_BLOCK_SIZE;
}
(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
/* 10.2.1.2 step 2.2 */
if (blocklen > TC_AES_BLOCK_SIZE) {
blocklen = TC_AES_BLOCK_SIZE;
}
(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
/* 10.2.1.2 step 2.3/step 3 */
memcpy(&(temp[len]), output_block, blocklen);
/* 10.2.1.2 step 2.3/step 3 */
memcpy(&(temp[len]), output_block, blocklen);
len += blocklen;
}
/* 10.2.1.2 step 4 */
if (0 != providedData) {
unsigned int i;
for (i = 0U; i < sizeof temp; i++) {
temp[i] ^= providedData[i];
}
}
/* 10.2.1.2 step 5 */
(void)tc_aes128_set_encrypt_key(&ctx->key, temp);
/* 10.2.1.2 step 6 */
memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE);
len += blocklen;
}
/* 10.2.1.2 step 4 */
if (0 != providedData) {
unsigned int i;
for (i = 0U; i < sizeof temp; i++) {
temp[i] ^= providedData[i];
}
}
/* 10.2.1.2 step 5 */
(void)tc_aes128_set_encrypt_key(&ctx->key, temp);
/* 10.2.1.2 step 6 */
memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE);
}
}
int tc_ctr_prng_init(TCCtrPrng_t *const ctx,
uint8_t const *const entropy,
unsigned int entropyLen,
uint8_t const *const personalization,
unsigned int pLen)
{
int result = TC_CRYPTO_FAIL;
unsigned int i;
uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = { 0U };
uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
uint8_t zeroArr[TC_AES_BLOCK_SIZE] = { 0U };
int tc_ctr_prng_init(TCCtrPrng_t *const ctx, uint8_t const *const entropy, unsigned int entropyLen, uint8_t const *const personalization, unsigned int pLen) {
int result = TC_CRYPTO_FAIL;
unsigned int i;
uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U};
if (0 != personalization) {
/* 10.2.1.3.1 step 1 */
unsigned int len = pLen;
if (len > sizeof personalization_buf) {
len = sizeof personalization_buf;
}
/* 10.2.1.3.1 step 2 */
memcpy(personalization_buf, personalization, len);
if (0 != personalization) {
/* 10.2.1.3.1 step 1 */
unsigned int len = pLen;
if (len > sizeof personalization_buf) {
len = sizeof personalization_buf;
}
if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) {
/* 10.2.1.3.1 step 3 */
memcpy(seed_material, entropy, sizeof seed_material);
for (i = 0U; i < sizeof seed_material; i++) {
seed_material[i] ^= personalization_buf[i];
}
/* 10.2.1.3.1 step 2 */
memcpy(personalization_buf, personalization, len);
}
/* 10.2.1.3.1 step 4 */
(void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr);
/* 10.2.1.3.1 step 5 */
memset(ctx->V, 0x00, sizeof ctx->V);
/* 10.2.1.3.1 step 6 */
tc_ctr_prng_update(ctx, seed_material);
/* 10.2.1.3.1 step 7 */
ctx->reseedCount = 1U;
result = TC_CRYPTO_SUCCESS;
if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) {
/* 10.2.1.3.1 step 3 */
memcpy(seed_material, entropy, sizeof seed_material);
for (i = 0U; i < sizeof seed_material; i++) {
seed_material[i] ^= personalization_buf[i];
}
return result;
/* 10.2.1.3.1 step 4 */
(void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr);
/* 10.2.1.3.1 step 5 */
memset(ctx->V, 0x00, sizeof ctx->V);
/* 10.2.1.3.1 step 6 */
tc_ctr_prng_update(ctx, seed_material);
/* 10.2.1.3.1 step 7 */
ctx->reseedCount = 1U;
result = TC_CRYPTO_SUCCESS;
}
return result;
}
int tc_ctr_prng_reseed(TCCtrPrng_t *const ctx,
uint8_t const *const entropy,
unsigned int entropyLen,
uint8_t const *const additional_input,
unsigned int additionallen)
{
unsigned int i;
int result = TC_CRYPTO_FAIL;
uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = { 0U };
uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
int tc_ctr_prng_reseed(TCCtrPrng_t *const ctx, uint8_t const *const entropy, unsigned int entropyLen, uint8_t const *const additional_input, unsigned int additionallen) {
unsigned int i;
int result = TC_CRYPTO_FAIL;
uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE];
if (0 != additional_input) {
/* 10.2.1.4.1 step 1 */
if (0 != additional_input) {
/* 10.2.1.4.1 step 1 */
unsigned int len = additionallen;
if (len > sizeof additional_input_buf) {
len = sizeof additional_input_buf;
}
/* 10.2.1.4.1 step 2 */
memcpy(additional_input_buf, additional_input, len);
}
unsigned int seedlen = (unsigned int)TC_AES_KEY_SIZE + (unsigned int)TC_AES_BLOCK_SIZE;
if ((0 != ctx) && (entropyLen >= seedlen)) {
/* 10.2.1.4.1 step 3 */
memcpy(seed_material, entropy, sizeof seed_material);
for (i = 0U; i < sizeof seed_material; i++) {
seed_material[i] ^= additional_input_buf[i];
}
/* 10.2.1.4.1 step 4 */
tc_ctr_prng_update(ctx, seed_material);
/* 10.2.1.4.1 step 5 */
ctx->reseedCount = 1U;
result = TC_CRYPTO_SUCCESS;
}
return result;
}
int tc_ctr_prng_generate(TCCtrPrng_t *const ctx, uint8_t const *const additional_input, unsigned int additionallen, uint8_t *const out, unsigned int outlen) {
/* 2^48 - see section 10.2.1 */
static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL;
/* 2^19 bits - see section 10.2.1 */
static const unsigned int MAX_BYTES_PER_REQ = 65536U;
unsigned int result = TC_CRYPTO_FAIL;
if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) {
/* 10.2.1.5.1 step 1 */
if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) {
result = TC_CTR_PRNG_RESEED_REQ;
} else {
uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U};
if (0 != additional_input) {
/* 10.2.1.5.1 step 2 */
unsigned int len = additionallen;
if (len > sizeof additional_input_buf) {
len = sizeof additional_input_buf;
len = sizeof additional_input_buf;
}
/* 10.2.1.4.1 step 2 */
memcpy(additional_input_buf, additional_input, len);
}
tc_ctr_prng_update(ctx, additional_input_buf);
}
unsigned int seedlen = (unsigned int)TC_AES_KEY_SIZE + (unsigned int)TC_AES_BLOCK_SIZE;
if ((0 != ctx) && (entropyLen >= seedlen)) {
/* 10.2.1.4.1 step 3 */
memcpy(seed_material, entropy, sizeof seed_material);
for (i = 0U; i < sizeof seed_material; i++) {
seed_material[i] ^= additional_input_buf[i];
/* 10.2.1.5.1 step 3 - implicit */
/* 10.2.1.5.1 step 4 */
unsigned int len = 0U;
while (len < outlen) {
unsigned int blocklen = outlen - len;
uint8_t output_block[TC_AES_BLOCK_SIZE];
/* 10.2.1.5.1 step 4.1 */
arrInc(ctx->V, sizeof ctx->V);
/* 10.2.1.5.1 step 4.2 */
(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
/* 10.2.1.5.1 step 4.3/step 5 */
if (blocklen > TC_AES_BLOCK_SIZE) {
blocklen = TC_AES_BLOCK_SIZE;
}
memcpy(&(out[len]), output_block, blocklen);
/* 10.2.1.4.1 step 4 */
tc_ctr_prng_update(ctx, seed_material);
len += blocklen;
}
/* 10.2.1.4.1 step 5 */
ctx->reseedCount = 1U;
/* 10.2.1.5.1 step 6 */
tc_ctr_prng_update(ctx, additional_input_buf);
result = TC_CRYPTO_SUCCESS;
/* 10.2.1.5.1 step 7 */
ctx->reseedCount++;
/* 10.2.1.5.1 step 8 */
result = TC_CRYPTO_SUCCESS;
}
return result;
}
return result;
}
int tc_ctr_prng_generate(TCCtrPrng_t *const ctx,
uint8_t const *const additional_input,
unsigned int additionallen,
uint8_t *const out,
unsigned int outlen)
{
/* 2^48 - see section 10.2.1 */
static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL;
/* 2^19 bits - see section 10.2.1 */
static const unsigned int MAX_BYTES_PER_REQ = 65536U;
unsigned int result = TC_CRYPTO_FAIL;
if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) {
/* 10.2.1.5.1 step 1 */
if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) {
result = TC_CTR_PRNG_RESEED_REQ;
} else {
uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = { 0U };
if (0 != additional_input) {
/* 10.2.1.5.1 step 2 */
unsigned int len = additionallen;
if (len > sizeof additional_input_buf) {
len = sizeof additional_input_buf;
}
memcpy(additional_input_buf, additional_input, len);
tc_ctr_prng_update(ctx, additional_input_buf);
}
/* 10.2.1.5.1 step 3 - implicit */
/* 10.2.1.5.1 step 4 */
unsigned int len = 0U;
while (len < outlen) {
unsigned int blocklen = outlen - len;
uint8_t output_block[TC_AES_BLOCK_SIZE];
/* 10.2.1.5.1 step 4.1 */
arrInc(ctx->V, sizeof ctx->V);
/* 10.2.1.5.1 step 4.2 */
(void)tc_aes_encrypt(output_block, ctx->V, &ctx->key);
/* 10.2.1.5.1 step 4.3/step 5 */
if (blocklen > TC_AES_BLOCK_SIZE) {
blocklen = TC_AES_BLOCK_SIZE;
}
memcpy(&(out[len]), output_block, blocklen);
len += blocklen;
}
/* 10.2.1.5.1 step 6 */
tc_ctr_prng_update(ctx, additional_input_buf);
/* 10.2.1.5.1 step 7 */
ctx->reseedCount++;
/* 10.2.1.5.1 step 8 */
result = TC_CRYPTO_SUCCESS;
}
}
return result;
}
void tc_ctr_prng_uninstantiate(TCCtrPrng_t *const ctx)
{
if (0 != ctx) {
memset(ctx->key.words, 0x00, sizeof ctx->key.words);
memset(ctx->V, 0x00, sizeof ctx->V);
ctx->reseedCount = 0U;
}
void tc_ctr_prng_uninstantiate(TCCtrPrng_t *const ctx) {
if (0 != ctx) {
memset(ctx->key.words, 0x00, sizeof ctx->key.words);
memset(ctx->V, 0x00, sizeof ctx->V);
ctx->reseedCount = 0U;
}
}

View File

@@ -1,6 +1,6 @@
/* ec_dh.c - TinyCrypt implementation of EC-DH */
/*
/*
* Copyright (c) 2014, Kenneth MacKay
* All rights reserved.
*
@@ -54,9 +54,9 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ecc_dh.h"
#include "constants.h"
#include "ecc.h"
#include "ecc_dh.h"
#if defined(BFLB_BLE)
#include "utils.h"
#endif
@@ -71,128 +71,103 @@ static uECC_RNG_Function g_rng_function = &default_CSPRNG;
static uECC_RNG_Function g_rng_function = 0;
#endif
int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key,
unsigned int *d, uECC_Curve curve)
{
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key, unsigned int *d, uECC_Curve curve) {
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
/* This function is designed for test purposes-only (such as validating NIST
* test vectors) as it uses a provided value for d instead of generating
* it uniformly at random. */
memcpy(_private, d, NUM_ECC_BYTES);
/* This function is designed for test purposes-only (such as validating NIST
* test vectors) as it uses a provided value for d instead of generating
* it uniformly at random. */
memcpy(_private, d, NUM_ECC_BYTES);
/* Computing public-key from private: */
if (EccPoint_compute_public_key(_public, _private, curve)) {
/* Converting buffers to correct bit order: */
uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), _private);
uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words);
/* erasing temporary buffer used to store secret: */
_set_secure(_private, 0, NUM_ECC_BYTES);
return 1;
}
return 0;
}
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve) {
uECC_word_t _random[NUM_ECC_WORDS * 2];
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t tries;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
/* Generating _private uniformly at random: */
uECC_RNG_Function rng_function = uECC_get_rng();
if (!rng_function || !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
return 0;
}
/* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
/* Computing public-key from private: */
if (EccPoint_compute_public_key(_public, _private, curve)) {
/* Converting buffers to correct bit order: */
uECC_vli_nativeToBytes(private_key,
BITS_TO_BYTES(curve->num_n_bits),
_private);
uECC_vli_nativeToBytes(public_key,
curve->num_bytes,
_public);
uECC_vli_nativeToBytes(public_key + curve->num_bytes,
curve->num_bytes,
_public + curve->num_words);
/* Converting buffers to correct bit order: */
uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), _private);
uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words);
/* erasing temporary buffer used to store secret: */
_set_secure(_private, 0, NUM_ECC_BYTES);
/* erasing temporary buffer that stored secret: */
_set_secure(_private, 0, NUM_ECC_BYTES);
return 1;
return 1;
}
return 0;
}
return 0;
}
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve)
{
uECC_word_t _random[NUM_ECC_WORDS * 2];
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t tries;
int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key, uint8_t *secret, uECC_Curve curve) {
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t _private[NUM_ECC_WORDS];
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
/* Generating _private uniformly at random: */
uECC_RNG_Function rng_function = uECC_get_rng();
if (!rng_function ||
!rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
return 0;
}
uECC_word_t tmp[NUM_ECC_WORDS];
uECC_word_t *p2[2] = {_private, tmp};
uECC_word_t *initial_Z = 0;
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
wordcount_t num_bytes = curve->num_bytes;
int r;
/* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
/* Converting buffers to correct bit order: */
uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits));
uECC_vli_bytesToNative(_public, public_key, num_bytes);
uECC_vli_bytesToNative(_public + num_words, public_key + num_bytes, num_bytes);
/* Computing public-key from private: */
if (EccPoint_compute_public_key(_public, _private, curve)) {
/* Converting buffers to correct bit order: */
uECC_vli_nativeToBytes(private_key,
BITS_TO_BYTES(curve->num_n_bits),
_private);
uECC_vli_nativeToBytes(public_key,
curve->num_bytes,
_public);
uECC_vli_nativeToBytes(public_key + curve->num_bytes,
curve->num_bytes,
_public + curve->num_words);
/* Regularize the bitcount for the private key so that attackers cannot use a
* side channel attack to learn the number of leading zeros. */
carry = regularize_k(_private, _private, tmp, curve);
/* erasing temporary buffer that stored secret: */
_set_secure(_private, 0, NUM_ECC_BYTES);
return 1;
}
/* If an RNG function was specified, try to get a random initial Z value to
* improve protection against side-channel attacks. */
if (g_rng_function) {
if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
r = 0;
goto clear_and_out;
}
return 0;
}
initial_Z = p2[carry];
}
int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
uint8_t *secret, uECC_Curve curve)
{
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t _private[NUM_ECC_WORDS];
EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
uECC_word_t tmp[NUM_ECC_WORDS];
uECC_word_t *p2[2] = { _private, tmp };
uECC_word_t *initial_Z = 0;
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
wordcount_t num_bytes = curve->num_bytes;
int r;
/* Converting buffers to correct bit order: */
uECC_vli_bytesToNative(_private,
private_key,
BITS_TO_BYTES(curve->num_n_bits));
uECC_vli_bytesToNative(_public,
public_key,
num_bytes);
uECC_vli_bytesToNative(_public + num_words,
public_key + num_bytes,
num_bytes);
/* Regularize the bitcount for the private key so that attackers cannot use a
* side channel attack to learn the number of leading zeros. */
carry = regularize_k(_private, _private, tmp, curve);
/* If an RNG function was specified, try to get a random initial Z value to
* improve protection against side-channel attacks. */
if (g_rng_function) {
if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
r = 0;
goto clear_and_out;
}
initial_Z = p2[carry];
}
EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1,
curve);
uECC_vli_nativeToBytes(secret, num_bytes, _public);
r = !EccPoint_isZero(_public, curve);
uECC_vli_nativeToBytes(secret, num_bytes, _public);
r = !EccPoint_isZero(_public, curve);
clear_and_out:
/* erasing temporary buffer used to store secret: */
_set_secure(p2, 0, sizeof(p2));
_set_secure(tmp, 0, sizeof(tmp));
_set_secure(_private, 0, sizeof(_private));
/* erasing temporary buffer used to store secret: */
_set_secure(p2, 0, sizeof(p2));
_set_secure(tmp, 0, sizeof(tmp));
_set_secure(_private, 0, sizeof(_private));
return r;
return r;
}

View File

@@ -53,9 +53,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ecc_dsa.h"
#include "constants.h"
#include "ecc.h"
#include "ecc_dsa.h"
#if defined(BL_MCU_SDK)
#include "ecc_platform_specific.h"
#endif
@@ -66,229 +66,209 @@ static uECC_RNG_Function g_rng_function = &default_CSPRNG;
static uECC_RNG_Function g_rng_function = 0;
#endif
static void bits2int(uECC_word_t *native, const uint8_t *bits,
unsigned bits_size, uECC_Curve curve)
{
unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits);
unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits);
int shift;
uECC_word_t carry;
uECC_word_t *ptr;
static void bits2int(uECC_word_t *native, const uint8_t *bits, unsigned bits_size, uECC_Curve curve) {
unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits);
unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits);
int shift;
uECC_word_t carry;
uECC_word_t *ptr;
if (bits_size > num_n_bytes) {
bits_size = num_n_bytes;
}
if (bits_size > num_n_bytes) {
bits_size = num_n_bytes;
}
uECC_vli_clear(native, num_n_words);
uECC_vli_bytesToNative(native, bits, bits_size);
if (bits_size * 8 <= (unsigned)curve->num_n_bits) {
return;
}
shift = bits_size * 8 - curve->num_n_bits;
carry = 0;
ptr = native + num_n_words;
while (ptr-- > native) {
uECC_word_t temp = *ptr;
*ptr = (temp >> shift) | carry;
carry = temp << (uECC_WORD_BITS - shift);
}
uECC_vli_clear(native, num_n_words);
uECC_vli_bytesToNative(native, bits, bits_size);
if (bits_size * 8 <= (unsigned)curve->num_n_bits) {
return;
}
shift = bits_size * 8 - curve->num_n_bits;
carry = 0;
ptr = native + num_n_words;
while (ptr-- > native) {
uECC_word_t temp = *ptr;
*ptr = (temp >> shift) | carry;
carry = temp << (uECC_WORD_BITS - shift);
}
/* Reduce mod curve_n */
if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) {
uECC_vli_sub(native, native, curve->n, num_n_words);
}
/* Reduce mod curve_n */
if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) {
uECC_vli_sub(native, native, curve->n, num_n_words);
}
}
int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
unsigned hash_size, uECC_word_t *k, uint8_t *signature,
uECC_Curve curve)
{
uECC_word_t tmp[NUM_ECC_WORDS];
uECC_word_t s[NUM_ECC_WORDS];
uECC_word_t *k2[2] = { tmp, s };
uECC_word_t p[NUM_ECC_WORDS * 2];
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash, unsigned hash_size, uECC_word_t *k, uint8_t *signature, uECC_Curve curve) {
uECC_word_t tmp[NUM_ECC_WORDS];
uECC_word_t s[NUM_ECC_WORDS];
uECC_word_t *k2[2] = {tmp, s};
uECC_word_t p[NUM_ECC_WORDS * 2];
uECC_word_t carry;
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
bitcount_t num_n_bits = curve->num_n_bits;
/* Make sure 0 < k < curve_n */
if (uECC_vli_isZero(k, num_words) ||
uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
return 0;
}
carry = regularize_k(k, tmp, s, curve);
EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
if (uECC_vli_isZero(p, num_words)) {
return 0;
}
/* If an RNG function was specified, get a random number
to prevent side channel analysis of k. */
if (!g_rng_function) {
uECC_vli_clear(tmp, num_n_words);
tmp[0] = 1;
} else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) {
return 0;
}
/* Prevent side channel analysis of uECC_vli_modInv() to determine
bits of k / the private key by premultiplying by a random number */
uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */
uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
/* tmp = d: */
uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
s[num_n_words - 1] = 0;
uECC_vli_set(s, p, num_words);
uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
bits2int(tmp, message_hash, hash_size, curve);
uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */
if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
return 0;
}
uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
return 1;
}
int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash,
unsigned hash_size, uint8_t *signature, uECC_Curve curve)
{
uECC_word_t _random[2 * NUM_ECC_WORDS];
uECC_word_t k[NUM_ECC_WORDS];
uECC_word_t tries;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
/* Generating _random uniformly at random: */
uECC_RNG_Function rng_function = uECC_get_rng();
if (!rng_function ||
!rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
return 0;
}
// computing k as modular reduction of _random (see FIPS 186.4 B.5.1):
uECC_vli_mmod(k, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature,
curve)) {
return 1;
}
}
/* Make sure 0 < k < curve_n */
if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
return 0;
}
carry = regularize_k(k, tmp, s, curve);
EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
if (uECC_vli_isZero(p, num_words)) {
return 0;
}
/* If an RNG function was specified, get a random number
to prevent side channel analysis of k. */
if (!g_rng_function) {
uECC_vli_clear(tmp, num_n_words);
tmp[0] = 1;
} else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) {
return 0;
}
/* Prevent side channel analysis of uECC_vli_modInv() to determine
bits of k / the private key by premultiplying by a random number */
uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */
uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
/* tmp = d: */
uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
s[num_n_words - 1] = 0;
uECC_vli_set(s, p, num_words);
uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
bits2int(tmp, message_hash, hash_size, curve);
uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */
if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
return 0;
}
uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
return 1;
}
static bitcount_t smax(bitcount_t a, bitcount_t b)
{
return (a > b ? a : b);
int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash, unsigned hash_size, uint8_t *signature, uECC_Curve curve) {
uECC_word_t _random[2 * NUM_ECC_WORDS];
uECC_word_t k[NUM_ECC_WORDS];
uECC_word_t tries;
for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
/* Generating _random uniformly at random: */
uECC_RNG_Function rng_function = uECC_get_rng();
if (!rng_function || !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS * uECC_WORD_SIZE)) {
return 0;
}
// computing k as modular reduction of _random (see FIPS 186.4 B.5.1):
uECC_vli_mmod(k, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) {
return 1;
}
}
return 0;
}
int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash,
unsigned hash_size, const uint8_t *signature,
uECC_Curve curve)
{
uECC_word_t u1[NUM_ECC_WORDS], u2[NUM_ECC_WORDS];
uECC_word_t z[NUM_ECC_WORDS];
uECC_word_t sum[NUM_ECC_WORDS * 2];
uECC_word_t rx[NUM_ECC_WORDS];
uECC_word_t ry[NUM_ECC_WORDS];
uECC_word_t tx[NUM_ECC_WORDS];
uECC_word_t ty[NUM_ECC_WORDS];
uECC_word_t tz[NUM_ECC_WORDS];
const uECC_word_t *points[4];
const uECC_word_t *point;
bitcount_t num_bits;
bitcount_t i;
static bitcount_t smax(bitcount_t a, bitcount_t b) { return (a > b ? a : b); }
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t r[NUM_ECC_WORDS], s[NUM_ECC_WORDS];
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash, unsigned hash_size, const uint8_t *signature, uECC_Curve curve) {
uECC_word_t u1[NUM_ECC_WORDS], u2[NUM_ECC_WORDS];
uECC_word_t z[NUM_ECC_WORDS];
uECC_word_t sum[NUM_ECC_WORDS * 2];
uECC_word_t rx[NUM_ECC_WORDS];
uECC_word_t ry[NUM_ECC_WORDS];
uECC_word_t tx[NUM_ECC_WORDS];
uECC_word_t ty[NUM_ECC_WORDS];
uECC_word_t tz[NUM_ECC_WORDS];
const uECC_word_t *points[4];
const uECC_word_t *point;
bitcount_t num_bits;
bitcount_t i;
rx[num_n_words - 1] = 0;
r[num_n_words - 1] = 0;
s[num_n_words - 1] = 0;
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_word_t r[NUM_ECC_WORDS], s[NUM_ECC_WORDS];
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
uECC_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes,
curve->num_bytes);
uECC_vli_bytesToNative(r, signature, curve->num_bytes);
uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
rx[num_n_words - 1] = 0;
r[num_n_words - 1] = 0;
s[num_n_words - 1] = 0;
/* r, s must not be 0. */
if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
return 0;
uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
uECC_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes, curve->num_bytes);
uECC_vli_bytesToNative(r, signature, curve->num_bytes);
uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
/* r, s must not be 0. */
if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
return 0;
}
/* r, s must be < n. */
if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
return 0;
}
/* Calculate u1 and u2. */
uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
u1[num_n_words - 1] = 0;
bits2int(u1, message_hash, hash_size, curve);
uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
/* Calculate sum = G + Q. */
uECC_vli_set(sum, _public, num_words);
uECC_vli_set(sum + num_words, _public + num_words, num_words);
uECC_vli_set(tx, curve->G, num_words);
uECC_vli_set(ty, curve->G + num_words, num_words);
uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
XYcZ_add(tx, ty, sum, sum + num_words, curve);
uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
apply_z(sum, sum + num_words, z, curve);
/* Use Shamir's trick to calculate u1*G + u2*Q */
points[0] = 0;
points[1] = curve->G;
points[2] = _public;
points[3] = sum;
num_bits = smax(uECC_vli_numBits(u1, num_n_words), uECC_vli_numBits(u2, num_n_words));
point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)];
uECC_vli_set(rx, point, num_words);
uECC_vli_set(ry, point + num_words, num_words);
uECC_vli_clear(z, num_words);
z[0] = 1;
for (i = num_bits - 2; i >= 0; --i) {
uECC_word_t index;
curve->double_jacobian(rx, ry, z, curve);
index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1);
point = points[index];
if (point) {
uECC_vli_set(tx, point, num_words);
uECC_vli_set(ty, point + num_words, num_words);
apply_z(tx, ty, z, curve);
uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
XYcZ_add(tx, ty, rx, ry, curve);
uECC_vli_modMult_fast(z, z, tz, curve);
}
}
/* r, s must be < n. */
if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 ||
uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
return 0;
}
uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
apply_z(rx, ry, z, curve);
/* Calculate u1 and u2. */
uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
u1[num_n_words - 1] = 0;
bits2int(u1, message_hash, hash_size, curve);
uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
/* v = x1 (mod n) */
if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
uECC_vli_sub(rx, rx, curve->n, num_n_words);
}
/* Calculate sum = G + Q. */
uECC_vli_set(sum, _public, num_words);
uECC_vli_set(sum + num_words, _public + num_words, num_words);
uECC_vli_set(tx, curve->G, num_words);
uECC_vli_set(ty, curve->G + num_words, num_words);
uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
XYcZ_add(tx, ty, sum, sum + num_words, curve);
uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
apply_z(sum, sum + num_words, z, curve);
/* Use Shamir's trick to calculate u1*G + u2*Q */
points[0] = 0;
points[1] = curve->G;
points[2] = _public;
points[3] = sum;
num_bits = smax(uECC_vli_numBits(u1, num_n_words),
uECC_vli_numBits(u2, num_n_words));
point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) |
((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)];
uECC_vli_set(rx, point, num_words);
uECC_vli_set(ry, point + num_words, num_words);
uECC_vli_clear(z, num_words);
z[0] = 1;
for (i = num_bits - 2; i >= 0; --i) {
uECC_word_t index;
curve->double_jacobian(rx, ry, z, curve);
index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1);
point = points[index];
if (point) {
uECC_vli_set(tx, point, num_words);
uECC_vli_set(ty, point + num_words, num_words);
apply_z(tx, ty, z, curve);
uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
XYcZ_add(tx, ty, rx, ry, curve);
uECC_vli_modMult_fast(z, z, tz, curve);
}
}
uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
apply_z(rx, ry, z, curve);
/* v = x1 (mod n) */
if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
uECC_vli_sub(rx, rx, curve->n, num_n_words);
}
/* Accept only if v == r. */
return (int)(uECC_vli_equal(rx, r, num_words) == 0);
/* Accept only if v == r. */
return (int)(uECC_vli_equal(rx, r, num_words) == 0);
}

View File

@@ -55,13 +55,11 @@
* uECC_platform_specific.c -- Implementation of platform specific functions
*/
#if defined(unix) || defined(__linux__) || defined(__unix__) || \
defined(__unix) | (defined(__APPLE__) && defined(__MACH__)) || \
defined(uECC_POSIX)
#if defined(unix) || defined(__linux__) || defined(__unix__) || defined(__unix) | (defined(__APPLE__) && defined(__MACH__)) || defined(uECC_POSIX)
/* Some POSIX-like system with /dev/urandom or /dev/random. */
#include <sys/types.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdint.h>
@@ -70,34 +68,34 @@
#define O_CLOEXEC 0
#endif
int default_CSPRNG(uint8_t *dest, unsigned int size)
{
/* input sanity check: */
if (dest == (uint8_t *)0 || (size <= 0))
return 0;
int default_CSPRNG(uint8_t *dest, unsigned int size) {
/* input sanity check: */
if (dest == (uint8_t *)0 || (size <= 0)) {
return 0;
}
int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1) {
fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
if (fd == -1) {
fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
if (fd == -1) {
return 0;
}
return 0;
}
}
char *ptr = (char *)dest;
size_t left = (size_t)size;
while (left > 0) {
ssize_t bytes_read = read(fd, ptr, left);
if (bytes_read <= 0) { // read failed
close(fd);
return 0;
}
left -= bytes_read;
ptr += bytes_read;
char *ptr = (char *)dest;
size_t left = (size_t)size;
while (left > 0) {
ssize_t bytes_read = read(fd, ptr, left);
if (bytes_read <= 0) { // read failed
close(fd);
return 0;
}
left -= bytes_read;
ptr += bytes_read;
}
close(fd);
return 1;
close(fd);
return 1;
}
#endif /* platform */

View File

@@ -34,112 +34,92 @@
#include "constants.h"
#include "utils.h"
static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size)
{
const uint8_t inner_pad = (uint8_t)0x36;
const uint8_t outer_pad = (uint8_t)0x5c;
unsigned int i;
static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size) {
const uint8_t inner_pad = (uint8_t)0x36;
const uint8_t outer_pad = (uint8_t)0x5c;
unsigned int i;
for (i = 0; i < key_size; ++i) {
key[i] = inner_pad ^ new_key[i];
key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i];
}
for (; i < TC_SHA256_BLOCK_SIZE; ++i) {
key[i] = inner_pad;
key[i + TC_SHA256_BLOCK_SIZE] = outer_pad;
}
for (i = 0; i < key_size; ++i) {
key[i] = inner_pad ^ new_key[i];
key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i];
}
for (; i < TC_SHA256_BLOCK_SIZE; ++i) {
key[i] = inner_pad;
key[i + TC_SHA256_BLOCK_SIZE] = outer_pad;
}
}
int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key,
unsigned int key_size)
{
/* Input sanity check */
if (ctx == (TCHmacState_t)0 ||
key == (const uint8_t *)0 ||
key_size == 0) {
return TC_CRYPTO_FAIL;
}
int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key, unsigned int key_size) {
/* Input sanity check */
if (ctx == (TCHmacState_t)0 || key == (const uint8_t *)0 || key_size == 0) {
return TC_CRYPTO_FAIL;
}
const uint8_t dummy_key[TC_SHA256_BLOCK_SIZE];
struct tc_hmac_state_struct dummy_state;
const uint8_t dummy_key[TC_SHA256_BLOCK_SIZE];
struct tc_hmac_state_struct dummy_state;
if (key_size <= TC_SHA256_BLOCK_SIZE) {
/*
* The next three calls are dummy calls just to avoid
* certain timing attacks. Without these dummy calls,
* adversaries would be able to learn whether the key_size is
* greater than TC_SHA256_BLOCK_SIZE by measuring the time
* consumed in this process.
*/
(void)tc_sha256_init(&dummy_state.hash_state);
(void)tc_sha256_update(&dummy_state.hash_state,
dummy_key,
key_size);
(void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE],
&dummy_state.hash_state);
/* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */
rekey(ctx->key, key, key_size);
} else {
(void)tc_sha256_init(&ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state, key, key_size);
(void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE],
&ctx->hash_state);
rekey(ctx->key,
&ctx->key[TC_SHA256_DIGEST_SIZE],
TC_SHA256_DIGEST_SIZE);
}
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_init(TCHmacState_t ctx)
{
/* input sanity check: */
if (ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
if (key_size <= TC_SHA256_BLOCK_SIZE) {
/*
* The next three calls are dummy calls just to avoid
* certain timing attacks. Without these dummy calls,
* adversaries would be able to learn whether the key_size is
* greater than TC_SHA256_BLOCK_SIZE by measuring the time
* consumed in this process.
*/
(void)tc_sha256_init(&dummy_state.hash_state);
(void)tc_sha256_update(&dummy_state.hash_state, dummy_key, key_size);
(void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE], &dummy_state.hash_state);
/* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */
rekey(ctx->key, key, key_size);
} else {
(void)tc_sha256_init(&ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state, ctx->key, TC_SHA256_BLOCK_SIZE);
(void)tc_sha256_update(&ctx->hash_state, key, key_size);
(void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE], &ctx->hash_state);
rekey(ctx->key, &ctx->key[TC_SHA256_DIGEST_SIZE], TC_SHA256_DIGEST_SIZE);
}
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_update(TCHmacState_t ctx,
const void *data,
unsigned int data_length)
{
/* input sanity check: */
if (ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
int tc_hmac_init(TCHmacState_t ctx) {
/* input sanity check: */
if (ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
(void)tc_sha256_update(&ctx->hash_state, data, data_length);
(void)tc_sha256_init(&ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state, ctx->key, TC_SHA256_BLOCK_SIZE);
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_final(uint8_t *tag, unsigned int taglen, TCHmacState_t ctx)
{
/* input sanity check: */
if (tag == (uint8_t *)0 ||
taglen != TC_SHA256_DIGEST_SIZE ||
ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
int tc_hmac_update(TCHmacState_t ctx, const void *data, unsigned int data_length) {
/* input sanity check: */
if (ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
(void)tc_sha256_final(tag, &ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state, data, data_length);
(void)tc_sha256_init(&ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state,
&ctx->key[TC_SHA256_BLOCK_SIZE],
TC_SHA256_BLOCK_SIZE);
(void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE);
(void)tc_sha256_final(tag, &ctx->hash_state);
/* destroy the current state */
_set(ctx, 0, sizeof(*ctx));
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_final(uint8_t *tag, unsigned int taglen, TCHmacState_t ctx) {
/* input sanity check: */
if (tag == (uint8_t *)0 || taglen != TC_SHA256_DIGEST_SIZE || ctx == (TCHmacState_t)0) {
return TC_CRYPTO_FAIL;
}
(void)tc_sha256_final(tag, &ctx->hash_state);
(void)tc_sha256_init(&ctx->hash_state);
(void)tc_sha256_update(&ctx->hash_state, &ctx->key[TC_SHA256_BLOCK_SIZE], TC_SHA256_BLOCK_SIZE);
(void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE);
(void)tc_sha256_final(tag, &ctx->hash_state);
/* destroy the current state */
_set(ctx, 0, sizeof(*ctx));
return TC_CRYPTO_SUCCESS;
}

View File

@@ -31,8 +31,8 @@
*/
#include "hmac_prng.h"
#include "hmac.h"
#include "constants.h"
#include "hmac.h"
#include "utils.h"
/*
@@ -75,156 +75,137 @@ static const unsigned int MAX_OUT = (1 << 19);
/*
* Assumes: prng != NULL
*/
static void update(TCHmacPrng_t prng, const uint8_t *data, unsigned int datalen, const uint8_t *additional_data, unsigned int additional_datalen)
{
const uint8_t separator0 = 0x00;
const uint8_t separator1 = 0x01;
static void update(TCHmacPrng_t prng, const uint8_t *data, unsigned int datalen, const uint8_t *additional_data, unsigned int additional_datalen) {
const uint8_t separator0 = 0x00;
const uint8_t separator1 = 0x01;
/* configure the new prng key into the prng's instance of hmac */
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* configure the new prng key into the prng's instance of hmac */
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use current state, e and separator 0 to compute a new prng key: */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
/* use current state, e and separator 0 to compute a new prng key: */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
if (data && datalen)
(void)tc_hmac_update(&prng->h, data, datalen);
if (additional_data && additional_datalen)
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
/* configure the new prng key into the prng's instance of hmac */
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use the new key to compute a new state variable v */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
if (data == 0 || datalen == 0)
return;
/* configure the new prng key into the prng's instance of hmac */
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use current state, e and separator 1 to compute a new prng key: */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
if (data && datalen) {
(void)tc_hmac_update(&prng->h, data, datalen);
if (additional_data && additional_datalen)
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
}
if (additional_data && additional_datalen) {
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
}
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
/* configure the new prng key into the prng's instance of hmac */
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use the new key to compute a new state variable v */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
if (data == 0 || datalen == 0) {
return;
}
/* configure the new prng key into the prng's instance of hmac */
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use current state, e and separator 1 to compute a new prng key: */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
(void)tc_hmac_update(&prng->h, data, datalen);
if (additional_data && additional_datalen) {
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
}
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
/* configure the new prng key into the prng's instance of hmac */
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use the new key to compute a new state variable v */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
}
int tc_hmac_prng_init(TCHmacPrng_t prng, const uint8_t *personalization, unsigned int plen) {
/* input sanity check: */
if (prng == (TCHmacPrng_t)0 || personalization == (uint8_t *)0 || plen > MAX_PLEN) {
return TC_CRYPTO_FAIL;
}
/* put the generator into a known state: */
_set(prng->key, 0x00, sizeof(prng->key));
_set(prng->v, 0x01, sizeof(prng->v));
update(prng, personalization, plen, 0, 0);
/* force a reseed before allowing tc_hmac_prng_generate to succeed: */
prng->countdown = 0;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed, unsigned int seedlen, const uint8_t *additional_input, unsigned int additionallen) {
/* input sanity check: */
if (prng == (TCHmacPrng_t)0 || seed == (const uint8_t *)0 || seedlen < MIN_SLEN || seedlen > MAX_SLEN) {
return TC_CRYPTO_FAIL;
}
if (additional_input != (const uint8_t *)0) {
/*
* Abort if additional_input is provided but has inappropriate
* length
*/
if (additionallen == 0 || additionallen > MAX_ALEN) {
return TC_CRYPTO_FAIL;
} else {
/* call update for the seed and additional_input */
update(prng, seed, seedlen, additional_input, additionallen);
}
} else {
/* call update only for the seed */
update(prng, seed, seedlen, 0, 0);
}
/* ... and enable hmac_prng_generate */
prng->countdown = MAX_GENS;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng) {
unsigned int bufferlen;
/* input sanity check: */
if (out == (uint8_t *)0 || prng == (TCHmacPrng_t)0 || outlen == 0 || outlen > MAX_OUT) {
return TC_CRYPTO_FAIL;
} else if (prng->countdown == 0) {
return TC_HMAC_PRNG_RESEED_REQ;
}
prng->countdown--;
while (outlen != 0) {
/* configure the new prng key into the prng's instance of hmac */
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* use the new key to compute a new state variable v */
/* operate HMAC in OFB mode to create "random" outputs */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
}
int tc_hmac_prng_init(TCHmacPrng_t prng,
const uint8_t *personalization,
unsigned int plen)
{
/* input sanity check: */
if (prng == (TCHmacPrng_t)0 ||
personalization == (uint8_t *)0 ||
plen > MAX_PLEN) {
return TC_CRYPTO_FAIL;
}
/* put the generator into a known state: */
_set(prng->key, 0x00, sizeof(prng->key));
_set(prng->v, 0x01, sizeof(prng->v));
update(prng, personalization, plen, 0, 0);
/* force a reseed before allowing tc_hmac_prng_generate to succeed: */
prng->countdown = 0;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_prng_reseed(TCHmacPrng_t prng,
const uint8_t *seed,
unsigned int seedlen,
const uint8_t *additional_input,
unsigned int additionallen)
{
/* input sanity check: */
if (prng == (TCHmacPrng_t)0 ||
seed == (const uint8_t *)0 ||
seedlen < MIN_SLEN ||
seedlen > MAX_SLEN) {
return TC_CRYPTO_FAIL;
}
if (additional_input != (const uint8_t *)0) {
/*
* Abort if additional_input is provided but has inappropriate
* length
*/
if (additionallen == 0 ||
additionallen > MAX_ALEN) {
return TC_CRYPTO_FAIL;
} else {
/* call update for the seed and additional_input */
update(prng, seed, seedlen, additional_input, additionallen);
}
} else {
/* call update only for the seed */
update(prng, seed, seedlen, 0, 0);
}
/* ... and enable hmac_prng_generate */
prng->countdown = MAX_GENS;
return TC_CRYPTO_SUCCESS;
}
int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
{
unsigned int bufferlen;
/* input sanity check: */
if (out == (uint8_t *)0 ||
prng == (TCHmacPrng_t)0 ||
outlen == 0 ||
outlen > MAX_OUT) {
return TC_CRYPTO_FAIL;
} else if (prng->countdown == 0) {
return TC_HMAC_PRNG_RESEED_REQ;
}
prng->countdown--;
while (outlen != 0) {
/* configure the new prng key into the prng's instance of hmac */
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
/* operate HMAC in OFB mode to create "random" outputs */
(void)tc_hmac_init(&prng->h);
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ?
outlen :
TC_SHA256_DIGEST_SIZE;
(void)_copy(out, bufferlen, prng->v, bufferlen);
out += bufferlen;
outlen = (outlen > TC_SHA256_DIGEST_SIZE) ?
(outlen - TC_SHA256_DIGEST_SIZE) :
0;
}
/* block future PRNG compromises from revealing past state */
update(prng, 0, 0, 0, 0);
return TC_CRYPTO_SUCCESS;
bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ? outlen : TC_SHA256_DIGEST_SIZE;
(void)_copy(out, bufferlen, prng->v, bufferlen);
out += bufferlen;
outlen = (outlen > TC_SHA256_DIGEST_SIZE) ? (outlen - TC_SHA256_DIGEST_SIZE) : 0;
}
/* block future PRNG compromises from revealing past state */
update(prng, 0, 0, 0, 0);
return TC_CRYPTO_SUCCESS;
}

View File

@@ -36,103 +36,96 @@
static void compress(unsigned int *iv, const uint8_t *data);
int tc_sha256_init(TCSha256State_t s)
{
/* input sanity check: */
if (s == (TCSha256State_t)0) {
return TC_CRYPTO_FAIL;
}
int tc_sha256_init(TCSha256State_t s) {
/* input sanity check: */
if (s == (TCSha256State_t)0) {
return TC_CRYPTO_FAIL;
}
/*
* Setting the initial state values.
* These values correspond to the first 32 bits of the fractional parts
* of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
* and 19.
*/
_set((uint8_t *)s, 0x00, sizeof(*s));
s->iv[0] = 0x6a09e667;
s->iv[1] = 0xbb67ae85;
s->iv[2] = 0x3c6ef372;
s->iv[3] = 0xa54ff53a;
s->iv[4] = 0x510e527f;
s->iv[5] = 0x9b05688c;
s->iv[6] = 0x1f83d9ab;
s->iv[7] = 0x5be0cd19;
/*
* Setting the initial state values.
* These values correspond to the first 32 bits of the fractional parts
* of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17
* and 19.
*/
_set((uint8_t *)s, 0x00, sizeof(*s));
s->iv[0] = 0x6a09e667;
s->iv[1] = 0xbb67ae85;
s->iv[2] = 0x3c6ef372;
s->iv[3] = 0xa54ff53a;
s->iv[4] = 0x510e527f;
s->iv[5] = 0x9b05688c;
s->iv[6] = 0x1f83d9ab;
s->iv[7] = 0x5be0cd19;
return TC_CRYPTO_SUCCESS;
return TC_CRYPTO_SUCCESS;
}
int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen)
{
/* input sanity check: */
if (s == (TCSha256State_t)0 ||
data == (void *)0) {
return TC_CRYPTO_FAIL;
} else if (datalen == 0) {
return TC_CRYPTO_SUCCESS;
}
while (datalen-- > 0) {
s->leftover[s->leftover_offset++] = *(data++);
if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
compress(s->iv, s->leftover);
s->leftover_offset = 0;
s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
}
}
int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) {
/* input sanity check: */
if (s == (TCSha256State_t)0 || data == (void *)0) {
return TC_CRYPTO_FAIL;
} else if (datalen == 0) {
return TC_CRYPTO_SUCCESS;
}
while (datalen-- > 0) {
s->leftover[s->leftover_offset++] = *(data++);
if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) {
compress(s->iv, s->leftover);
s->leftover_offset = 0;
s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3);
}
}
return TC_CRYPTO_SUCCESS;
}
int tc_sha256_final(uint8_t *digest, TCSha256State_t s)
{
unsigned int i;
int tc_sha256_final(uint8_t *digest, TCSha256State_t s) {
unsigned int i;
/* input sanity check: */
if (digest == (uint8_t *)0 ||
s == (TCSha256State_t)0) {
return TC_CRYPTO_FAIL;
}
/* input sanity check: */
if (digest == (uint8_t *)0 || s == (TCSha256State_t)0) {
return TC_CRYPTO_FAIL;
}
s->bits_hashed += (s->leftover_offset << 3);
s->bits_hashed += (s->leftover_offset << 3);
s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
/* there is not room for all the padding in this block */
_set(s->leftover + s->leftover_offset, 0x00,
sizeof(s->leftover) - s->leftover_offset);
compress(s->iv, s->leftover);
s->leftover_offset = 0;
}
/* add the padding and the length in big-Endian format */
_set(s->leftover + s->leftover_offset, 0x00,
sizeof(s->leftover) - 8 - s->leftover_offset);
s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
/* hash the padding and length */
s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */
if (s->leftover_offset > (sizeof(s->leftover) - 8)) {
/* there is not room for all the padding in this block */
_set(s->leftover + s->leftover_offset, 0x00, sizeof(s->leftover) - s->leftover_offset);
compress(s->iv, s->leftover);
s->leftover_offset = 0;
}
/* copy the iv out to digest */
for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
unsigned int t = *((unsigned int *)&s->iv[i]);
*digest++ = (uint8_t)(t >> 24);
*digest++ = (uint8_t)(t >> 16);
*digest++ = (uint8_t)(t >> 8);
*digest++ = (uint8_t)(t);
}
/* add the padding and the length in big-Endian format */
_set(s->leftover + s->leftover_offset, 0x00, sizeof(s->leftover) - 8 - s->leftover_offset);
s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed);
s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8);
s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16);
s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24);
s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32);
s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40);
s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48);
s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56);
/* destroy the current state */
_set(s, 0, sizeof(*s));
/* hash the padding and length */
compress(s->iv, s->leftover);
return TC_CRYPTO_SUCCESS;
/* copy the iv out to digest */
for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) {
unsigned int t = *((unsigned int *)&s->iv[i]);
*digest++ = (uint8_t)(t >> 24);
*digest++ = (uint8_t)(t >> 16);
*digest++ = (uint8_t)(t >> 8);
*digest++ = (uint8_t)(t);
}
/* destroy the current state */
_set(s, 0, sizeof(*s));
return TC_CRYPTO_SUCCESS;
}
/*
@@ -140,24 +133,13 @@ int tc_sha256_final(uint8_t *digest, TCSha256State_t s)
* These values correspond to the first 32 bits of the fractional parts of the
* cube roots of the first 64 primes between 2 and 311.
*/
static const unsigned int k256[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
static const unsigned int k256[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74,
0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d,
0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e,
0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
static inline unsigned int ROTR(unsigned int a, unsigned int n)
{
return (((a) >> n) | ((a) << (32 - n)));
}
static inline unsigned int ROTR(unsigned int a, unsigned int n) { return (((a) >> n) | ((a) << (32 - n))); }
#define Sigma0(a) (ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22))
#define Sigma1(a) (ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25))
@@ -167,75 +149,73 @@ static inline unsigned int ROTR(unsigned int a, unsigned int n)
#define Ch(a, b, c) (((a) & (b)) ^ ((~(a)) & (c)))
#define Maj(a, b, c) (((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c)))
static inline unsigned int BigEndian(const uint8_t **c)
{
unsigned int n = 0;
static inline unsigned int BigEndian(const uint8_t **c) {
unsigned int n = 0;
n = (((unsigned int)(*((*c)++))) << 24);
n |= ((unsigned int)(*((*c)++)) << 16);
n |= ((unsigned int)(*((*c)++)) << 8);
n |= ((unsigned int)(*((*c)++)));
return n;
n = (((unsigned int)(*((*c)++))) << 24);
n |= ((unsigned int)(*((*c)++)) << 16);
n |= ((unsigned int)(*((*c)++)) << 8);
n |= ((unsigned int)(*((*c)++)));
return n;
}
static void compress(unsigned int *iv, const uint8_t *data)
{
unsigned int a, b, c, d, e, f, g, h;
unsigned int s0, s1;
unsigned int t1, t2;
unsigned int work_space[16];
unsigned int n;
unsigned int i;
static void compress(unsigned int *iv, const uint8_t *data) {
unsigned int a, b, c, d, e, f, g, h;
unsigned int s0, s1;
unsigned int t1, t2;
unsigned int work_space[16];
unsigned int n;
unsigned int i;
a = iv[0];
b = iv[1];
c = iv[2];
d = iv[3];
e = iv[4];
f = iv[5];
g = iv[6];
h = iv[7];
a = iv[0];
b = iv[1];
c = iv[2];
d = iv[3];
e = iv[4];
f = iv[5];
g = iv[6];
h = iv[7];
for (i = 0; i < 16; ++i) {
n = BigEndian(&data);
t1 = work_space[i] = n;
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
t2 = Sigma0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
for (i = 0; i < 16; ++i) {
n = BigEndian(&data);
t1 = work_space[i] = n;
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
t2 = Sigma0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
for (; i < 64; ++i) {
s0 = work_space[(i + 1) & 0x0f];
s0 = sigma0(s0);
s1 = work_space[(i + 14) & 0x0f];
s1 = sigma1(s1);
for (; i < 64; ++i) {
s0 = work_space[(i + 1) & 0x0f];
s0 = sigma0(s0);
s1 = work_space[(i + 14) & 0x0f];
s1 = sigma1(s1);
t1 = work_space[i & 0xf] += s0 + s1 + work_space[(i + 9) & 0xf];
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
t2 = Sigma0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
t1 = work_space[i & 0xf] += s0 + s1 + work_space[(i + 9) & 0xf];
t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i];
t2 = Sigma0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
iv[0] += a;
iv[1] += b;
iv[2] += c;
iv[3] += d;
iv[4] += e;
iv[5] += f;
iv[6] += g;
iv[7] += h;
iv[0] += a;
iv[1] += b;
iv[2] += c;
iv[3] += d;
iv[4] += e;
iv[5] += f;
iv[6] += g;
iv[7] += h;
}

View File

@@ -37,38 +37,29 @@
#define MASK_TWENTY_SEVEN 0x1b
unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len)
{
if (from_len <= to_len) {
(void)memcpy(to, from, from_len);
return from_len;
} else {
return TC_CRYPTO_FAIL;
}
unsigned int _copy(uint8_t *to, unsigned int to_len, const uint8_t *from, unsigned int from_len) {
if (from_len <= to_len) {
(void)memcpy(to, from, from_len);
return from_len;
} else {
return TC_CRYPTO_FAIL;
}
}
void _set(void *to, uint8_t val, unsigned int len)
{
(void)memset(to, val, len);
}
void _set(void *to, uint8_t val, unsigned int len) { (void)memset(to, val, len); }
/*
* Doubles the value of a byte for values up to 127.
*/
uint8_t _double_byte(uint8_t a)
{
return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN));
}
uint8_t _double_byte(uint8_t a) { return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN)); }
int _compare(const uint8_t *a, const uint8_t *b, size_t size)
{
const uint8_t *tempa = a;
const uint8_t *tempb = b;
uint8_t result = 0;
int _compare(const uint8_t *a, const uint8_t *b, size_t size) {
const uint8_t *tempa = a;
const uint8_t *tempb = b;
uint8_t result = 0;
for (unsigned int i = 0; i < size; i++) {
result |= tempa[i] ^ tempb[i];
}
return result;
for (unsigned int i = 0; i < size; i++) {
result |= tempa[i] ^ tempb[i];
}
return result;
}

View File

@@ -1,132 +1,125 @@
/*****************************************************************************************
*
* @file utils.c
*
* @brief entry
*
* Copyright (C) Bouffalo Lab 2019
*
* History: 2019-11 crealted by Lanlan Gong @ Shanghai
*
*****************************************************************************************/
#include <stdint.h>
*
* @file utils.c
*
* @brief entry
*
* Copyright (C) Bouffalo Lab 2019
*
* History: 2019-11 crealted by Lanlan Gong @ Shanghai
*
*****************************************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
void reverse_bytearray(uint8_t *src, uint8_t *result, int array_size)
{
for (int i = 0; i < array_size; i++) {
result[array_size - i - 1] = src[i];
}
void reverse_bytearray(uint8_t *src, uint8_t *result, int array_size) {
for (int i = 0; i < array_size; i++) {
result[array_size - i - 1] = src[i];
}
}
unsigned int find_msb_set(uint32_t data)
{
uint32_t count = 0;
uint32_t mask = 0x80000000;
if (!data) {
return 0;
}
while ((data & mask) == 0) {
count += 1u;
mask = mask >> 1u;
}
return (32 - count);
}
unsigned int find_lsb_set(uint32_t data)
{
uint32_t count = 0;
uint32_t mask = 0x00000001;
if (!data) {
return 0;
}
while ((data & mask) == 0) {
count += 1u;
mask = mask << 1u;
}
return (1 + count);
}
int char2hex(char c, uint8_t *x)
{
if (c >= '0' && c <= '9') {
*x = c - '0';
} else if (c >= 'a' && c <= 'f') {
*x = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
*x = c - 'A' + 10;
} else {
return -1;
}
unsigned int find_msb_set(uint32_t data) {
uint32_t count = 0;
uint32_t mask = 0x80000000;
if (!data) {
return 0;
}
while ((data & mask) == 0) {
count += 1u;
mask = mask >> 1u;
}
return (32 - count);
}
int hex2char(uint8_t x, char *c)
{
if (x <= 9) {
*c = x + '0';
} else if (x <= 15) {
*c = x - 10 + 'a';
} else {
return -1;
}
unsigned int find_lsb_set(uint32_t data) {
uint32_t count = 0;
uint32_t mask = 0x00000001;
if (!data) {
return 0;
}
while ((data & mask) == 0) {
count += 1u;
mask = mask << 1u;
}
return (1 + count);
}
size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen)
{
if ((hexlen + 1) < buflen * 2) {
return 0;
}
int char2hex(char c, uint8_t *x) {
if (c >= '0' && c <= '9') {
*x = c - '0';
} else if (c >= 'a' && c <= 'f') {
*x = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
*x = c - 'A' + 10;
} else {
return -1;
}
for (size_t i = 0; i < buflen; i++) {
if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) {
return 0;
}
if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) {
return 0;
}
}
hex[2 * buflen] = '\0';
return 2 * buflen;
return 0;
}
size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen)
{
uint8_t dec;
int hex2char(uint8_t x, char *c) {
if (x <= 9) {
*c = x + '0';
} else if (x <= 15) {
*c = x - 10 + 'a';
} else {
return -1;
}
if (buflen < hexlen / 2 + hexlen % 2) {
return 0;
}
/* if hexlen is uneven, insert leading zero nibble */
if (hexlen % 2) {
if (char2hex(hex[0], &dec) < 0) {
return 0;
}
buf[0] = dec;
hex++;
buf++;
}
/* regular hex conversion */
for (size_t i = 0; i < hexlen / 2; i++) {
if (char2hex(hex[2 * i], &dec) < 0) {
return 0;
}
buf[i] = dec << 4;
if (char2hex(hex[2 * i + 1], &dec) < 0) {
return 0;
}
buf[i] += dec;
}
return hexlen / 2 + hexlen % 2;
return 0;
}
size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen) {
if ((hexlen + 1) < buflen * 2) {
return 0;
}
for (size_t i = 0; i < buflen; i++) {
if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) {
return 0;
}
if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) {
return 0;
}
}
hex[2 * buflen] = '\0';
return 2 * buflen;
}
size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen) {
uint8_t dec;
if (buflen < hexlen / 2 + hexlen % 2) {
return 0;
}
/* if hexlen is uneven, insert leading zero nibble */
if (hexlen % 2) {
if (char2hex(hex[0], &dec) < 0) {
return 0;
}
buf[0] = dec;
hex++;
buf++;
}
/* regular hex conversion */
for (size_t i = 0; i < hexlen / 2; i++) {
if (char2hex(hex[2 * i], &dec) < 0) {
return 0;
}
buf[i] = dec << 4;
if (char2hex(hex[2 * i + 1], &dec) < 0) {
return 0;
}
buf[i] += dec;
}
return hexlen / 2 + hexlen % 2;
}

View File

@@ -11,9 +11,9 @@
* Workqueue support functions
*/
#include <zephyr.h>
#include <log.h>
#include "errno.h"
#include <log.h>
#include <zephyr.h>
struct k_thread work_q_thread;
#if !defined(BFLB_BLE)
@@ -21,328 +21,295 @@ static BT_STACK_NOINIT(work_q_stack, CONFIG_BT_WORK_QUEUE_STACK_SIZE);
#endif
struct k_work_q g_work_queue_main;
static void k_work_submit_to_queue(struct k_work_q *work_q,
struct k_work *work)
{
if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) {
k_fifo_put(&work_q->fifo, work);
}
static void k_work_submit_to_queue(struct k_work_q *work_q, struct k_work *work) {
if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) {
k_fifo_put(&work_q->fifo, work);
}
}
#if defined(BFLB_BLE)
static void work_queue_main(void *p1)
{
struct k_work *work;
UNUSED(p1);
static void work_queue_main(void *p1) {
struct k_work *work;
UNUSED(p1);
while (1) {
work = k_fifo_get(&g_work_queue_main.fifo, K_FOREVER);
while (1) {
work = k_fifo_get(&g_work_queue_main.fifo, K_FOREVER);
if (atomic_test_and_clear_bit(work->flags, K_WORK_STATE_PENDING)) {
work->handler(work);
}
k_yield();
}
}
int k_work_q_start(void)
{
k_fifo_init(&g_work_queue_main.fifo, 20);
return k_thread_create(&work_q_thread, "work_q_thread",
CONFIG_BT_WORK_QUEUE_STACK_SIZE,
work_queue_main, CONFIG_BT_WORK_QUEUE_PRIO);
}
int k_work_init(struct k_work *work, k_work_handler_t handler)
{
ASSERT(work, "work is NULL");
atomic_clear(work->flags);
work->handler = handler;
return 0;
}
void k_work_submit(struct k_work *work)
{
k_work_submit_to_queue(&g_work_queue_main, work);
}
static void work_timeout(void *timer)
{
/* Parameter timer type is */
struct k_delayed_work *w = (struct k_delayed_work *)k_timer_get_id(timer);
if (w->work_q == NULL) {
return;
if (atomic_test_and_clear_bit(work->flags, K_WORK_STATE_PENDING)) {
work->handler(work);
}
/* submit work to workqueue */
if (!atomic_test_bit(w->work.flags, K_WORK_STATE_PERIODIC)) {
k_work_submit_to_queue(w->work_q, &w->work);
/* detach from workqueue, for cancel to return appropriate status */
w->work_q = NULL;
} else {
/* For periodic timer, restart it.*/
k_timer_reset(&w->timer);
k_work_submit_to_queue(w->work_q, &w->work);
}
k_yield();
}
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
{
ASSERT(work, "delay work is NULL");
/* Added by bouffalolab */
k_work_init(&work->work, handler);
k_timer_init(&work->timer, work_timeout, work);
int k_work_q_start(void) {
k_fifo_init(&g_work_queue_main.fifo, 20);
return k_thread_create(&work_q_thread, "work_q_thread", CONFIG_BT_WORK_QUEUE_STACK_SIZE, work_queue_main, CONFIG_BT_WORK_QUEUE_PRIO);
}
int k_work_init(struct k_work *work, k_work_handler_t handler) {
ASSERT(work, "work is NULL");
atomic_clear(work->flags);
work->handler = handler;
return 0;
}
void k_work_submit(struct k_work *work) { k_work_submit_to_queue(&g_work_queue_main, work); }
static void work_timeout(void *timer) {
/* Parameter timer type is */
struct k_delayed_work *w = (struct k_delayed_work *)k_timer_get_id(timer);
if (w->work_q == NULL) {
return;
}
/* submit work to workqueue */
if (!atomic_test_bit(w->work.flags, K_WORK_STATE_PERIODIC)) {
k_work_submit_to_queue(w->work_q, &w->work);
/* detach from workqueue, for cancel to return appropriate status */
w->work_q = NULL;
} else {
/* For periodic timer, restart it.*/
k_timer_reset(&w->timer);
k_work_submit_to_queue(w->work_q, &w->work);
}
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) {
ASSERT(work, "delay work is NULL");
/* Added by bouffalolab */
k_work_init(&work->work, handler);
k_timer_init(&work->timer, work_timeout, work);
work->work_q = NULL;
}
static int k_delayed_work_submit_to_queue(struct k_work_q *work_q, struct k_delayed_work *work, uint32_t delay) {
int err;
/* Work cannot be active in multiple queues */
if (work->work_q && work->work_q != work_q) {
err = -EADDRINUSE;
goto done;
}
/* Cancel if work has been submitted */
if (work->work_q == work_q) {
err = k_delayed_work_cancel(work);
if (err < 0) {
goto done;
}
}
if (!delay) {
/* Submit work if no ticks is 0 */
k_work_submit_to_queue(work_q, &work->work);
work->work_q = NULL;
}
} else {
/* Add timeout */
/* Attach workqueue so the timeout callback can submit it */
k_timer_start(&work->timer, delay);
work->work_q = work_q;
}
static int k_delayed_work_submit_to_queue(struct k_work_q *work_q,
struct k_delayed_work *work,
uint32_t delay)
{
int err;
/* Work cannot be active in multiple queues */
if (work->work_q && work->work_q != work_q) {
err = -EADDRINUSE;
goto done;
}
/* Cancel if work has been submitted */
if (work->work_q == work_q) {
err = k_delayed_work_cancel(work);
if (err < 0) {
goto done;
}
}
if (!delay) {
/* Submit work if no ticks is 0 */
k_work_submit_to_queue(work_q, &work->work);
work->work_q = NULL;
} else {
/* Add timeout */
/* Attach workqueue so the timeout callback can submit it */
k_timer_start(&work->timer, delay);
work->work_q = work_q;
}
err = 0;
err = 0;
done:
return err;
return err;
}
int k_delayed_work_submit(struct k_delayed_work *work, uint32_t delay)
{
atomic_clear_bit(work->work.flags, K_WORK_STATE_PERIODIC);
return k_delayed_work_submit_to_queue(&g_work_queue_main, work, delay);
int k_delayed_work_submit(struct k_delayed_work *work, uint32_t delay) {
atomic_clear_bit(work->work.flags, K_WORK_STATE_PERIODIC);
return k_delayed_work_submit_to_queue(&g_work_queue_main, work, delay);
}
/* Added by bouffalolab */
int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period)
{
atomic_set_bit(work->work.flags, K_WORK_STATE_PERIODIC);
return k_delayed_work_submit_to_queue(&g_work_queue_main, work, period);
int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period) {
atomic_set_bit(work->work.flags, K_WORK_STATE_PERIODIC);
return k_delayed_work_submit_to_queue(&g_work_queue_main, work, period);
}
int k_delayed_work_cancel(struct k_delayed_work *work)
{
int err = 0;
int k_delayed_work_cancel(struct k_delayed_work *work) {
int err = 0;
if (atomic_test_bit(work->work.flags, K_WORK_STATE_PENDING)) {
err = -EINPROGRESS;
goto exit;
}
if (atomic_test_bit(work->work.flags, K_WORK_STATE_PENDING)) {
err = -EINPROGRESS;
goto exit;
}
if (!work->work_q) {
err = -EINVAL;
goto exit;
}
if (!work->work_q) {
err = -EINVAL;
goto exit;
}
k_timer_stop(&work->timer);
work->work_q = NULL;
work->timer.timeout = 0;
work->timer.start_ms = 0;
k_timer_stop(&work->timer);
work->work_q = NULL;
work->timer.timeout = 0;
work->timer.start_ms = 0;
exit:
return err;
return err;
}
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
{
int32_t remain;
k_timer_t *timer;
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work) {
int32_t remain;
k_timer_t *timer;
if (work == NULL) {
return 0;
}
if (work == NULL) {
return 0;
}
timer = &work->timer;
remain = timer->timeout - (k_now_ms() - timer->start_ms);
if (remain < 0) {
remain = 0;
}
return remain;
timer = &work->timer;
remain = timer->timeout - (k_now_ms() - timer->start_ms);
if (remain < 0) {
remain = 0;
}
return remain;
}
void k_delayed_work_del_timer(struct k_delayed_work *work)
{
if (NULL == work || NULL == work->timer.timer.hdl)
return;
void k_delayed_work_del_timer(struct k_delayed_work *work) {
if (NULL == work || NULL == work->timer.timer.hdl) {
return;
}
k_timer_delete(&work->timer);
work->timer.timer.hdl = NULL;
k_timer_delete(&work->timer);
work->timer.timer.hdl = NULL;
}
/* Added by bouffalolab */
int k_delayed_work_free(struct k_delayed_work *work)
{
int err = 0;
int k_delayed_work_free(struct k_delayed_work *work) {
int err = 0;
if (atomic_test_bit(work->work.flags, K_WORK_STATE_PENDING)) {
err = -EINPROGRESS;
goto exit;
}
if (atomic_test_bit(work->work.flags, K_WORK_STATE_PENDING)) {
err = -EINPROGRESS;
goto exit;
}
k_delayed_work_del_timer(work);
work->work_q = NULL;
work->timer.timeout = 0;
work->timer.start_ms = 0;
k_delayed_work_del_timer(work);
work->work_q = NULL;
work->timer.timeout = 0;
work->timer.start_ms = 0;
exit:
return err;
return err;
}
#else
static void work_q_main(void *work_q_ptr, void *p2, void *p3)
{
struct k_work_q *work_q = work_q_ptr;
static void work_q_main(void *work_q_ptr, void *p2, void *p3) {
struct k_work_q *work_q = work_q_ptr;
ARG_UNUSED(p2);
ARG_UNUSED(p3);
ARG_UNUSED(p2);
ARG_UNUSED(p3);
while (1) {
struct k_work *work;
k_work_handler_t handler;
while (1) {
struct k_work *work;
k_work_handler_t handler;
work = k_queue_get(&work_q->queue, K_FOREVER);
if (!work) {
continue;
}
handler = work->handler;
/* Reset pending state so it can be resubmitted by handler */
if (atomic_test_and_clear_bit(work->flags,
K_WORK_STATE_PENDING)) {
handler(work);
}
/* Make sure we don't hog up the CPU if the FIFO never (or
* very rarely) gets empty.
*/
k_yield();
work = k_queue_get(&work_q->queue, K_FOREVER);
if (!work) {
continue;
}
handler = work->handler;
/* Reset pending state so it can be resubmitted by handler */
if (atomic_test_and_clear_bit(work->flags, K_WORK_STATE_PENDING)) {
handler(work);
}
/* Make sure we don't hog up the CPU if the FIFO never (or
* very rarely) gets empty.
*/
k_yield();
}
}
void k_work_q_start(struct k_work_q *work_q, k_thread_stack_t *stack,
size_t stack_size, int prio)
{
k_queue_init(&work_q->queue, 20);
k_thread_create(&work_q->thread, stack, stack_size, work_q_main,
work_q, 0, 0, prio, 0, 0);
_k_object_init(work_q);
void k_work_q_start(struct k_work_q *work_q, k_thread_stack_t *stack, size_t stack_size, int prio) {
k_queue_init(&work_q->queue, 20);
k_thread_create(&work_q->thread, stack, stack_size, work_q_main, work_q, 0, 0, prio, 0, 0);
_k_object_init(work_q);
}
#ifdef CONFIG_SYS_CLOCK_EXISTS
static void work_timeout(struct _timeout *t)
{
struct k_delayed_work *w = CONTAINER_OF(t, struct k_delayed_work,
timeout);
static void work_timeout(struct _timeout *t) {
struct k_delayed_work *w = CONTAINER_OF(t, struct k_delayed_work, timeout);
/* submit work to workqueue */
k_work_submit_to_queue(w->work_q, &w->work);
/* submit work to workqueue */
k_work_submit_to_queue(w->work_q, &w->work);
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
{
k_work_init(&work->work, handler);
_init_timeout(&work->timeout, work_timeout);
work->work_q = NULL;
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) {
k_work_init(&work->work, handler);
_init_timeout(&work->timeout, work_timeout);
work->work_q = NULL;
_k_object_init(work);
_k_object_init(work);
}
int k_delayed_work_submit_to_queue(struct k_work_q *work_q,
struct k_delayed_work *work,
s32_t delay)
{
unsigned int key = irq_lock();
int err;
int k_delayed_work_submit_to_queue(struct k_work_q *work_q, struct k_delayed_work *work, s32_t delay) {
unsigned int key = irq_lock();
int err;
/* Work cannot be active in multiple queues */
if (work->work_q && work->work_q != work_q) {
err = -EADDRINUSE;
goto done;
/* Work cannot be active in multiple queues */
if (work->work_q && work->work_q != work_q) {
err = -EADDRINUSE;
goto done;
}
/* Cancel if work has been submitted */
if (work->work_q == work_q) {
err = k_delayed_work_cancel(work);
if (err < 0) {
goto done;
}
}
/* Cancel if work has been submitted */
if (work->work_q == work_q) {
err = k_delayed_work_cancel(work);
if (err < 0) {
goto done;
}
}
/* Attach workqueue so the timeout callback can submit it */
work->work_q = work_q;
/* Attach workqueue so the timeout callback can submit it */
work->work_q = work_q;
if (!delay) {
/* Submit work if no ticks is 0 */
k_work_submit_to_queue(work_q, &work->work);
} else {
/* Add timeout */
_add_timeout(NULL, &work->timeout, NULL, _TICK_ALIGN + _ms_to_ticks(delay));
}
if (!delay) {
/* Submit work if no ticks is 0 */
k_work_submit_to_queue(work_q, &work->work);
} else {
/* Add timeout */
_add_timeout(NULL, &work->timeout, NULL,
_TICK_ALIGN + _ms_to_ticks(delay));
}
err = 0;
err = 0;
done:
irq_unlock(key);
irq_unlock(key);
return err;
return err;
}
int k_delayed_work_cancel(struct k_delayed_work *work)
{
unsigned int key = irq_lock();
int k_delayed_work_cancel(struct k_delayed_work *work) {
unsigned int key = irq_lock();
if (!work->work_q) {
irq_unlock(key);
return -EINVAL;
}
if (k_work_pending(&work->work)) {
/* Remove from the queue if already submitted */
if (!k_queue_remove(&work->work_q->queue, &work->work)) {
irq_unlock(key);
return -EINVAL;
}
} else {
_abort_timeout(&work->timeout);
}
/* Detach from workqueue */
work->work_q = NULL;
atomic_clear_bit(work->work.flags, K_WORK_STATE_PENDING);
if (!work->work_q) {
irq_unlock(key);
return -EINVAL;
}
return 0;
if (k_work_pending(&work->work)) {
/* Remove from the queue if already submitted */
if (!k_queue_remove(&work->work_q->queue, &work->work)) {
irq_unlock(key);
return -EINVAL;
}
} else {
_abort_timeout(&work->timeout);
}
/* Detach from workqueue */
work->work_q = NULL;
atomic_clear_bit(work->work.flags, K_WORK_STATE_PENDING);
irq_unlock(key);
return 0;
}
#endif /* CONFIG_SYS_CLOCK_EXISTS */
#endif /* BFLB_BLE */

View File

@@ -10,20 +10,20 @@
#include <string.h>
#include <zephyr.h>
//#include <soc.h>
//#include <init.h>
//#include <device.h>
//#include <clock_control.h>
// #include <soc.h>
// #include <init.h>
// #include <device.h>
// #include <clock_control.h>
#include <FreeRTOS.h>
#include <include/atomic.h>
#include <misc/util.h>
#include <misc/stack.h>
#include <misc/byteorder.h>
#include <misc/stack.h>
#include <misc/util.h>
#include <bluetooth.h>
#include <hci_host.h>
#include <hci_driver.h>
#include <hci_host.h>
#ifdef CONFIG_CLOCK_CONTROL_NRF5
#include <drivers/clock_control/nrf5_clock_control.h>
@@ -32,20 +32,19 @@
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#include "log.h"
//#include "util/util.h"
//#include "hal/ccm.h"
//#include "hal/radio.h"
//#include "ll_sw/pdu.h"
//#include "ll_sw/ctrl.h"
// #include "util/util.h"
// #include "hal/ccm.h"
// #include "hal/radio.h"
// #include "ll_sw/pdu.h"
// #include "ll_sw/ctrl.h"
#include "hci_internal.h"
//#include "init.h"
//#include "hal/debug.h"
// #include "init.h"
// #include "hal/debug.h"
#if defined(BFLB_BLE)
#include "bl_hci_wrapper.h"
#endif
#define NODE_RX(_node) CONTAINER_OF(_node, struct radio_pdu_node_rx, \
hdr.onion.node)
#define NODE_RX(_node) CONTAINER_OF(_node, struct radio_pdu_node_rx, hdr.onion.node)
#if !defined(BFLB_BLE)
static K_SEM_DEFINE(sem_prio_recv, 0, BT_UINT_MAX);
@@ -54,13 +53,12 @@ static K_SEM_DEFINE(sem_prio_recv, 0, BT_UINT_MAX);
K_FIFO_DEFINE(recv_fifo);
#if (BFLB_BLE_CO_THREAD)
extern struct k_sem g_poll_sem;
static int recv_fifo_count = 0;
static int recv_fifo_count = 0;
#endif
#if !defined(BFLB_BLE)
struct k_thread prio_recv_thread_data;
static BT_STACK_NOINIT(prio_recv_thread_stack,
CONFIG_BT_CTLR_RX_PRIO_STACK_SIZE);
static BT_STACK_NOINIT(prio_recv_thread_stack, CONFIG_BT_CTLR_RX_PRIO_STACK_SIZE);
#endif
struct k_thread recv_thread_data;
@@ -74,487 +72,452 @@ static u32_t rx_ts;
#endif
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static struct k_poll_signal hbuf_signal =
K_POLL_SIGNAL_INITIALIZER(hbuf_signal);
static sys_slist_t hbuf_pend;
static s32_t hbuf_count;
static struct k_poll_signal hbuf_signal = K_POLL_SIGNAL_INITIALIZER(hbuf_signal);
static sys_slist_t hbuf_pend;
static s32_t hbuf_count;
#endif
#if !defined(BFLB_BLE)
static void prio_recv_thread(void *p1, void *p2, void *p3)
{
while (1) {
struct radio_pdu_node_rx *node_rx;
u8_t num_cmplt;
u16_t handle;
static void prio_recv_thread(void *p1, void *p2, void *p3) {
while (1) {
struct radio_pdu_node_rx *node_rx;
u8_t num_cmplt;
u16_t handle;
while ((num_cmplt = radio_rx_get(&node_rx, &handle))) {
while ((num_cmplt = radio_rx_get(&node_rx, &handle))) {
#if defined(CONFIG_BT_CONN)
struct net_buf *buf;
struct net_buf *buf;
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
hci_num_cmplt_encode(buf, handle, num_cmplt);
BT_DBG("Num Complete: 0x%04x:%u", handle, num_cmplt);
bt_recv_prio(buf);
k_yield();
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
hci_num_cmplt_encode(buf, handle, num_cmplt);
BT_DBG("Num Complete: 0x%04x:%u", handle, num_cmplt);
bt_recv_prio(buf);
k_yield();
#endif
}
}
if (node_rx) {
radio_rx_dequeue();
if (node_rx) {
radio_rx_dequeue();
BT_DBG("RX node enqueue");
k_fifo_put(&recv_fifo, node_rx);
BT_DBG("RX node enqueue");
k_fifo_put(&recv_fifo, node_rx);
continue;
}
continue;
}
BT_DBG("sem take...");
k_sem_take(&sem_prio_recv, K_FOREVER);
BT_DBG("sem taken");
BT_DBG("sem take...");
k_sem_take(&sem_prio_recv, K_FOREVER);
BT_DBG("sem taken");
#if defined(CONFIG_INIT_STACKS)
if (k_uptime_get_32() - prio_ts > K_SECONDS(5)) {
STACK_ANALYZE("prio recv thread stack",
prio_recv_thread_stack);
prio_ts = k_uptime_get_32();
}
#endif
if (k_uptime_get_32() - prio_ts > K_SECONDS(5)) {
STACK_ANALYZE("prio recv thread stack", prio_recv_thread_stack);
prio_ts = k_uptime_get_32();
}
#endif
}
}
static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx,
s8_t class)
{
struct net_buf *buf = NULL;
static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx, s8_t class) {
struct net_buf *buf = NULL;
/* Check if we need to generate an HCI event or ACL data */
switch (class) {
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
case HCI_CLASS_EVT_CONNECTION:
if (class == HCI_CLASS_EVT_DISCARDABLE) {
buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT);
} else {
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
}
if (buf) {
hci_evt_encode(node_rx, buf);
}
break;
#if defined(CONFIG_BT_CONN)
case HCI_CLASS_ACL_DATA:
/* generate ACL data */
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
hci_acl_encode(node_rx, buf);
break;
#endif
default:
LL_ASSERT(0);
break;
}
radio_rx_fc_set(node_rx->hdr.handle, 0);
node_rx->hdr.onion.next = 0;
radio_rx_mem_release(&node_rx);
return buf;
}
static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
{
s8_t class = hci_get_class(node_rx);
struct net_buf *buf = NULL;
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
if (hbuf_count != -1) {
bool pend = !sys_slist_is_empty(&hbuf_pend);
/* controller to host flow control enabled */
switch (class) {
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
break;
case HCI_CLASS_EVT_CONNECTION:
/* for conn-related events, only pend is relevant */
hbuf_count = 1;
/* fallthrough */
case HCI_CLASS_ACL_DATA:
if (pend || !hbuf_count) {
sys_slist_append(&hbuf_pend,
&node_rx->hdr.onion.node);
BT_DBG("FC: Queuing item: %d", class);
return NULL;
}
break;
default:
LL_ASSERT(0);
break;
}
}
#endif
/* process regular node from radio */
buf = encode_node(node_rx, class);
return buf;
}
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
{
/* shadow total count in case of preemption */
struct radio_pdu_node_rx *node_rx = NULL;
s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL;
sys_snode_t *node = NULL;
s8_t class;
int reset;
reset = atomic_test_and_clear_bit(&hci_state_mask, HCI_STATE_BIT_RESET);
if (reset) {
/* flush queue, no need to free, the LL has already done it */
sys_slist_init(&hbuf_pend);
}
if (hbuf_total <= 0) {
hbuf_count = -1;
return NULL;
}
/* available host buffers */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */
node = sys_slist_peek_head(&hbuf_pend);
if (!node) {
return NULL;
}
/* Return early if this iteration already has a node to process */
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (n) {
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* node to process later, schedule an iteration */
BT_DBG("FC: signalling");
k_poll_signal_raise(&hbuf_signal, 0x0);
}
return NULL;
}
switch (class) {
case HCI_CLASS_EVT_CONNECTION:
BT_DBG("FC: dequeueing event");
(void)sys_slist_get(&hbuf_pend);
break;
case HCI_CLASS_ACL_DATA:
if (hbuf_count) {
BT_DBG("FC: dequeueing ACL data");
(void)sys_slist_get(&hbuf_pend);
} else {
/* no buffers, HCI will signal */
node = NULL;
}
break;
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
default:
LL_ASSERT(0);
break;
}
if (node) {
buf = encode_node(node_rx, class);
/* Update host buffers after encoding */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* next node */
node = sys_slist_peek_head(&hbuf_pend);
if (node) {
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (class == HCI_CLASS_EVT_CONNECTION ||
(class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* more to process, schedule an
* iteration
*/
BT_DBG("FC: signalling");
k_poll_signal_raise(&hbuf_signal, 0x0);
}
}
}
return buf;
}
#endif
#endif
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
void co_rx_thread()
{
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_NO_WAIT);
if (buf) {
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
}
void co_tx_rx_thread(void *p1)
{
UNUSED(p1);
BT_DBG("using %s\n", __func__);
while (1) {
if (k_sem_count_get(&g_poll_sem) > 0) {
co_tx_thread();
}
if (recv_fifo_count > 0) {
recv_fifo_count--;
co_rx_thread();
}
k_sleep(portTICK_PERIOD_MS);
k_yield();
}
}
#else
static void recv_thread(void *p1)
{
UNUSED(p1);
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
/* @todo: check if the events structure really needs to be static */
static struct k_poll_event events[2] = {
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SIGNAL,
K_POLL_MODE_NOTIFY_ONLY,
&hbuf_signal, 0),
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&recv_fifo, 0),
};
#endif
while (1) {
#if defined(BFLB_BLE)
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_FOREVER);
if (buf) {
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
#else
struct radio_pdu_node_rx *node_rx = NULL;
struct net_buf *buf = NULL;
BT_DBG("blocking");
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
int err;
err = k_poll(events, 2, K_FOREVER);
LL_ASSERT(err == 0);
if (events[0].state == K_POLL_STATE_SIGNALED) {
events[0].signal->signaled = 0;
} else if (events[1].state ==
K_POLL_STATE_FIFO_DATA_AVAILABLE) {
node_rx = k_fifo_get(events[1].fifo, 0);
}
events[0].state = K_POLL_STATE_NOT_READY;
events[1].state = K_POLL_STATE_NOT_READY;
/* process host buffers first if any */
buf = process_hbuf(node_rx);
#else
node_rx = k_fifo_get(&recv_fifo, K_FOREVER);
#endif
BT_DBG("unblocked");
if (node_rx && !buf) {
/* process regular node from radio */
buf = process_node(node_rx);
}
if (buf) {
if (buf->len) {
BT_DBG("Packet in: type:%u len:%u",
bt_buf_get_type(buf), buf->len);
bt_recv(buf);
} else {
net_buf_unref(buf);
}
}
#endif
k_yield();
#if defined(CONFIG_INIT_STACKS)
if (k_uptime_get_32() - rx_ts > K_SECONDS(5)) {
STACK_ANALYZE("recv thread stack", recv_thread_stack);
rx_ts = k_uptime_get_32();
}
#endif
}
}
#endif
#endif
#if !defined(BFLB_BLE)
static int cmd_handle(struct net_buf *buf)
{
struct net_buf *evt;
evt = hci_cmd_handle(buf);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
}
#if defined(CONFIG_BT_CONN)
static int acl_handle(struct net_buf *buf)
{
struct net_buf *evt;
int err;
err = hci_acl_handle(buf, &evt);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
return err;
}
#endif /* CONFIG_BT_CONN */
#endif
static int hci_driver_send(struct net_buf *buf)
{
#if !defined(BFLB_BLE)
u8_t type;
#endif
int err;
BT_DBG("enter");
if (!buf->len) {
BT_ERR("Empty HCI packet");
return -EINVAL;
}
#if defined(BFLB_BLE)
err = bl_onchiphci_send_2_controller(buf);
net_buf_unref(buf);
return err;
#else
type = bt_buf_get_type(buf);
switch (type) {
#if defined(CONFIG_BT_CONN)
case BT_BUF_ACL_OUT:
err = acl_handle(buf);
break;
#endif /* CONFIG_BT_CONN */
case BT_BUF_CMD:
err = cmd_handle(buf);
break;
default:
BT_ERR("Unknown HCI type %u", type);
return -EINVAL;
}
if (!err) {
net_buf_unref(buf);
/* Check if we need to generate an HCI event or ACL data */
switch (class) {
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
case HCI_CLASS_EVT_CONNECTION:
if (class == HCI_CLASS_EVT_DISCARDABLE) {
buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT);
} else {
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
}
BT_DBG("exit: %d", err);
if (buf) {
hci_evt_encode(node_rx, buf);
}
break;
#if defined(CONFIG_BT_CONN)
case HCI_CLASS_ACL_DATA:
/* generate ACL data */
buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
hci_acl_encode(node_rx, buf);
break;
#endif
return err;
default:
LL_ASSERT(0);
break;
}
radio_rx_fc_set(node_rx->hdr.handle, 0);
node_rx->hdr.onion.next = 0;
radio_rx_mem_release(&node_rx);
return buf;
}
static int hci_driver_open(void)
{
#if !defined(BFLB_BLE)
u32_t err;
static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx) {
s8_t class = hci_get_class(node_rx);
struct net_buf *buf = NULL;
DEBUG_INIT();
k_sem_init(&sem_prio_recv, 0, BT_UINT_MAX);
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
if (hbuf_count != -1) {
bool pend = !sys_slist_is_empty(&hbuf_pend);
err = ll_init(&sem_prio_recv);
if (err) {
BT_ERR("LL initialization failed: %u", err);
return err;
/* controller to host flow control enabled */
switch (class) {
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
break;
case HCI_CLASS_EVT_CONNECTION:
/* for conn-related events, only pend is relevant */
hbuf_count = 1;
/* fallthrough */
case HCI_CLASS_ACL_DATA:
if (pend || !hbuf_count) {
sys_slist_append(&hbuf_pend, &node_rx->hdr.onion.node);
BT_DBG("FC: Queuing item: %d", class);
return NULL;
}
break;
default:
LL_ASSERT(0);
break;
}
}
#endif
/* process regular node from radio */
buf = encode_node(node_rx, class);
return buf;
}
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n) {
/* shadow total count in case of preemption */
struct radio_pdu_node_rx *node_rx = NULL;
s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL;
sys_snode_t *node = NULL;
s8_t class;
int reset;
reset = atomic_test_and_clear_bit(&hci_state_mask, HCI_STATE_BIT_RESET);
if (reset) {
/* flush queue, no need to free, the LL has already done it */
sys_slist_init(&hbuf_pend);
}
if (hbuf_total <= 0) {
hbuf_count = -1;
return NULL;
}
/* available host buffers */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */
node = sys_slist_peek_head(&hbuf_pend);
if (!node) {
return NULL;
}
/* Return early if this iteration already has a node to process */
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (n) {
if (class == HCI_CLASS_EVT_CONNECTION || (class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* node to process later, schedule an iteration */
BT_DBG("FC: signalling");
k_poll_signal_raise(&hbuf_signal, 0x0);
}
return NULL;
}
switch (class) {
case HCI_CLASS_EVT_CONNECTION:
BT_DBG("FC: dequeueing event");
(void)sys_slist_get(&hbuf_pend);
break;
case HCI_CLASS_ACL_DATA:
if (hbuf_count) {
BT_DBG("FC: dequeueing ACL data");
(void)sys_slist_get(&hbuf_pend);
} else {
/* no buffers, HCI will signal */
node = NULL;
}
break;
case HCI_CLASS_EVT_DISCARDABLE:
case HCI_CLASS_EVT_REQUIRED:
default:
LL_ASSERT(0);
break;
}
if (node) {
buf = encode_node(node_rx, class);
/* Update host buffers after encoding */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* next node */
node = sys_slist_peek_head(&hbuf_pend);
if (node) {
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (class == HCI_CLASS_EVT_CONNECTION || (class == HCI_CLASS_ACL_DATA && hbuf_count)) {
/* more to process, schedule an
* iteration
*/
BT_DBG("FC: signalling");
k_poll_signal_raise(&hbuf_signal, 0x0);
}
}
}
return buf;
}
#endif
#endif
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
void co_rx_thread() {
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_NO_WAIT);
if (buf) {
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
}
void co_tx_rx_thread(void *p1) {
UNUSED(p1);
BT_DBG("using %s\n", __func__);
while (1) {
if (k_sem_count_get(&g_poll_sem) > 0) {
co_tx_thread();
}
if (recv_fifo_count > 0) {
recv_fifo_count--;
co_rx_thread();
}
k_sleep(portTICK_PERIOD_MS);
k_yield();
}
}
#else
static void recv_thread(void *p1) {
UNUSED(p1);
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
/* @todo: check if the events structure really needs to be static */
static struct k_poll_event events[2] = {
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &hbuf_signal, 0),
K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &recv_fifo, 0),
};
#endif
while (1) {
#if defined(BFLB_BLE)
struct net_buf *buf = NULL;
buf = net_buf_get(&recv_fifo, K_FOREVER);
if (buf) {
BT_DBG("Calling bt_recv(%p)", buf);
bt_recv(buf);
}
#else
struct radio_pdu_node_rx *node_rx = NULL;
struct net_buf *buf = NULL;
BT_DBG("blocking");
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
int err;
err = k_poll(events, 2, K_FOREVER);
LL_ASSERT(err == 0);
if (events[0].state == K_POLL_STATE_SIGNALED) {
events[0].signal->signaled = 0;
} else if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) {
node_rx = k_fifo_get(events[1].fifo, 0);
}
events[0].state = K_POLL_STATE_NOT_READY;
events[1].state = K_POLL_STATE_NOT_READY;
/* process host buffers first if any */
buf = process_hbuf(node_rx);
#else
node_rx = k_fifo_get(&recv_fifo, K_FOREVER);
#endif
BT_DBG("unblocked");
if (node_rx && !buf) {
/* process regular node from radio */
buf = process_node(node_rx);
}
if (buf) {
if (buf->len) {
BT_DBG("Packet in: type:%u len:%u", bt_buf_get_type(buf), buf->len);
bt_recv(buf);
} else {
net_buf_unref(buf);
}
}
#endif
k_yield();
#if defined(CONFIG_INIT_STACKS)
if (k_uptime_get_32() - rx_ts > K_SECONDS(5)) {
STACK_ANALYZE("recv thread stack", recv_thread_stack);
rx_ts = k_uptime_get_32();
}
#endif
}
}
#endif
#endif
#if !defined(BFLB_BLE)
static int cmd_handle(struct net_buf *buf) {
struct net_buf *evt;
evt = hci_cmd_handle(buf);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
}
#if defined(CONFIG_BT_CONN)
static int acl_handle(struct net_buf *buf) {
struct net_buf *evt;
int err;
err = hci_acl_handle(buf, &evt);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
return err;
}
#endif /* CONFIG_BT_CONN */
#endif
static int hci_driver_send(struct net_buf *buf) {
#if !defined(BFLB_BLE)
u8_t type;
#endif
int err;
BT_DBG("enter");
if (!buf->len) {
BT_ERR("Empty HCI packet");
return -EINVAL;
}
#if defined(BFLB_BLE)
err = bl_onchiphci_send_2_controller(buf);
net_buf_unref(buf);
return err;
#else
type = bt_buf_get_type(buf);
switch (type) {
#if defined(CONFIG_BT_CONN)
case BT_BUF_ACL_OUT:
err = acl_handle(buf);
break;
#endif /* CONFIG_BT_CONN */
case BT_BUF_CMD:
err = cmd_handle(buf);
break;
default:
BT_ERR("Unknown HCI type %u", type);
return -EINVAL;
}
if (!err) {
net_buf_unref(buf);
} else {
}
BT_DBG("exit: %d", err);
#endif
return err;
}
static int hci_driver_open(void) {
#if !defined(BFLB_BLE)
u32_t err;
DEBUG_INIT();
k_sem_init(&sem_prio_recv, 0, BT_UINT_MAX);
err = ll_init(&sem_prio_recv);
if (err) {
BT_ERR("LL initialization failed: %u", err);
return err;
}
#endif
#if !defined(BFLB_BLE)
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
hci_init(&hbuf_signal);
hci_init(&hbuf_signal);
#else
hci_init(NULL);
hci_init(NULL);
#endif
#endif
k_fifo_init(&recv_fifo, 20);
k_fifo_init(&recv_fifo, 20);
#if defined(BFLB_BLE)
#if (BFLB_BLE_CO_THREAD)
k_thread_create(&recv_thread_data, "co_tx_rx_thread",
CONFIG_BT_RX_STACK_SIZE,
co_tx_rx_thread,
K_PRIO_COOP(CONFIG_BT_RX_PRIO));
k_thread_create(&recv_thread_data, "co_tx_rx_thread", CONFIG_BT_RX_STACK_SIZE, co_tx_rx_thread, K_PRIO_COOP(CONFIG_BT_RX_PRIO));
#else
k_thread_create(&recv_thread_data, "recv_thread",
CONFIG_BT_RX_STACK_SIZE /*K_THREAD_STACK_SIZEOF(recv_thread_stack)*/,
recv_thread,
K_PRIO_COOP(CONFIG_BT_RX_PRIO));
k_thread_create(&recv_thread_data, "recv_thread", CONFIG_BT_RX_STACK_SIZE /*K_THREAD_STACK_SIZEOF(recv_thread_stack)*/, recv_thread, K_PRIO_COOP(CONFIG_BT_RX_PRIO));
#endif
#else
k_thread_create(&prio_recv_thread_data, prio_recv_thread_stack,
K_THREAD_STACK_SIZEOF(prio_recv_thread_stack),
prio_recv_thread, NULL, NULL, NULL,
K_PRIO_COOP(CONFIG_BT_CTLR_RX_PRIO), 0, K_NO_WAIT);
k_thread_create(&prio_recv_thread_data, prio_recv_thread_stack, K_THREAD_STACK_SIZEOF(prio_recv_thread_stack), prio_recv_thread, NULL, NULL, NULL, K_PRIO_COOP(CONFIG_BT_CTLR_RX_PRIO), 0, K_NO_WAIT);
#endif
BT_DBG("Success.");
BT_DBG("Success.");
return 0;
return 0;
}
void hci_driver_enque_recvq(struct net_buf *buf)
{
net_buf_put(&recv_fifo, buf);
void hci_driver_enque_recvq(struct net_buf *buf) {
net_buf_put(&recv_fifo, buf);
#if (BFLB_BLE_CO_THREAD)
recv_fifo_count++;
recv_fifo_count++;
#endif
}
static const struct bt_hci_driver drv = {
.name = "Controller",
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
.open = hci_driver_open,
.send = hci_driver_send,
};
#if defined(BFLB_BLE)
int hci_driver_init(void)
{
bt_hci_driver_register(&drv);
int hci_driver_init(void) {
bt_hci_driver_register(&drv);
return 0;
return 0;
}
#else
static int _hci_driver_init(struct device *unused)
{
ARG_UNUSED(unused);
static int _hci_driver_init(struct device *unused) {
ARG_UNUSED(unused);
bt_hci_driver_register(&drv);
bt_hci_driver_register(&drv);
return 0;
return 0;
}
//SYS_INIT(_hci_driver_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
// SYS_INIT(_hci_driver_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
#endif

View File

@@ -8,84 +8,61 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <atomic.h>
#include <byteorder.h>
#include <util.h>
#include <errno.h>
#include <printk.h>
#include <assert.h>
#include <string.h>
#include <util.h>
#include <zephyr.h>
#include <a2dp.h>
#include <avdtp.h>
#include <bluetooth.h>
#include <l2cap.h>
#include <avdtp.h>
#include <a2dp.h>
#include <sdp.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_A2DP)
#define LOG_MODULE_NAME bt_a2dp
#include "log.h"
#include "hci_core.h"
#include "conn_internal.h"
#include "avdtp_internal.h"
#include "a2dp_internal.h"
#include "a2dp-codec.h"
#include "a2dp_internal.h"
#include "avdtp_internal.h"
#include "conn_internal.h"
#include "hci_core.h"
#include "oi_codec_sbc.h"
#define A2DP_NO_SPACE (-1)
struct bt_a2dp {
struct bt_avdtp session;
struct bt_avdtp session;
};
typedef struct {
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
uint32_t context_data[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_CODEC_FAST_FILTER_BUFFERS)];
int16_t decode_buf[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
OI_CODEC_SBC_DECODER_CONTEXT decoder_context;
uint32_t context_data[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_CODEC_FAST_FILTER_BUFFERS)];
int16_t decode_buf[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
} A2DP_SBC_DECODER;
static A2DP_SBC_DECODER sbc_decoder;
/* Connections */
static struct bt_a2dp connection[CONFIG_BT_MAX_CONN];
static struct bt_a2dp connection[CONFIG_BT_MAX_CONN];
static struct bt_avdtp_stream stream[CONFIG_BT_MAX_CONN];
static struct bt_sdp_attribute a2dp_attrs[] = {
BT_SDP_NEW_SERVICE,
BT_SDP_LIST(
BT_SDP_ATTR_SVCLASS_ID_LIST,
BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
BT_SDP_ARRAY_16(BT_SDP_AUDIO_SINK_SVCLASS) }, )),
BT_SDP_LIST(
BT_SDP_ATTR_PROTO_DESC_LIST,
BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP) },
{ BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVDTP) }, ) },
{ BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVDTP) },
{ BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
BT_SDP_ARRAY_16(0x0102) }, ) }, )),
BT_SDP_LIST(
BT_SDP_ATTR_PROFILE_DESC_LIST,
BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
BT_SDP_DATA_ELEM_LIST(
{ BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
BT_SDP_ARRAY_16(BT_SDP_ADVANCED_AUDIO_SVCLASS) },
{ BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
BT_SDP_ARRAY_16(0x0102) }, ) }, )),
BT_SDP_LIST(BT_SDP_ATTR_SVCLASS_ID_LIST, BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3), BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE(BT_SDP_UUID16), BT_SDP_ARRAY_16(BT_SDP_AUDIO_SINK_SVCLASS)}, )),
BT_SDP_LIST(BT_SDP_ATTR_PROTO_DESC_LIST, BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16),
BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE(BT_SDP_UUID16), BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP)},
{BT_SDP_TYPE_SIZE(BT_SDP_UINT16), BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVDTP)}, )},
{BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE(BT_SDP_UUID16), BT_SDP_ARRAY_16(BT_L2CAP_PSM_AVDTP)}, {BT_SDP_TYPE_SIZE(BT_SDP_UINT16), BT_SDP_ARRAY_16(0x0102)}, )}, )),
BT_SDP_LIST(BT_SDP_ATTR_PROFILE_DESC_LIST, BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8),
BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE(BT_SDP_UUID16), BT_SDP_ARRAY_16(BT_SDP_ADVANCED_AUDIO_SVCLASS)},
{BT_SDP_TYPE_SIZE(BT_SDP_UINT16), BT_SDP_ARRAY_16(0x0102)}, )}, )),
BT_SDP_SERVICE_NAME("A2DP sink"),
};
@@ -96,164 +73,131 @@ struct bt_a2dp_endpoint endpoint_2;
struct bt_a2dp_codec_sbc_params sbc_info;
void bt_a2dp_set_sbc_codec_info()
{
sbc_info.config[0] =
//Sampling Frequency
A2DP_SBC_SAMP_FREQ_48000 |
A2DP_SBC_SAMP_FREQ_44100 |
A2DP_SBC_SAMP_FREQ_32000 |
A2DP_SBC_SAMP_FREQ_16000 |
//Channel Mode
A2DP_SBC_CH_MODE_JOINT |
A2DP_SBC_CH_MODE_STREO |
A2DP_SBC_CH_MODE_DUAL |
A2DP_SBC_CH_MODE_MONO;
sbc_info.config[1] =
//Block Length
A2DP_SBC_BLK_LEN_16 |
A2DP_SBC_BLK_LEN_12 |
A2DP_SBC_BLK_LEN_8 |
A2DP_SBC_BLK_LEN_4 |
//Subbands
A2DP_SBC_SUBBAND_8 |
A2DP_SBC_SUBBAND_4 |
//Allocation Method
A2DP_SBC_ALLOC_MTHD_SNR |
A2DP_SBC_ALLOC_MTHD_LOUDNESS;
sbc_info.min_bitpool = 2;
sbc_info.max_bitpool = 53;
void bt_a2dp_set_sbc_codec_info() {
sbc_info.config[0] =
// Sampling Frequency
A2DP_SBC_SAMP_FREQ_48000 | A2DP_SBC_SAMP_FREQ_44100 | A2DP_SBC_SAMP_FREQ_32000 | A2DP_SBC_SAMP_FREQ_16000 |
// Channel Mode
A2DP_SBC_CH_MODE_JOINT | A2DP_SBC_CH_MODE_STREO | A2DP_SBC_CH_MODE_DUAL | A2DP_SBC_CH_MODE_MONO;
sbc_info.config[1] =
// Block Length
A2DP_SBC_BLK_LEN_16 | A2DP_SBC_BLK_LEN_12 | A2DP_SBC_BLK_LEN_8 | A2DP_SBC_BLK_LEN_4 |
// Subbands
A2DP_SBC_SUBBAND_8 | A2DP_SBC_SUBBAND_4 |
// Allocation Method
A2DP_SBC_ALLOC_MTHD_SNR | A2DP_SBC_ALLOC_MTHD_LOUDNESS;
sbc_info.min_bitpool = 2;
sbc_info.max_bitpool = 53;
}
void a2d_reset(struct bt_a2dp *a2dp_conn)
{
(void)memset(a2dp_conn, 0, sizeof(struct bt_a2dp));
}
void a2d_reset(struct bt_a2dp *a2dp_conn) { (void)memset(a2dp_conn, 0, sizeof(struct bt_a2dp)); }
void stream_reset(struct bt_avdtp_stream *stream_conn)
{
(void)memset(stream_conn, 0, sizeof(struct bt_avdtp_stream));
}
void stream_reset(struct bt_avdtp_stream *stream_conn) { (void)memset(stream_conn, 0, sizeof(struct bt_avdtp_stream)); }
struct bt_a2dp *get_new_connection(struct bt_conn *conn)
{
int8_t i, free;
struct bt_a2dp *get_new_connection(struct bt_conn *conn) {
int8_t i, free;
free = A2DP_NO_SPACE;
free = A2DP_NO_SPACE;
if (!conn) {
BT_ERR("Invalid Input (err: %d)", -EINVAL);
if (!conn) {
BT_ERR("Invalid Input (err: %d)", -EINVAL);
return NULL;
}
/* Find a space */
for (i = 0; i < CONFIG_BT_MAX_CONN; i++) {
if (connection[i].session.br_chan.chan.conn == conn) {
BT_DBG("Conn already exists");
if (!connection[i].session.streams->chan.chan.conn) {
BT_DBG("Create AV stream");
return &connection[i];
} else {
BT_DBG("A2DP signal stream and AV stream already exists");
return NULL;
}
}
/* Find a space */
for (i = 0; i < CONFIG_BT_MAX_CONN; i++) {
if (connection[i].session.br_chan.chan.conn == conn) {
BT_DBG("Conn already exists");
if (!connection[i].session.streams->chan.chan.conn) {
BT_DBG("Create AV stream");
return &connection[i];
} else {
BT_DBG("A2DP signal stream and AV stream already exists");
return NULL;
}
}
if (!connection[i].session.br_chan.chan.conn &&
free == A2DP_NO_SPACE) {
BT_DBG("Create signal stream");
free = i;
}
if (!connection[i].session.br_chan.chan.conn && free == A2DP_NO_SPACE) {
BT_DBG("Create signal stream");
free = i;
}
}
if (free == A2DP_NO_SPACE) {
BT_DBG("More connection cannot be supported");
return NULL;
}
if (free == A2DP_NO_SPACE) {
BT_DBG("More connection cannot be supported");
return NULL;
}
/* Clean the memory area before returning */
a2d_reset(&connection[free]);
stream_reset(&stream[free]);
connection[free].session.streams = &stream[free];
/* Clean the memory area before returning */
a2d_reset(&connection[free]);
stream_reset(&stream[free]);
connection[free].session.streams = &stream[free];
return &connection[free];
return &connection[free];
}
int a2dp_accept(struct bt_conn *conn, struct bt_avdtp **session)
{
struct bt_a2dp *a2dp_conn;
int a2dp_accept(struct bt_conn *conn, struct bt_avdtp **session) {
struct bt_a2dp *a2dp_conn;
a2dp_conn = get_new_connection(conn);
if (!a2dp_conn) {
return -ENOMEM;
}
a2dp_conn = get_new_connection(conn);
if (!a2dp_conn) {
return -ENOMEM;
}
*session = &(a2dp_conn->session);
BT_DBG("session: %p", &(a2dp_conn->session));
*session = &(a2dp_conn->session);
BT_DBG("session: %p", &(a2dp_conn->session));
return 0;
return 0;
}
int a2dp_sbc_decode_init()
{
OI_STATUS status = OI_CODEC_SBC_DecoderReset(&sbc_decoder.decoder_context,
sbc_decoder.context_data,
sizeof(sbc_decoder.context_data),
2,
2,
false,
false);
if (!OI_SUCCESS(status)) {
BT_ERR("decode init failed with error: %d\n", status);
return status;
}
int a2dp_sbc_decode_init() {
OI_STATUS status = OI_CODEC_SBC_DecoderReset(&sbc_decoder.decoder_context, sbc_decoder.context_data, sizeof(sbc_decoder.context_data), 2, 2, false, false);
if (!OI_SUCCESS(status)) {
BT_ERR("decode init failed with error: %d\n", status);
return status;
}
return 0;
return 0;
}
#if PCM_PRINTF
extern int16_t cool_edit[];
extern int16_t cool_edit[];
extern uint32_t byte_index;
#endif
int a2dp_sbc_decode_process(uint8_t media_data[], uint16_t data_len)
{
//remove media header, expose sbc frame
const OI_BYTE *data = media_data + 12 + 1;
OI_UINT32 data_size = data_len - 12 - 1;
int a2dp_sbc_decode_process(uint8_t media_data[], uint16_t data_len) {
// remove media header, expose sbc frame
const OI_BYTE *data = media_data + 12 + 1;
OI_UINT32 data_size = data_len - 12 - 1;
if (data_size <= 0) {
BT_ERR("empty packet\n");
return -1;
if (data_size <= 0) {
BT_ERR("empty packet\n");
return -1;
}
if (data[0] != 0x9c) {
BT_ERR("sbc frame syncword error \n");
}
OI_INT16 *pcm = sbc_decoder.decode_buf;
OI_UINT32 pcm_size = sizeof(sbc_decoder.decode_buf);
OI_INT16 frame_count = OI_CODEC_SBC_FrameCount((OI_BYTE *)data, data_size);
BT_DBG("frame_count: %d\n", frame_count);
for (int i = 0; i < frame_count; i++) {
OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&sbc_decoder.decoder_context, &data, &data_size, pcm, &pcm_size);
if (!OI_SUCCESS(status)) {
BT_ERR("decoding failure with error: %d \n", status);
return -1;
}
if (data[0] != 0x9c) {
BT_ERR("sbc frame syncword error \n");
}
OI_INT16 *pcm = sbc_decoder.decode_buf;
OI_UINT32 pcm_size = sizeof(sbc_decoder.decode_buf);
OI_INT16 frame_count = OI_CODEC_SBC_FrameCount((OI_BYTE *)data, data_size);
BT_DBG("frame_count: %d\n", frame_count);
for (int i = 0; i < frame_count; i++) {
OI_STATUS status = OI_CODEC_SBC_DecodeFrame(&sbc_decoder.decoder_context,
&data,
&data_size,
pcm,
&pcm_size);
if (!OI_SUCCESS(status)) {
BT_ERR("decoding failure with error: %d \n", status);
return -1;
}
#if PCM_PRINTF
memcpy((OI_INT8 *)cool_edit + byte_index, pcm, pcm_size);
byte_index += pcm_size;
memcpy((OI_INT8 *)cool_edit + byte_index, pcm, pcm_size);
byte_index += pcm_size;
#endif
}
}
return 0;
return 0;
}
/* Callback for incoming requests */
@@ -262,82 +206,75 @@ static struct bt_avdtp_ind_cb cb_ind = {
};
/* The above callback structures need to be packed and passed to AVDTP */
static struct bt_avdtp_event_cb avdtp_cb = {
.ind = &cb_ind,
.accept = a2dp_accept
};
static struct bt_avdtp_event_cb avdtp_cb = {.ind = &cb_ind, .accept = a2dp_accept};
int bt_a2dp_init(void)
{
int err;
int bt_a2dp_init(void) {
int err;
/* Register event handlers with AVDTP */
err = bt_avdtp_register(&avdtp_cb);
if (err < 0) {
BT_ERR("A2DP registration failed");
return err;
}
/* Register event handlers with AVDTP */
err = bt_avdtp_register(&avdtp_cb);
if (err < 0) {
BT_ERR("A2DP registration failed");
return err;
}
/* Register SDP record */
err = bt_sdp_register_service(&a2dp_rec);
if (err < 0) {
BT_ERR("A2DP regist sdp record failed");
return err;
}
/* Register SDP record */
err = bt_sdp_register_service(&a2dp_rec);
if (err < 0) {
BT_ERR("A2DP regist sdp record failed");
return err;
}
int reg_1 = bt_a2dp_register_endpoint(&endpoint_1, BT_A2DP_AUDIO, BT_A2DP_SINK);
int reg_2 = bt_a2dp_register_endpoint(&endpoint_2, BT_A2DP_AUDIO, BT_A2DP_SINK);
if (reg_1 || reg_2) {
BT_ERR("A2DP registration endpoint 1 failed");
return err;
}
int reg_1 = bt_a2dp_register_endpoint(&endpoint_1, BT_A2DP_AUDIO, BT_A2DP_SINK);
int reg_2 = bt_a2dp_register_endpoint(&endpoint_2, BT_A2DP_AUDIO, BT_A2DP_SINK);
if (reg_1 || reg_2) {
BT_ERR("A2DP registration endpoint 1 failed");
return err;
}
bt_a2dp_set_sbc_codec_info();
bt_a2dp_set_sbc_codec_info();
err = a2dp_sbc_decode_init();
if (err < 0) {
BT_ERR("sbc codec init failed");
return err;
}
err = a2dp_sbc_decode_init();
if (err < 0) {
BT_ERR("sbc codec init failed");
return err;
}
BT_DBG("A2DP Initialized successfully.");
return 0;
BT_DBG("A2DP Initialized successfully.");
return 0;
}
struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn)
{
struct bt_a2dp *a2dp_conn;
int err;
struct bt_a2dp *bt_a2dp_connect(struct bt_conn *conn) {
struct bt_a2dp *a2dp_conn;
int err;
a2dp_conn = get_new_connection(conn);
if (!a2dp_conn) {
BT_ERR("Cannot allocate memory");
return NULL;
}
a2dp_conn = get_new_connection(conn);
if (!a2dp_conn) {
BT_ERR("Cannot allocate memory");
return NULL;
}
err = bt_avdtp_connect(conn, &(a2dp_conn->session));
if (err < 0) {
/* If error occurs, undo the saving and return the error */
a2d_reset(a2dp_conn);
BT_DBG("AVDTP Connect failed");
return NULL;
}
err = bt_avdtp_connect(conn, &(a2dp_conn->session));
if (err < 0) {
/* If error occurs, undo the saving and return the error */
a2d_reset(a2dp_conn);
BT_DBG("AVDTP Connect failed");
return NULL;
}
BT_DBG("Connect request sent");
return a2dp_conn;
BT_DBG("Connect request sent");
return a2dp_conn;
}
int bt_a2dp_register_endpoint(struct bt_a2dp_endpoint *endpoint,
uint8_t media_type, uint8_t role)
{
int err;
int bt_a2dp_register_endpoint(struct bt_a2dp_endpoint *endpoint, uint8_t media_type, uint8_t role) {
int err;
BT_ASSERT(endpoint);
BT_ASSERT(endpoint);
err = bt_avdtp_register_sep(media_type, role, &(endpoint->info));
if (err < 0) {
return err;
}
err = bt_avdtp_register_sep(media_type, role, &(endpoint->info));
if (err < 0) {
return err;
}
return 0;
return 0;
}

View File

@@ -9,295 +9,264 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <net/buf.h>
#include <stdarg.h>
#include <string.h>
#include "at.h"
static void next_list(struct at_client *at)
{
if (at->buf[at->pos] == ',') {
at->pos++;
}
static void next_list(struct at_client *at) {
if (at->buf[at->pos] == ',') {
at->pos++;
}
}
int at_check_byte(struct net_buf *buf, char check_byte)
{
const unsigned char *str = buf->data;
int at_check_byte(struct net_buf *buf, char check_byte) {
const unsigned char *str = buf->data;
if (*str != check_byte) {
return -EINVAL;
}
net_buf_pull(buf, 1);
if (*str != check_byte) {
return -EINVAL;
}
net_buf_pull(buf, 1);
return 0;
return 0;
}
static void skip_space(struct at_client *at)
{
while (at->buf[at->pos] == ' ') {
at->pos++;
}
static void skip_space(struct at_client *at) {
while (at->buf[at->pos] == ' ') {
at->pos++;
}
}
int at_get_number(struct at_client *at, uint32_t *val)
{
uint32_t i;
int at_get_number(struct at_client *at, uint32_t *val) {
uint32_t i;
skip_space(at);
skip_space(at);
for (i = 0U, *val = 0U;
isdigit((unsigned char)at->buf[at->pos]);
at->pos++, i++) {
*val = *val * 10U + at->buf[at->pos] - '0';
}
if (i == 0U) {
return -ENODATA;
}
next_list(at);
return 0;
}
static bool str_has_prefix(const char *str, const char *prefix)
{
if (strncmp(str, prefix, strlen(prefix)) != 0) {
return false;
}
return true;
}
static int at_parse_result(const char *str, struct net_buf *buf,
enum at_result *result)
{
/* Map the result and check for end lf */
if ((!strncmp(str, "OK", 2)) && (at_check_byte(buf, '\n') == 0)) {
*result = AT_RESULT_OK;
return 0;
}
if ((!strncmp(str, "ERROR", 5)) && (at_check_byte(buf, '\n')) == 0) {
*result = AT_RESULT_ERROR;
return 0;
}
return -ENOMSG;
}
static int get_cmd_value(struct at_client *at, struct net_buf *buf,
char stop_byte, enum at_cmd_state cmd_state)
{
int cmd_len = 0;
uint8_t pos = at->pos;
const char *str = (char *)buf->data;
while (cmd_len < buf->len && at->pos != at->buf_max_len) {
if (*str != stop_byte) {
at->buf[at->pos++] = *str;
cmd_len++;
str++;
pos = at->pos;
} else {
cmd_len++;
at->buf[at->pos] = '\0';
at->pos = 0U;
at->cmd_state = cmd_state;
break;
}
}
net_buf_pull(buf, cmd_len);
if (pos == at->buf_max_len) {
return -ENOBUFS;
}
return 0;
}
static int get_response_string(struct at_client *at, struct net_buf *buf,
char stop_byte, enum at_state state)
{
int cmd_len = 0;
uint8_t pos = at->pos;
const char *str = (char *)buf->data;
while (cmd_len < buf->len && at->pos != at->buf_max_len) {
if (*str != stop_byte) {
at->buf[at->pos++] = *str;
cmd_len++;
str++;
pos = at->pos;
} else {
cmd_len++;
at->buf[at->pos] = '\0';
at->pos = 0U;
at->state = state;
break;
}
}
net_buf_pull(buf, cmd_len);
if (pos == at->buf_max_len) {
return -ENOBUFS;
}
return 0;
}
static void reset_buffer(struct at_client *at)
{
(void)memset(at->buf, 0, at->buf_max_len);
at->pos = 0U;
}
static int at_state_start(struct at_client *at, struct net_buf *buf)
{
int err;
err = at_check_byte(buf, '\r');
if (err < 0) {
return err;
}
at->state = AT_STATE_START_CR;
return 0;
}
static int at_state_start_cr(struct at_client *at, struct net_buf *buf)
{
int err;
err = at_check_byte(buf, '\n');
if (err < 0) {
return err;
}
at->state = AT_STATE_START_LF;
return 0;
}
static int at_state_start_lf(struct at_client *at, struct net_buf *buf)
{
reset_buffer(at);
if (at_check_byte(buf, '+') == 0) {
at->state = AT_STATE_GET_CMD_STRING;
return 0;
} else if (isalpha(*buf->data)) {
at->state = AT_STATE_GET_RESULT_STRING;
return 0;
}
for (i = 0U, *val = 0U; isdigit((unsigned char)at->buf[at->pos]); at->pos++, i++) {
*val = *val * 10U + at->buf[at->pos] - '0';
}
if (i == 0U) {
return -ENODATA;
}
next_list(at);
return 0;
}
static int at_state_get_cmd_string(struct at_client *at, struct net_buf *buf)
{
return get_response_string(at, buf, ':', AT_STATE_PROCESS_CMD);
}
static bool is_cmer(struct at_client *at)
{
if (strncmp(at->buf, "CME ERROR", 9) == 0) {
return true;
}
static bool str_has_prefix(const char *str, const char *prefix) {
if (strncmp(str, prefix, strlen(prefix)) != 0) {
return false;
}
return true;
}
static int at_state_process_cmd(struct at_client *at, struct net_buf *buf)
{
if (is_cmer(at)) {
at->state = AT_STATE_PROCESS_AG_NW_ERR;
return 0;
}
static int at_parse_result(const char *str, struct net_buf *buf, enum at_result *result) {
/* Map the result and check for end lf */
if ((!strncmp(str, "OK", 2)) && (at_check_byte(buf, '\n') == 0)) {
*result = AT_RESULT_OK;
return 0;
}
if (at->resp) {
at->resp(at, buf);
at->resp = NULL;
return 0;
if ((!strncmp(str, "ERROR", 5)) && (at_check_byte(buf, '\n')) == 0) {
*result = AT_RESULT_ERROR;
return 0;
}
return -ENOMSG;
}
static int get_cmd_value(struct at_client *at, struct net_buf *buf, char stop_byte, enum at_cmd_state cmd_state) {
int cmd_len = 0;
uint8_t pos = at->pos;
const char *str = (char *)buf->data;
while (cmd_len < buf->len && at->pos != at->buf_max_len) {
if (*str != stop_byte) {
at->buf[at->pos++] = *str;
cmd_len++;
str++;
pos = at->pos;
} else {
cmd_len++;
at->buf[at->pos] = '\0';
at->pos = 0U;
at->cmd_state = cmd_state;
break;
}
}
net_buf_pull(buf, cmd_len);
if (pos == at->buf_max_len) {
return -ENOBUFS;
}
return 0;
}
static int get_response_string(struct at_client *at, struct net_buf *buf, char stop_byte, enum at_state state) {
int cmd_len = 0;
uint8_t pos = at->pos;
const char *str = (char *)buf->data;
while (cmd_len < buf->len && at->pos != at->buf_max_len) {
if (*str != stop_byte) {
at->buf[at->pos++] = *str;
cmd_len++;
str++;
pos = at->pos;
} else {
cmd_len++;
at->buf[at->pos] = '\0';
at->pos = 0U;
at->state = state;
break;
}
}
net_buf_pull(buf, cmd_len);
if (pos == at->buf_max_len) {
return -ENOBUFS;
}
return 0;
}
static void reset_buffer(struct at_client *at) {
(void)memset(at->buf, 0, at->buf_max_len);
at->pos = 0U;
}
static int at_state_start(struct at_client *at, struct net_buf *buf) {
int err;
err = at_check_byte(buf, '\r');
if (err < 0) {
return err;
}
at->state = AT_STATE_START_CR;
return 0;
}
static int at_state_start_cr(struct at_client *at, struct net_buf *buf) {
int err;
err = at_check_byte(buf, '\n');
if (err < 0) {
return err;
}
at->state = AT_STATE_START_LF;
return 0;
}
static int at_state_start_lf(struct at_client *at, struct net_buf *buf) {
reset_buffer(at);
if (at_check_byte(buf, '+') == 0) {
at->state = AT_STATE_GET_CMD_STRING;
return 0;
} else if (isalpha(*buf->data)) {
at->state = AT_STATE_GET_RESULT_STRING;
return 0;
}
return -ENODATA;
}
static int at_state_get_cmd_string(struct at_client *at, struct net_buf *buf) { return get_response_string(at, buf, ':', AT_STATE_PROCESS_CMD); }
static bool is_cmer(struct at_client *at) {
if (strncmp(at->buf, "CME ERROR", 9) == 0) {
return true;
}
return false;
}
static int at_state_process_cmd(struct at_client *at, struct net_buf *buf) {
if (is_cmer(at)) {
at->state = AT_STATE_PROCESS_AG_NW_ERR;
return 0;
}
if (at->resp) {
at->resp(at, buf);
at->resp = NULL;
return 0;
}
at->state = AT_STATE_UNSOLICITED_CMD;
return 0;
}
static int at_state_get_result_string(struct at_client *at, struct net_buf *buf) { return get_response_string(at, buf, '\r', AT_STATE_PROCESS_RESULT); }
static bool is_ring(struct at_client *at) {
if (strncmp(at->buf, "RING", 4) == 0) {
return true;
}
return false;
}
static int at_state_process_result(struct at_client *at, struct net_buf *buf) {
enum at_cme cme_err;
enum at_result result;
if (is_ring(at)) {
at->state = AT_STATE_UNSOLICITED_CMD;
return 0;
}
static int at_state_get_result_string(struct at_client *at, struct net_buf *buf)
{
return get_response_string(at, buf, '\r', AT_STATE_PROCESS_RESULT);
}
static bool is_ring(struct at_client *at)
{
if (strncmp(at->buf, "RING", 4) == 0) {
return true;
}
return false;
}
static int at_state_process_result(struct at_client *at, struct net_buf *buf)
{
enum at_cme cme_err;
enum at_result result;
if (is_ring(at)) {
at->state = AT_STATE_UNSOLICITED_CMD;
return 0;
}
if (at_parse_result(at->buf, buf, &result) == 0) {
if (at->finish) {
/* cme_err is 0 - Is invalid until result is
* AT_RESULT_CME_ERROR
*/
cme_err = 0;
at->finish(at, result, cme_err);
}
}
/* Reset the state to process unsolicited response */
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return 0;
}
int cme_handle(struct at_client *at)
{
enum at_cme cme_err;
uint32_t val;
if (!at_get_number(at, &val) && val <= CME_ERROR_NETWORK_NOT_ALLOWED) {
cme_err = val;
} else {
cme_err = CME_ERROR_UNKNOWN;
}
}
if (at_parse_result(at->buf, buf, &result) == 0) {
if (at->finish) {
at->finish(at, AT_RESULT_CME_ERROR, cme_err);
/* cme_err is 0 - Is invalid until result is
* AT_RESULT_CME_ERROR
*/
cme_err = 0;
at->finish(at, result, cme_err);
}
}
return 0;
/* Reset the state to process unsolicited response */
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return 0;
}
static int at_state_process_ag_nw_err(struct at_client *at, struct net_buf *buf)
{
at->cmd_state = AT_CMD_GET_VALUE;
return at_parse_cmd_input(at, buf, NULL, cme_handle,
AT_CMD_TYPE_NORMAL);
int cme_handle(struct at_client *at) {
enum at_cme cme_err;
uint32_t val;
if (!at_get_number(at, &val) && val <= CME_ERROR_NETWORK_NOT_ALLOWED) {
cme_err = val;
} else {
cme_err = CME_ERROR_UNKNOWN;
}
if (at->finish) {
at->finish(at, AT_RESULT_CME_ERROR, cme_err);
}
return 0;
}
static int at_state_unsolicited_cmd(struct at_client *at, struct net_buf *buf)
{
if (at->unsolicited) {
return at->unsolicited(at, buf);
}
static int at_state_process_ag_nw_err(struct at_client *at, struct net_buf *buf) {
at->cmd_state = AT_CMD_GET_VALUE;
return at_parse_cmd_input(at, buf, NULL, cme_handle, AT_CMD_TYPE_NORMAL);
}
return -ENODATA;
static int at_state_unsolicited_cmd(struct at_client *at, struct net_buf *buf) {
if (at->unsolicited) {
return at->unsolicited(at, buf);
}
return -ENODATA;
}
/* The order of handler function should match the enum at_state */
@@ -313,84 +282,71 @@ static handle_parse_input_t parser_cb[] = {
at_state_unsolicited_cmd /* AT_STATE_UNSOLICITED_CMD */
};
int at_parse_input(struct at_client *at, struct net_buf *buf)
{
int ret;
int at_parse_input(struct at_client *at, struct net_buf *buf) {
int ret;
while (buf->len) {
if (at->state < AT_STATE_START || at->state >= AT_STATE_END) {
return -EINVAL;
}
ret = parser_cb[at->state](at, buf);
if (ret < 0) {
/* Reset the state in case of error */
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return ret;
}
while (buf->len) {
if (at->state < AT_STATE_START || at->state >= AT_STATE_END) {
return -EINVAL;
}
ret = parser_cb[at->state](at, buf);
if (ret < 0) {
/* Reset the state in case of error */
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return ret;
}
}
return 0;
return 0;
}
static int at_cmd_start(struct at_client *at, struct net_buf *buf,
const char *prefix, parse_val_t func,
enum at_cmd_type type)
{
if (!str_has_prefix(at->buf, prefix)) {
if (type == AT_CMD_TYPE_NORMAL) {
at->state = AT_STATE_UNSOLICITED_CMD;
}
return -ENODATA;
static int at_cmd_start(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) {
if (!str_has_prefix(at->buf, prefix)) {
if (type == AT_CMD_TYPE_NORMAL) {
at->state = AT_STATE_UNSOLICITED_CMD;
}
return -ENODATA;
}
if (type == AT_CMD_TYPE_OTHER) {
/* Skip for Other type such as ..RING.. which does not have
* values to get processed.
*/
at->cmd_state = AT_CMD_PROCESS_VALUE;
} else {
at->cmd_state = AT_CMD_GET_VALUE;
}
if (type == AT_CMD_TYPE_OTHER) {
/* Skip for Other type such as ..RING.. which does not have
* values to get processed.
*/
at->cmd_state = AT_CMD_PROCESS_VALUE;
} else {
at->cmd_state = AT_CMD_GET_VALUE;
}
return 0;
return 0;
}
static int at_cmd_get_value(struct at_client *at, struct net_buf *buf,
const char *prefix, parse_val_t func,
enum at_cmd_type type)
{
/* Reset buffer before getting the values */
reset_buffer(at);
return get_cmd_value(at, buf, '\r', AT_CMD_PROCESS_VALUE);
static int at_cmd_get_value(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) {
/* Reset buffer before getting the values */
reset_buffer(at);
return get_cmd_value(at, buf, '\r', AT_CMD_PROCESS_VALUE);
}
static int at_cmd_process_value(struct at_client *at, struct net_buf *buf,
const char *prefix, parse_val_t func,
enum at_cmd_type type)
{
int ret;
static int at_cmd_process_value(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) {
int ret;
ret = func(at);
at->cmd_state = AT_CMD_STATE_END_LF;
ret = func(at);
at->cmd_state = AT_CMD_STATE_END_LF;
return ret;
return ret;
}
static int at_cmd_state_end_lf(struct at_client *at, struct net_buf *buf,
const char *prefix, parse_val_t func,
enum at_cmd_type type)
{
int err;
static int at_cmd_state_end_lf(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) {
int err;
err = at_check_byte(buf, '\n');
if (err < 0) {
return err;
}
err = at_check_byte(buf, '\n');
if (err < 0) {
return err;
}
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return 0;
at->cmd_state = AT_CMD_START;
at->state = AT_STATE_START;
return 0;
}
/* The order of handler function should match the enum at_cmd_state */
@@ -401,137 +357,122 @@ static handle_cmd_input_t cmd_parser_cb[] = {
at_cmd_state_end_lf /* AT_CMD_STATE_END_LF */
};
int at_parse_cmd_input(struct at_client *at, struct net_buf *buf,
const char *prefix, parse_val_t func,
enum at_cmd_type type)
{
int ret;
int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, const char *prefix, parse_val_t func, enum at_cmd_type type) {
int ret;
while (buf->len) {
if (at->cmd_state < AT_CMD_START ||
at->cmd_state >= AT_CMD_STATE_END) {
return -EINVAL;
}
ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func, type);
if (ret < 0) {
return ret;
}
/* Check for main state, the end of cmd parsing and return. */
if (at->state == AT_STATE_START) {
return 0;
}
while (buf->len) {
if (at->cmd_state < AT_CMD_START || at->cmd_state >= AT_CMD_STATE_END) {
return -EINVAL;
}
ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func, type);
if (ret < 0) {
return ret;
}
/* Check for main state, the end of cmd parsing and return. */
if (at->state == AT_STATE_START) {
return 0;
}
}
return 0;
return 0;
}
int at_has_next_list(struct at_client *at)
{
return at->buf[at->pos] != '\0';
int at_has_next_list(struct at_client *at) { return at->buf[at->pos] != '\0'; }
int at_open_list(struct at_client *at) {
skip_space(at);
/* The list shall start with '(' open parenthesis */
if (at->buf[at->pos] != '(') {
return -ENODATA;
}
at->pos++;
return 0;
}
int at_open_list(struct at_client *at)
{
skip_space(at);
int at_close_list(struct at_client *at) {
skip_space(at);
/* The list shall start with '(' open parenthesis */
if (at->buf[at->pos] != '(') {
return -ENODATA;
}
at->pos++;
if (at->buf[at->pos] != ')') {
return -ENODATA;
}
at->pos++;
return 0;
next_list(at);
return 0;
}
int at_close_list(struct at_client *at)
{
skip_space(at);
int at_list_get_string(struct at_client *at, char *name, uint8_t len) {
int i = 0;
if (at->buf[at->pos] != ')') {
return -ENODATA;
}
at->pos++;
skip_space(at);
next_list(at);
return 0;
}
int at_list_get_string(struct at_client *at, char *name, uint8_t len)
{
int i = 0;
skip_space(at);
if (at->buf[at->pos] != '"') {
return -ENODATA;
}
at->pos++;
while (at->buf[at->pos] != '\0' && at->buf[at->pos] != '"') {
if (i == len) {
return -ENODATA;
}
name[i++] = at->buf[at->pos++];
}
if (at->buf[at->pos] != '"') {
return -ENODATA;
}
at->pos++;
while (at->buf[at->pos] != '\0' && at->buf[at->pos] != '"') {
if (i == len) {
return -ENODATA;
return -ENODATA;
}
name[i++] = at->buf[at->pos++];
}
name[i] = '\0';
if (i == len) {
return -ENODATA;
}
if (at->buf[at->pos] != '"') {
return -ENODATA;
}
name[i] = '\0';
if (at->buf[at->pos] != '"') {
return -ENODATA;
}
at->pos++;
skip_space(at);
next_list(at);
return 0;
}
int at_list_get_range(struct at_client *at, uint32_t *min, uint32_t *max) {
uint32_t low, high;
int ret;
ret = at_get_number(at, &low);
if (ret < 0) {
return ret;
}
if (at->buf[at->pos] == '-') {
at->pos++;
goto out;
}
skip_space(at);
next_list(at);
return 0;
}
int at_list_get_range(struct at_client *at, uint32_t *min, uint32_t *max)
{
uint32_t low, high;
int ret;
ret = at_get_number(at, &low);
if (ret < 0) {
return ret;
}
if (at->buf[at->pos] == '-') {
at->pos++;
goto out;
}
if (!isdigit((unsigned char)at->buf[at->pos])) {
return -ENODATA;
}
if (!isdigit((unsigned char)at->buf[at->pos])) {
return -ENODATA;
}
out:
ret = at_get_number(at, &high);
if (ret < 0) {
return ret;
}
ret = at_get_number(at, &high);
if (ret < 0) {
return ret;
}
*min = low;
*max = high;
*min = low;
*max = high;
next_list(at);
next_list(at);
return 0;
return 0;
}
void at_register_unsolicited(struct at_client *at, at_resp_cb_t unsolicited)
{
at->unsolicited = unsolicited;
}
void at_register_unsolicited(struct at_client *at, at_resp_cb_t unsolicited) { at->unsolicited = unsolicited; }
void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish)
{
at->resp = resp;
at->finish = finish;
at->state = AT_STATE_START;
void at_register(struct at_client *at, at_resp_cb_t resp, at_finish_cb_t finish) {
at->resp = resp;
at->finish = finish;
at->state = AT_STATE_START;
}

View File

@@ -5,7 +5,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "conn_internal.h"
#define BT_ATT_DEFAULT_LE_MTU 23
#if BT_L2CAP_RX_MTU < CONFIG_BT_L2CAP_TX_MTU

View File

@@ -7,6 +7,9 @@
*/
#include <avdtp.h>
#include "l2cap.h"
#ifndef BLE_STACK_HOST_AVDTP_INTERNAL_H_
#define BLE_STACK_HOST_AVDTP_INTERNAL_H_
/* @brief A2DP ROLE's */
#define A2DP_SRC_ROLE 0x00
@@ -173,3 +176,5 @@ int bt_avdtp_register_sep(uint8_t media_type, uint8_t role,
/* AVDTP Discover Request */
int bt_avdtp_discover(struct bt_avdtp *session,
struct bt_avdtp_discover_params *param);
#endif

View File

@@ -1,6 +1,9 @@
/** @file
* @brief Internal APIs for Bluetooth connection handling.
*/
#ifndef BLE_STACK_HOST_CONN_INTERNAL_H_
#define BLE_STACK_HOST_CONN_INTERNAL_H_
#include "addr.h"
#include "atomic.h"
#include "slist.h"
@@ -8,6 +11,12 @@
#include "work_q.h"
#include <stddef.h>
#include <stdint.h>
#include "conn.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Copyright (c) 2015 Intel Corporation
*
@@ -324,3 +333,9 @@ void bt_conn_process_tx(struct bt_conn *conn);
*/
int bt_hci_get_conn_handle(const struct bt_conn *conn, u16_t *conn_handle);
#endif
#ifdef __cplusplus
};
#endif
#endif //BLE_STACK_HOST_CONN_INTERNAL_H_

View File

@@ -5,19 +5,19 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include <string.h>
#include <zephyr.h>
#include <misc/byteorder.h>
#include <zephyr.h>
#include <bluetooth.h>
#include <hci_host.h>
#include <conn.h>
#include <hci_host.h>
#include <aes.h>
#include <constants.h>
#include <hmac_prng.h>
#include <aes.h>
#include <utils.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
@@ -28,140 +28,132 @@
static struct tc_hmac_prng_struct prng;
static int prng_reseed(struct tc_hmac_prng_struct *h)
{
u8_t seed[32];
s64_t extra;
int ret, i;
static int prng_reseed(struct tc_hmac_prng_struct *h) {
u8_t seed[32];
s64_t extra;
int ret, i;
for (i = 0; i < (sizeof(seed) / 8); i++) {
struct bt_hci_rp_le_rand *rp;
struct net_buf *rsp;
ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
if (ret) {
return ret;
}
rp = (void *)rsp->data;
memcpy(&seed[i * 8], rp->rand, 8);
net_buf_unref(rsp);
}
extra = k_uptime_get();
ret = tc_hmac_prng_reseed(h, seed, sizeof(seed), (u8_t *)&extra,
sizeof(extra));
if (ret == TC_CRYPTO_FAIL) {
BT_ERR("Failed to re-seed PRNG");
return -EIO;
}
return 0;
}
int prng_init(void)
{
for (i = 0; i < (sizeof(seed) / 8); i++) {
struct bt_hci_rp_le_rand *rp;
struct net_buf *rsp;
int ret;
/* Check first that HCI_LE_Rand is supported */
if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) {
return -ENOTSUP;
}
struct net_buf *rsp;
ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
if (ret) {
return ret;
return ret;
}
rp = (void *)rsp->data;
ret = tc_hmac_prng_init(&prng, rp->rand, sizeof(rp->rand));
memcpy(&seed[i * 8], rp->rand, 8);
net_buf_unref(rsp);
}
if (ret == TC_CRYPTO_FAIL) {
BT_ERR("Failed to initialize PRNG");
return -EIO;
}
extra = k_uptime_get();
/* re-seed is needed after init */
return prng_reseed(&prng);
ret = tc_hmac_prng_reseed(h, seed, sizeof(seed), (u8_t *)&extra, sizeof(extra));
if (ret == TC_CRYPTO_FAIL) {
BT_ERR("Failed to re-seed PRNG");
return -EIO;
}
return 0;
}
int bt_rand(void *buf, size_t len)
{
#if !defined(CONFIG_BT_GEN_RANDOM_BY_SW)
k_get_random_byte_array(buf, len);
return 0;
#else
int ret;
ret = tc_hmac_prng_generate(buf, len, &prng);
if (ret == TC_HMAC_PRNG_RESEED_REQ) {
ret = prng_reseed(&prng);
if (ret) {
return ret;
}
int prng_init(void) {
struct bt_hci_rp_le_rand *rp;
struct net_buf *rsp;
int ret;
ret = tc_hmac_prng_generate(buf, len, &prng);
}
/* Check first that HCI_LE_Rand is supported */
if (!BT_CMD_TEST(bt_dev.supported_commands, 27, 7)) {
return -ENOTSUP;
}
if (ret == TC_CRYPTO_SUCCESS) {
return 0;
}
ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp);
if (ret) {
return ret;
}
rp = (void *)rsp->data;
ret = tc_hmac_prng_init(&prng, rp->rand, sizeof(rp->rand));
net_buf_unref(rsp);
if (ret == TC_CRYPTO_FAIL) {
BT_ERR("Failed to initialize PRNG");
return -EIO;
}
/* re-seed is needed after init */
return prng_reseed(&prng);
}
int bt_rand(void *buf, size_t len) {
#if !defined(CONFIG_BT_GEN_RANDOM_BY_SW)
k_get_random_byte_array(buf, len);
return 0;
#else
int ret;
ret = tc_hmac_prng_generate(buf, len, &prng);
if (ret == TC_HMAC_PRNG_RESEED_REQ) {
ret = prng_reseed(&prng);
if (ret) {
return ret;
}
ret = tc_hmac_prng_generate(buf, len, &prng);
}
if (ret == TC_CRYPTO_SUCCESS) {
return 0;
}
return -EIO;
#endif
}
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16])
{
struct tc_aes_key_sched_struct s;
u8_t tmp[16];
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16], u8_t enc_data[16]) {
struct tc_aes_key_sched_struct s;
u8_t tmp[16];
BT_DBG("key %s", bt_hex(key, 16));
BT_DBG("plaintext %s", bt_hex(plaintext, 16));
BT_DBG("key %s", bt_hex(key, 16));
BT_DBG("plaintext %s", bt_hex(plaintext, 16));
sys_memcpy_swap(tmp, key, 16);
sys_memcpy_swap(tmp, key, 16);
if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
sys_memcpy_swap(tmp, plaintext, 16);
sys_memcpy_swap(tmp, plaintext, 16);
if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
sys_mem_swap(enc_data, 16);
sys_mem_swap(enc_data, 16);
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
return 0;
return 0;
}
int bt_encrypt_be(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16])
{
struct tc_aes_key_sched_struct s;
int bt_encrypt_be(const u8_t key[16], const u8_t plaintext[16], u8_t enc_data[16]) {
struct tc_aes_key_sched_struct s;
BT_DBG("key %s", bt_hex(key, 16));
BT_DBG("plaintext %s", bt_hex(plaintext, 16));
BT_DBG("key %s", bt_hex(key, 16));
BT_DBG("plaintext %s", bt_hex(plaintext, 16));
if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
return -EINVAL;
}
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
BT_DBG("enc_data %s", bt_hex(enc_data, 16));
return 0;
return 0;
}

View File

@@ -1,5 +1,5 @@
/* ecc.h - ECDH helpers */
#include "types.h"
/*
* Copyright (c) 2016 Intel Corporation
*

View File

@@ -9,28 +9,28 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <atomic.h>
#include <misc/stack.h>
#include <misc/byteorder.h>
#include <constants.h>
#include <utils.h>
#include <ecc.h>
#include <ecc_dh.h>
#include <misc/byteorder.h>
#include <misc/stack.h>
#include <utils.h>
#include <zephyr.h>
#include <../include/bluetooth/crypto.h>
#include <bluetooth.h>
#include <conn.h>
#include <hci_host.h>
#include <hci_driver.h>
#include <../include/bluetooth/crypto.h>
#include <hci_host.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
#include "log.h"
#include "hci_ecc.h"
#ifdef CONFIG_BT_HCI_RAW
#include <bluetooth/hci_raw.h>
#include "hci_raw_internal.h"
#include <bluetooth/hci_raw.h>
#else
#include "hci_core.h"
#endif
@@ -41,28 +41,20 @@ static BT_STACK_NOINIT(ecc_thread_stack, 1024);
#endif
/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */
static const u32_t debug_private_key[8] = {
0xcd3c1abd, 0x5899b8a6, 0xeb40b799, 0x4aff607b, 0xd2103f50, 0x74c9b3e3,
0xa3c55f38, 0x3f49f6d4
};
static const u32_t debug_private_key[8] = {0xcd3c1abd, 0x5899b8a6, 0xeb40b799, 0x4aff607b, 0xd2103f50, 0x74c9b3e3, 0xa3c55f38, 0x3f49f6d4};
#if defined(CONFIG_BT_USE_DEBUG_KEYS)
static const u8_t debug_public_key[64] = {
0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac,
0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e,
0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 0x8b, 0xd2, 0x89, 0x15,
0xd0, 0x8e, 0x1c, 0x74, 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76,
0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 0x6d, 0xeb, 0x2a, 0x65,
0x49, 0x9c, 0x80, 0xdc
};
static const u8_t debug_public_key[64] = {0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83,
0x2c, 0x5e, 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 0x8b, 0xd2, 0x89, 0x15, 0xd0, 0x8e, 0x1c, 0x74, 0x24, 0x30, 0xed, 0x8f,
0xc2, 0x45, 0x63, 0x76, 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 0x6d, 0xeb, 0x2a, 0x65, 0x49, 0x9c, 0x80, 0xdc};
#endif
enum {
PENDING_PUB_KEY,
PENDING_DHKEY,
PENDING_PUB_KEY,
PENDING_DHKEY,
/* Total number of flags - must be at the end of the enum */
NUM_FLAGS,
/* Total number of flags - must be at the end of the enum */
NUM_FLAGS,
};
static ATOMIC_DEFINE(flags, NUM_FLAGS);
@@ -70,140 +62,135 @@ static ATOMIC_DEFINE(flags, NUM_FLAGS);
static K_SEM_DEFINE(cmd_sem, 0, 1);
static struct {
u8_t private_key[32];
u8_t private_key[32];
union {
u8_t pk[64];
u8_t dhkey[32];
};
union {
u8_t pk[64];
u8_t dhkey[32];
};
} ecc;
static void send_cmd_status(u16_t opcode, u8_t status)
{
struct bt_hci_evt_cmd_status *evt;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
static void send_cmd_status(u16_t opcode, u8_t status) {
struct bt_hci_evt_cmd_status *evt;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
BT_DBG("opcode %x status %x", opcode, status);
BT_DBG("opcode %x status %x", opcode, status);
buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS, false, K_FOREVER);
bt_buf_set_type(buf, BT_BUF_EVT);
buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS, false, K_FOREVER);
bt_buf_set_type(buf, BT_BUF_EVT);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_CMD_STATUS;
hdr->len = sizeof(*evt);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_CMD_STATUS;
hdr->len = sizeof(*evt);
evt = net_buf_add(buf, sizeof(*evt));
evt->ncmd = 1U;
evt->opcode = sys_cpu_to_le16(opcode);
evt->status = status;
evt = net_buf_add(buf, sizeof(*evt));
evt->ncmd = 1U;
evt->opcode = sys_cpu_to_le16(opcode);
evt->status = status;
bt_recv_prio(buf);
bt_recv_prio(buf);
}
static u8_t generate_keys(void)
{
static u8_t generate_keys(void) {
#if !defined(CONFIG_BT_USE_DEBUG_KEYS)
do {
int rc;
do {
int rc;
rc = uECC_make_key(ecc.pk, ecc.private_key, &curve_secp256r1);
if (rc == TC_CRYPTO_FAIL) {
BT_ERR("Failed to create ECC public/private pair");
return BT_HCI_ERR_UNSPECIFIED;
}
rc = uECC_make_key(ecc.pk, ecc.private_key, &curve_secp256r1);
if (rc == TC_CRYPTO_FAIL) {
BT_ERR("Failed to create ECC public/private pair");
return BT_HCI_ERR_UNSPECIFIED;
}
/* make sure generated key isn't debug key */
} while (memcmp(ecc.private_key, debug_private_key, 32) == 0);
/* make sure generated key isn't debug key */
} while (memcmp(ecc.private_key, debug_private_key, 32) == 0);
#else
sys_memcpy_swap(&ecc.pk, debug_public_key, 32);
sys_memcpy_swap(&ecc.pk[32], &debug_public_key[32], 32);
sys_memcpy_swap(ecc.private_key, debug_private_key, 32);
sys_memcpy_swap(&ecc.pk, debug_public_key, 32);
sys_memcpy_swap(&ecc.pk[32], &debug_public_key[32], 32);
sys_memcpy_swap(ecc.private_key, debug_private_key, 32);
#endif
return 0;
return 0;
}
static void emulate_le_p256_public_key_cmd(void)
{
struct bt_hci_evt_le_p256_public_key_complete *evt;
struct bt_hci_evt_le_meta_event *meta;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
u8_t status;
static void emulate_le_p256_public_key_cmd(void) {
struct bt_hci_evt_le_p256_public_key_complete *evt;
struct bt_hci_evt_le_meta_event *meta;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
u8_t status;
BT_DBG("");
BT_DBG("");
status = generate_keys();
status = generate_keys();
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_LE_META_EVENT;
hdr->len = sizeof(*meta) + sizeof(*evt);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_LE_META_EVENT;
hdr->len = sizeof(*meta) + sizeof(*evt);
meta = net_buf_add(buf, sizeof(*meta));
meta->subevent = BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE;
meta = net_buf_add(buf, sizeof(*meta));
meta->subevent = BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE;
evt = net_buf_add(buf, sizeof(*evt));
evt->status = status;
evt = net_buf_add(buf, sizeof(*evt));
evt->status = status;
if (status) {
(void)memset(evt->key, 0, sizeof(evt->key));
} else {
/* Convert X and Y coordinates from big-endian (provided
* by crypto API) to little endian HCI.
*/
sys_memcpy_swap(evt->key, ecc.pk, 32);
sys_memcpy_swap(&evt->key[32], &ecc.pk[32], 32);
}
if (status) {
(void)memset(evt->key, 0, sizeof(evt->key));
} else {
/* Convert X and Y coordinates from big-endian (provided
* by crypto API) to little endian HCI.
*/
sys_memcpy_swap(evt->key, ecc.pk, 32);
sys_memcpy_swap(&evt->key[32], &ecc.pk[32], 32);
}
atomic_clear_bit(flags, PENDING_PUB_KEY);
atomic_clear_bit(flags, PENDING_PUB_KEY);
bt_recv(buf);
bt_recv(buf);
}
static void emulate_le_generate_dhkey(void)
{
struct bt_hci_evt_le_generate_dhkey_complete *evt;
struct bt_hci_evt_le_meta_event *meta;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
int ret;
static void emulate_le_generate_dhkey(void) {
struct bt_hci_evt_le_generate_dhkey_complete *evt;
struct bt_hci_evt_le_meta_event *meta;
struct bt_hci_evt_hdr *hdr;
struct net_buf *buf;
int ret;
ret = uECC_valid_public_key(ecc.pk, &curve_secp256r1);
if (ret < 0) {
BT_ERR("public key is not valid (ret %d)", ret);
ret = TC_CRYPTO_FAIL;
} else {
ret = uECC_shared_secret(ecc.pk, ecc.private_key, ecc.dhkey,
&curve_secp256r1);
}
ret = uECC_valid_public_key(ecc.pk, &curve_secp256r1);
if (ret < 0) {
BT_ERR("public key is not valid (ret %d)", ret);
ret = TC_CRYPTO_FAIL;
} else {
ret = uECC_shared_secret(ecc.pk, ecc.private_key, ecc.dhkey, &curve_secp256r1);
}
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_LE_META_EVENT;
hdr->len = sizeof(*meta) + sizeof(*evt);
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->evt = BT_HCI_EVT_LE_META_EVENT;
hdr->len = sizeof(*meta) + sizeof(*evt);
meta = net_buf_add(buf, sizeof(*meta));
meta->subevent = BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE;
meta = net_buf_add(buf, sizeof(*meta));
meta->subevent = BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE;
evt = net_buf_add(buf, sizeof(*evt));
evt = net_buf_add(buf, sizeof(*evt));
if (ret == TC_CRYPTO_FAIL) {
evt->status = BT_HCI_ERR_UNSPECIFIED;
(void)memset(evt->dhkey, 0, sizeof(evt->dhkey));
} else {
evt->status = 0U;
/* Convert from big-endian (provided by crypto API) to
* little-endian HCI.
*/
sys_memcpy_swap(evt->dhkey, ecc.dhkey, sizeof(ecc.dhkey));
}
if (ret == TC_CRYPTO_FAIL) {
evt->status = BT_HCI_ERR_UNSPECIFIED;
(void)memset(evt->dhkey, 0, sizeof(evt->dhkey));
} else {
evt->status = 0U;
/* Convert from big-endian (provided by crypto API) to
* little-endian HCI.
*/
sys_memcpy_swap(evt->dhkey, ecc.dhkey, sizeof(ecc.dhkey));
}
atomic_clear_bit(flags, PENDING_DHKEY);
atomic_clear_bit(flags, PENDING_DHKEY);
bt_recv(buf);
bt_recv(buf);
}
#if defined(BFLB_BLE)
@@ -212,129 +199,117 @@ static void ecc_thread(void *p1)
static void ecc_thread(void *p1, void *p2, void *p3)
#endif
{
while (true) {
k_sem_take(&cmd_sem, K_FOREVER);
if (atomic_test_bit(flags, PENDING_PUB_KEY)) {
emulate_le_p256_public_key_cmd();
} else if (atomic_test_bit(flags, PENDING_DHKEY)) {
emulate_le_generate_dhkey();
} else {
__ASSERT(0, "Unhandled ECC command");
}
#if !defined(BFLB_BLE)
STACK_ANALYZE("ecc stack", ecc_thread_stack);
#endif
}
}
static void clear_ecc_events(struct net_buf *buf)
{
struct bt_hci_cp_le_set_event_mask *cmd;
cmd = (void *)(buf->data + sizeof(struct bt_hci_cmd_hdr));
/*
* don't enable controller ECC events as those will be generated from
* emulation code
*/
cmd->events[0] &= ~0x80; /* LE Read Local P-256 PKey Compl */
cmd->events[1] &= ~0x01; /* LE Generate DHKey Compl Event */
}
static void le_gen_dhkey(struct net_buf *buf)
{
struct bt_hci_cp_le_generate_dhkey *cmd;
u8_t status;
while (true) {
k_sem_take(&cmd_sem, K_FOREVER);
if (atomic_test_bit(flags, PENDING_PUB_KEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
goto send_status;
emulate_le_p256_public_key_cmd();
} else if (atomic_test_bit(flags, PENDING_DHKEY)) {
emulate_le_generate_dhkey();
} else {
__ASSERT(0, "Unhandled ECC command");
}
#if !defined(BFLB_BLE)
STACK_ANALYZE("ecc stack", ecc_thread_stack);
#endif
}
}
if (buf->len < sizeof(struct bt_hci_cp_le_generate_dhkey)) {
status = BT_HCI_ERR_INVALID_PARAM;
goto send_status;
}
static void clear_ecc_events(struct net_buf *buf) {
struct bt_hci_cp_le_set_event_mask *cmd;
if (atomic_test_and_set_bit(flags, PENDING_DHKEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
goto send_status;
}
cmd = (void *)(buf->data + sizeof(struct bt_hci_cmd_hdr));
cmd = (void *)buf->data;
/* Convert X and Y coordinates from little-endian HCI to
* big-endian (expected by the crypto API).
*/
sys_memcpy_swap(ecc.pk, cmd->key, 32);
sys_memcpy_swap(&ecc.pk[32], &cmd->key[32], 32);
k_sem_give(&cmd_sem);
status = BT_HCI_ERR_SUCCESS;
/*
* don't enable controller ECC events as those will be generated from
* emulation code
*/
cmd->events[0] &= ~0x80; /* LE Read Local P-256 PKey Compl */
cmd->events[1] &= ~0x01; /* LE Generate DHKey Compl Event */
}
static void le_gen_dhkey(struct net_buf *buf) {
struct bt_hci_cp_le_generate_dhkey *cmd;
u8_t status;
if (atomic_test_bit(flags, PENDING_PUB_KEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
goto send_status;
}
if (buf->len < sizeof(struct bt_hci_cp_le_generate_dhkey)) {
status = BT_HCI_ERR_INVALID_PARAM;
goto send_status;
}
if (atomic_test_and_set_bit(flags, PENDING_DHKEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
goto send_status;
}
cmd = (void *)buf->data;
/* Convert X and Y coordinates from little-endian HCI to
* big-endian (expected by the crypto API).
*/
sys_memcpy_swap(ecc.pk, cmd->key, 32);
sys_memcpy_swap(&ecc.pk[32], &cmd->key[32], 32);
k_sem_give(&cmd_sem);
status = BT_HCI_ERR_SUCCESS;
send_status:
net_buf_unref(buf);
send_cmd_status(BT_HCI_OP_LE_GENERATE_DHKEY, status);
net_buf_unref(buf);
send_cmd_status(BT_HCI_OP_LE_GENERATE_DHKEY, status);
}
static void le_p256_pub_key(struct net_buf *buf)
{
u8_t status;
static void le_p256_pub_key(struct net_buf *buf) {
u8_t status;
net_buf_unref(buf);
net_buf_unref(buf);
if (atomic_test_bit(flags, PENDING_DHKEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
} else if (atomic_test_and_set_bit(flags, PENDING_PUB_KEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
} else {
k_sem_give(&cmd_sem);
status = BT_HCI_ERR_SUCCESS;
if (atomic_test_bit(flags, PENDING_DHKEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
} else if (atomic_test_and_set_bit(flags, PENDING_PUB_KEY)) {
status = BT_HCI_ERR_CMD_DISALLOWED;
} else {
k_sem_give(&cmd_sem);
status = BT_HCI_ERR_SUCCESS;
}
send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, status);
}
int bt_hci_ecc_send(struct net_buf *buf) {
if (bt_buf_get_type(buf) == BT_BUF_CMD) {
struct bt_hci_cmd_hdr *chdr = (void *)buf->data;
switch (sys_le16_to_cpu(chdr->opcode)) {
case BT_HCI_OP_LE_P256_PUBLIC_KEY:
net_buf_pull(buf, sizeof(*chdr));
le_p256_pub_key(buf);
return 0;
case BT_HCI_OP_LE_GENERATE_DHKEY:
net_buf_pull(buf, sizeof(*chdr));
le_gen_dhkey(buf);
return 0;
case BT_HCI_OP_LE_SET_EVENT_MASK:
clear_ecc_events(buf);
break;
default:
break;
}
}
send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, status);
return bt_dev.drv->send(buf);
}
int bt_hci_ecc_send(struct net_buf *buf)
{
if (bt_buf_get_type(buf) == BT_BUF_CMD) {
struct bt_hci_cmd_hdr *chdr = (void *)buf->data;
int default_CSPRNG(u8_t *dst, unsigned int len) { return !bt_rand(dst, len); }
switch (sys_le16_to_cpu(chdr->opcode)) {
case BT_HCI_OP_LE_P256_PUBLIC_KEY:
net_buf_pull(buf, sizeof(*chdr));
le_p256_pub_key(buf);
return 0;
case BT_HCI_OP_LE_GENERATE_DHKEY:
net_buf_pull(buf, sizeof(*chdr));
le_gen_dhkey(buf);
return 0;
case BT_HCI_OP_LE_SET_EVENT_MASK:
clear_ecc_events(buf);
break;
default:
break;
}
}
return bt_dev.drv->send(buf);
}
int default_CSPRNG(u8_t *dst, unsigned int len)
{
return !bt_rand(dst, len);
}
void bt_hci_ecc_init(void)
{
void bt_hci_ecc_init(void) {
#if defined(BFLB_BLE)
k_sem_init(&cmd_sem, 0, 1);
k_thread_create(&ecc_thread_data, "ecc_thread",
CONFIG_BT_HCI_ECC_STACK_SIZE, ecc_thread,
CONFIG_BT_WORK_QUEUE_PRIO);
k_sem_init(&cmd_sem, 0, 1);
k_thread_create(&ecc_thread_data, "ecc_thread", CONFIG_BT_HCI_ECC_STACK_SIZE, ecc_thread, CONFIG_BT_WORK_QUEUE_PRIO);
#else
k_thread_create(&ecc_thread_data, ecc_thread_stack,
K_THREAD_STACK_SIZEOF(ecc_thread_stack), ecc_thread,
NULL, NULL, NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT);
k_thread_name_set(&ecc_thread_data, "BT ECC");
k_thread_create(&ecc_thread_data, ecc_thread_stack, K_THREAD_STACK_SIZEOF(ecc_thread_stack), ecc_thread, NULL, NULL, NULL, K_PRIO_PREEMPT(10), 0, K_NO_WAIT);
k_thread_name_set(&ecc_thread_data, "BT ECC");
#endif
}

View File

@@ -6,11 +6,11 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <string.h>
#include <stdlib.h>
#include <atomic.h>
#include <misc/util.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr.h>
#include <bluetooth.h>
#include <conn.h>
@@ -19,12 +19,12 @@
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_KEYS)
#include "log.h"
#include "rpa.h"
#include "gatt_internal.h"
#include "hci_core.h"
#include "smp.h"
#include "settings.h"
#include "keys.h"
#include "rpa.h"
#include "settings.h"
#include "smp.h"
#if defined(BFLB_BLE)
#if defined(CONFIG_BT_SETTINGS)
#include "easyflash.h"
@@ -36,419 +36,375 @@ static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
#define BT_KEYS_STORAGE_LEN_COMPAT (BT_KEYS_STORAGE_LEN - sizeof(uint32_t))
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
static u32_t aging_counter_val;
static u32_t aging_counter_val;
static struct bt_keys *last_keys_updated;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr)
{
struct bt_keys *keys;
int i;
size_t first_free_slot = ARRAY_SIZE(key_pool);
struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr) {
struct bt_keys *keys;
int i;
size_t first_free_slot = ARRAY_SIZE(key_pool);
BT_DBG("%s", bt_addr_le_str(addr));
BT_DBG("%s", bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
keys = &key_pool[i];
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
keys = &key_pool[i];
if (keys->id == id && !bt_addr_le_cmp(&keys->addr, addr)) {
return keys;
}
if (first_free_slot == ARRAY_SIZE(key_pool) &&
(!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY) ||
!keys->enc_size)) {
first_free_slot = i;
}
if (keys->id == id && !bt_addr_le_cmp(&keys->addr, addr)) {
return keys;
}
if (first_free_slot == ARRAY_SIZE(key_pool) && (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY) || !keys->enc_size)) {
first_free_slot = i;
}
}
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
if (first_free_slot == ARRAY_SIZE(key_pool)) {
struct bt_keys *oldest = &key_pool[0];
if (first_free_slot == ARRAY_SIZE(key_pool)) {
struct bt_keys *oldest = &key_pool[0];
for (i = 1; i < ARRAY_SIZE(key_pool); i++) {
struct bt_keys *current = &key_pool[i];
for (i = 1; i < ARRAY_SIZE(key_pool); i++) {
struct bt_keys *current = &key_pool[i];
if (current->aging_counter < oldest->aging_counter) {
oldest = current;
}
}
bt_unpair(oldest->id, &oldest->addr);
if (!bt_addr_le_cmp(&oldest->addr, BT_ADDR_LE_ANY)) {
first_free_slot = oldest - &key_pool[0];
}
if (current->aging_counter < oldest->aging_counter) {
oldest = current;
}
}
bt_unpair(oldest->id, &oldest->addr);
if (!bt_addr_le_cmp(&oldest->addr, BT_ADDR_LE_ANY)) {
first_free_slot = oldest - &key_pool[0];
}
}
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
if (first_free_slot < ARRAY_SIZE(key_pool)) {
keys = &key_pool[first_free_slot];
keys->id = id;
bt_addr_le_copy(&keys->addr, addr);
if (first_free_slot < ARRAY_SIZE(key_pool)) {
keys = &key_pool[first_free_slot];
keys->id = id;
bt_addr_le_copy(&keys->addr, addr);
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
keys->aging_counter = ++aging_counter_val;
last_keys_updated = keys;
keys->aging_counter = ++aging_counter_val;
last_keys_updated = keys;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
return keys;
}
BT_DBG("unable to create keys for %s", bt_addr_le_str(addr));
return NULL;
}
void bt_foreach_bond(u8_t id, void (*func)(const struct bt_bond_info *info, void *user_data),
void *user_data)
{
int i;
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
struct bt_keys *keys = &key_pool[i];
if (keys->keys && keys->id == id) {
struct bt_bond_info info;
bt_addr_le_copy(&info.addr, &keys->addr);
func(&info, user_data);
}
}
}
void bt_keys_foreach(int type, void (*func)(struct bt_keys *keys, void *data),
void *data)
{
int i;
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if ((key_pool[i].keys & type)) {
func(&key_pool[i], data);
}
}
}
struct bt_keys *bt_keys_find(int type, u8_t id, const bt_addr_le_t *addr)
{
int i;
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if ((key_pool[i].keys & type) && key_pool[i].id == id &&
!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
return &key_pool[i];
}
}
return NULL;
}
struct bt_keys *bt_keys_get_type(int type, u8_t id, const bt_addr_le_t *addr)
{
struct bt_keys *keys;
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
keys = bt_keys_find(type, id, addr);
if (keys) {
return keys;
}
keys = bt_keys_get_addr(id, addr);
if (!keys) {
return NULL;
}
bt_keys_add_type(keys, type);
BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
return keys;
}
BT_DBG("unable to create keys for %s", bt_addr_le_str(addr));
return NULL;
}
struct bt_keys *bt_keys_find_irk(u8_t id, const bt_addr_le_t *addr)
{
int i;
void bt_foreach_bond(u8_t id, void (*func)(const struct bt_bond_info *info, void *user_data), void *user_data) {
int i;
BT_DBG("%s", bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
struct bt_keys *keys = &key_pool[i];
if (!bt_addr_le_is_rpa(addr)) {
return NULL;
if (keys->keys && keys->id == id) {
struct bt_bond_info info;
bt_addr_le_copy(&info.addr, &keys->addr);
func(&info, user_data);
}
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (!(key_pool[i].keys & BT_KEYS_IRK)) {
continue;
}
if (key_pool[i].id == id &&
!bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) {
BT_DBG("cached RPA %s for %s",
bt_addr_str(&key_pool[i].irk.rpa),
bt_addr_le_str(&key_pool[i].addr));
return &key_pool[i];
}
}
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (!(key_pool[i].keys & BT_KEYS_IRK)) {
continue;
}
if (key_pool[i].id != id) {
continue;
}
if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
BT_DBG("RPA %s matches %s",
bt_addr_str(&key_pool[i].irk.rpa),
bt_addr_le_str(&key_pool[i].addr));
bt_addr_copy(&key_pool[i].irk.rpa, &addr->a);
return &key_pool[i];
}
}
BT_DBG("No IRK for %s", bt_addr_le_str(addr));
return NULL;
}
}
struct bt_keys *bt_keys_find_addr(u8_t id, const bt_addr_le_t *addr)
{
int i;
void bt_keys_foreach(int type, void (*func)(struct bt_keys *keys, void *data), void *data) {
int i;
BT_DBG("%s", bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if ((key_pool[i].keys & type)) {
func(&key_pool[i], data);
}
}
}
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (key_pool[i].id == id &&
!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
return &key_pool[i];
}
struct bt_keys *bt_keys_find(int type, u8_t id, const bt_addr_le_t *addr) {
int i;
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if ((key_pool[i].keys & type) && key_pool[i].id == id && !bt_addr_le_cmp(&key_pool[i].addr, addr)) {
return &key_pool[i];
}
}
return NULL;
}
struct bt_keys *bt_keys_get_type(int type, u8_t id, const bt_addr_le_t *addr) {
struct bt_keys *keys;
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
keys = bt_keys_find(type, id, addr);
if (keys) {
return keys;
}
keys = bt_keys_get_addr(id, addr);
if (!keys) {
return NULL;
}
bt_keys_add_type(keys, type);
return keys;
}
struct bt_keys *bt_keys_find_irk(u8_t id, const bt_addr_le_t *addr) {
int i;
BT_DBG("%s", bt_addr_le_str(addr));
if (!bt_addr_le_is_rpa(addr)) {
return NULL;
}
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (!(key_pool[i].keys & BT_KEYS_IRK)) {
continue;
}
return NULL;
if (key_pool[i].id == id && !bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) {
BT_DBG("cached RPA %s for %s", bt_addr_str(&key_pool[i].irk.rpa), bt_addr_le_str(&key_pool[i].addr));
return &key_pool[i];
}
}
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (!(key_pool[i].keys & BT_KEYS_IRK)) {
continue;
}
if (key_pool[i].id != id) {
continue;
}
if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
BT_DBG("RPA %s matches %s", bt_addr_str(&key_pool[i].irk.rpa), bt_addr_le_str(&key_pool[i].addr));
bt_addr_copy(&key_pool[i].irk.rpa, &addr->a);
return &key_pool[i];
}
}
BT_DBG("No IRK for %s", bt_addr_le_str(addr));
return NULL;
}
struct bt_keys *bt_keys_find_addr(u8_t id, const bt_addr_le_t *addr) {
int i;
BT_DBG("%s", bt_addr_le_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
if (key_pool[i].id == id && !bt_addr_le_cmp(&key_pool[i].addr, addr)) {
return &key_pool[i];
}
}
return NULL;
}
#if defined(CONFIG_BLE_AT_CMD)
bt_addr_le_t *bt_get_keys_address(u8_t id)
{
bt_addr_le_t addr;
bt_addr_le_t *bt_get_keys_address(u8_t id) {
bt_addr_le_t addr;
memset(&addr, 0, sizeof(bt_addr_le_t));
if (id < ARRAY_SIZE(key_pool)) {
if (bt_addr_le_cmp(&key_pool[id].addr, &addr)) {
return &key_pool[id].addr;
}
memset(&addr, 0, sizeof(bt_addr_le_t));
if (id < ARRAY_SIZE(key_pool)) {
if (bt_addr_le_cmp(&key_pool[id].addr, &addr)) {
return &key_pool[id].addr;
}
}
return NULL;
return NULL;
}
#endif
void bt_keys_add_type(struct bt_keys *keys, int type)
{
keys->keys |= type;
}
void bt_keys_add_type(struct bt_keys *keys, int type) { keys->keys |= type; }
void bt_keys_clear(struct bt_keys *keys)
{
void bt_keys_clear(struct bt_keys *keys) {
#if defined(BFLB_BLE)
if (keys->keys & BT_KEYS_IRK) {
bt_id_del(keys);
}
if (keys->keys & BT_KEYS_IRK) {
bt_id_del(keys);
}
memset(keys, 0, sizeof(*keys));
memset(keys, 0, sizeof(*keys));
#if defined(CONFIG_BT_SETTINGS)
ef_del_env(NV_KEY_POOL);
ef_del_env(NV_KEY_POOL);
#endif
#else
BT_DBG("%s (keys 0x%04x)", bt_addr_le_str(&keys->addr), keys->keys);
BT_DBG("%s (keys 0x%04x)", bt_addr_le_str(&keys->addr), keys->keys);
if (keys->keys & BT_KEYS_IRK) {
bt_id_del(keys);
}
if (keys->keys & BT_KEYS_IRK) {
bt_id_del(keys);
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
char key[BT_SETTINGS_KEY_MAX];
/* Delete stored keys from flash */
if (keys->id) {
char id[4];
u8_to_dec(id, sizeof(id), keys->id);
bt_settings_encode_key(key, sizeof(key), "keys",
&keys->addr, id);
} else {
bt_settings_encode_key(key, sizeof(key), "keys",
&keys->addr, NULL);
}
BT_DBG("Deleting key %s", log_strdup(key));
settings_delete(key);
}
(void)memset(keys, 0, sizeof(*keys));
#endif
}
static void keys_clear_id(struct bt_keys *keys, void *data)
{
u8_t *id = data;
if (*id == keys->id) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_gatt_clear(*id, &keys->addr);
}
bt_keys_clear(keys);
}
}
void bt_keys_clear_all(u8_t id)
{
bt_keys_foreach(BT_KEYS_ALL, keys_clear_id, &id);
}
#if defined(CONFIG_BT_SETTINGS)
int bt_keys_store(struct bt_keys *keys)
{
#if defined(BFLB_BLE)
int err;
err = bt_settings_set_bin(NV_KEY_POOL, (const u8_t *)&key_pool[0], sizeof(key_pool));
return err;
#else
char val[BT_SETTINGS_SIZE(BT_KEYS_STORAGE_LEN)];
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
char key[BT_SETTINGS_KEY_MAX];
char *str;
int err;
str = settings_str_from_bytes(keys->storage_start, BT_KEYS_STORAGE_LEN,
val, sizeof(val));
if (!str) {
BT_ERR("Unable to encode bt_keys as value");
return -EINVAL;
}
/* Delete stored keys from flash */
if (keys->id) {
char id[4];
char id[4];
u8_to_dec(id, sizeof(id), keys->id);
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
id);
u8_to_dec(id, sizeof(id), keys->id);
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr, id);
} else {
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
NULL);
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr, NULL);
}
err = settings_save_one(key, keys->storage_start, BT_KEYS_STORAGE_LEN);
if (err) {
BT_ERR("Failed to save keys (err %d)", err);
return err;
BT_DBG("Deleting key %s", log_strdup(key));
settings_delete(key);
}
(void)memset(keys, 0, sizeof(*keys));
#endif
}
static void keys_clear_id(struct bt_keys *keys, void *data) {
u8_t *id = data;
if (*id == keys->id) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
bt_gatt_clear(*id, &keys->addr);
}
BT_DBG("Stored keys for %s (%s)", bt_addr_le_str(&keys->addr),
log_strdup(key));
bt_keys_clear(keys);
}
}
return 0;
#endif //BFLB_BLE
void bt_keys_clear_all(u8_t id) { bt_keys_foreach(BT_KEYS_ALL, keys_clear_id, &id); }
#if defined(CONFIG_BT_SETTINGS)
int bt_keys_store(struct bt_keys *keys) {
#if defined(BFLB_BLE)
int err;
err = bt_settings_set_bin(NV_KEY_POOL, (const u8_t *)&key_pool[0], sizeof(key_pool));
return err;
#else
char val[BT_SETTINGS_SIZE(BT_KEYS_STORAGE_LEN)];
char key[BT_SETTINGS_KEY_MAX];
char *str;
int err;
str = settings_str_from_bytes(keys->storage_start, BT_KEYS_STORAGE_LEN, val, sizeof(val));
if (!str) {
BT_ERR("Unable to encode bt_keys as value");
return -EINVAL;
}
if (keys->id) {
char id[4];
u8_to_dec(id, sizeof(id), keys->id);
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr, id);
} else {
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr, NULL);
}
err = settings_save_one(key, keys->storage_start, BT_KEYS_STORAGE_LEN);
if (err) {
BT_ERR("Failed to save keys (err %d)", err);
return err;
}
BT_DBG("Stored keys for %s (%s)", bt_addr_le_str(&keys->addr), log_strdup(key));
return 0;
#endif // BFLB_BLE
}
#if !defined(BFLB_BLE)
static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb,
void *cb_arg)
{
struct bt_keys *keys;
bt_addr_le_t addr;
u8_t id;
size_t len;
int err;
char val[BT_KEYS_STORAGE_LEN];
const char *next;
static int keys_set(const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) {
struct bt_keys *keys;
bt_addr_le_t addr;
u8_t id;
size_t len;
int err;
char val[BT_KEYS_STORAGE_LEN];
const char *next;
if (!name) {
BT_ERR("Insufficient number of arguments");
return -EINVAL;
}
if (!name) {
BT_ERR("Insufficient number of arguments");
return -EINVAL;
}
len = read_cb(cb_arg, val, sizeof(val));
if (len < 0) {
BT_ERR("Failed to read value (err %zu)", len);
return -EINVAL;
}
len = read_cb(cb_arg, val, sizeof(val));
if (len < 0) {
BT_ERR("Failed to read value (err %zu)", len);
return -EINVAL;
}
BT_DBG("name %s val %s", log_strdup(name),
(len) ? bt_hex(val, sizeof(val)) : "(null)");
BT_DBG("name %s val %s", log_strdup(name), (len) ? bt_hex(val, sizeof(val)) : "(null)");
err = bt_settings_decode_key(name, &addr);
if (err) {
BT_ERR("Unable to decode address %s", name);
return -EINVAL;
}
err = bt_settings_decode_key(name, &addr);
if (err) {
BT_ERR("Unable to decode address %s", name);
return -EINVAL;
}
settings_name_next(name, &next);
settings_name_next(name, &next);
if (!next) {
id = BT_ID_DEFAULT;
if (!next) {
id = BT_ID_DEFAULT;
} else {
id = strtol(next, NULL, 10);
}
if (!len) {
keys = bt_keys_find(BT_KEYS_ALL, id, &addr);
if (keys) {
(void)memset(keys, 0, sizeof(*keys));
BT_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
} else {
id = strtol(next, NULL, 10);
BT_WARN("Unable to find deleted keys for %s", bt_addr_le_str(&addr));
}
if (!len) {
keys = bt_keys_find(BT_KEYS_ALL, id, &addr);
if (keys) {
(void)memset(keys, 0, sizeof(*keys));
BT_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
} else {
BT_WARN("Unable to find deleted keys for %s",
bt_addr_le_str(&addr));
}
return 0;
}
keys = bt_keys_get_addr(id, &addr);
if (!keys) {
BT_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
return -ENOMEM;
}
if (len != BT_KEYS_STORAGE_LEN) {
do {
/* Load shorter structure for compatibility with old
* records format with no counter.
*/
if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) &&
len == BT_KEYS_STORAGE_LEN_COMPAT) {
BT_WARN("Keys for %s have no aging counter",
bt_addr_le_str(&addr));
memcpy(keys->storage_start, val, len);
continue;
}
BT_ERR("Invalid key length %zu != %zu", len,
BT_KEYS_STORAGE_LEN);
bt_keys_clear(keys);
return -EINVAL;
} while (0);
} else {
memcpy(keys->storage_start, val, len);
}
BT_DBG("Successfully restored keys for %s", bt_addr_le_str(&addr));
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
if (aging_counter_val < keys->aging_counter) {
aging_counter_val = keys->aging_counter;
}
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
return 0;
}
keys = bt_keys_get_addr(id, &addr);
if (!keys) {
BT_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
return -ENOMEM;
}
if (len != BT_KEYS_STORAGE_LEN) {
do {
/* Load shorter structure for compatibility with old
* records format with no counter.
*/
if (IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) && len == BT_KEYS_STORAGE_LEN_COMPAT) {
BT_WARN("Keys for %s have no aging counter", bt_addr_le_str(&addr));
memcpy(keys->storage_start, val, len);
continue;
}
BT_ERR("Invalid key length %zu != %zu", len, BT_KEYS_STORAGE_LEN);
bt_keys_clear(keys);
return -EINVAL;
} while (0);
} else {
memcpy(keys->storage_start, val, len);
}
BT_DBG("Successfully restored keys for %s", bt_addr_le_str(&addr));
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
if (aging_counter_val < keys->aging_counter) {
aging_counter_val = keys->aging_counter;
}
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
return 0;
}
#endif //!(BFLB_BLE)
static void id_add(struct bt_keys *keys, void *user_data)
{
bt_id_add(keys);
}
static void id_add(struct bt_keys *keys, void *user_data) { bt_id_add(keys); }
#if defined(BFLB_BLE)
int keys_commit(void)
@@ -456,51 +412,46 @@ int keys_commit(void)
static int keys_commit(void)
#endif
{
BT_DBG("");
BT_DBG("");
/* We do this in commit() rather than add() since add() may get
* called multiple times for the same address, especially if
* the keys were already removed.
*/
bt_keys_foreach(BT_KEYS_IRK, id_add, NULL);
/* We do this in commit() rather than add() since add() may get
* called multiple times for the same address, especially if
* the keys were already removed.
*/
bt_keys_foreach(BT_KEYS_IRK, id_add, NULL);
return 0;
return 0;
}
//SETTINGS_STATIC_HANDLER_DEFINE(bt_keys, "bt/keys", NULL, keys_set, keys_commit,
// SETTINGS_STATIC_HANDLER_DEFINE(bt_keys, "bt/keys", NULL, keys_set, keys_commit,
// NULL);
#if defined(BFLB_BLE)
int bt_keys_load(void)
{
return bt_settings_get_bin(NV_KEY_POOL, (u8_t *)&key_pool[0], sizeof(key_pool), NULL);
}
int bt_keys_load(void) { return bt_settings_get_bin(NV_KEY_POOL, (u8_t *)&key_pool[0], sizeof(key_pool), NULL); }
#endif
#endif /* CONFIG_BT_SETTINGS */
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
void bt_keys_update_usage(u8_t id, const bt_addr_le_t *addr)
{
struct bt_keys *keys = bt_keys_find_addr(id, addr);
void bt_keys_update_usage(u8_t id, const bt_addr_le_t *addr) {
struct bt_keys *keys = bt_keys_find_addr(id, addr);
if (!keys) {
return;
}
if (!keys) {
return;
}
if (last_keys_updated == keys) {
return;
}
if (last_keys_updated == keys) {
return;
}
keys->aging_counter = ++aging_counter_val;
last_keys_updated = keys;
keys->aging_counter = ++aging_counter_val;
last_keys_updated = keys;
BT_DBG("Aging counter for %s is set to %u", bt_addr_le_str(addr),
keys->aging_counter);
BT_DBG("Aging counter for %s is set to %u", bt_addr_le_str(addr), keys->aging_counter);
if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
bt_keys_store(keys);
}
if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
bt_keys_store(keys);
}
}
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */

View File

@@ -6,10 +6,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <string.h>
#include <atomic.h>
#include <string.h>
#include <util.h>
#include <zephyr.h>
#include <bluetooth.h>
#include <conn.h>
@@ -21,45 +21,43 @@
#include "log.h"
#include "hci_core.h"
#include "settings.h"
#include "keys.h"
#include "settings.h"
static struct bt_keys_link_key key_pool[CONFIG_BT_MAX_PAIRED];
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
static uint32_t aging_counter_val;
static uint32_t aging_counter_val;
static struct bt_keys_link_key *last_keys_updated;
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr)
{
struct bt_keys_link_key *key;
int i;
struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr) {
struct bt_keys_link_key *key;
int i;
BT_DBG("%s", bt_addr_str(addr));
BT_DBG("%s", bt_addr_str(addr));
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
key = &key_pool[i];
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
key = &key_pool[i];
if (!bt_addr_cmp(&key->addr, addr)) {
return key;
}
if (!bt_addr_cmp(&key->addr, addr)) {
return key;
}
}
return NULL;
return NULL;
}
struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr)
{
struct bt_keys_link_key *key;
struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr) {
struct bt_keys_link_key *key;
key = bt_keys_find_link_key(addr);
if (key) {
return key;
}
key = bt_keys_find_link_key(addr);
if (key) {
return key;
}
key = bt_keys_find_link_key(BT_ADDR_ANY);
#if 0 //IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) //MBHJ
key = bt_keys_find_link_key(BT_ADDR_ANY);
#if 0 // IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) //MBHJ
if (!key) {
int i;
@@ -78,60 +76,56 @@ struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr)
}
#endif
if (key) {
bt_addr_copy(&key->addr, addr);
#if 0 //IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) //MBHJ
if (key) {
bt_addr_copy(&key->addr, addr);
#if 0 // IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST) //MBHJ
key->aging_counter = ++aging_counter_val;
last_keys_updated = key;
#endif
BT_DBG("created %p for %s", key, bt_addr_str(addr));
return key;
}
BT_DBG("created %p for %s", key, bt_addr_str(addr));
return key;
}
BT_DBG("unable to create keys for %s", bt_addr_str(addr));
BT_DBG("unable to create keys for %s", bt_addr_str(addr));
return NULL;
return NULL;
}
void bt_keys_link_key_clear(struct bt_keys_link_key *link_key)
{
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
char key[BT_SETTINGS_KEY_MAX];
bt_addr_le_t le_addr;
void bt_keys_link_key_clear(struct bt_keys_link_key *link_key) {
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
char key[BT_SETTINGS_KEY_MAX];
bt_addr_le_t le_addr;
le_addr.type = BT_ADDR_LE_PUBLIC;
bt_addr_copy(&le_addr.a, &link_key->addr);
bt_settings_encode_key(key, sizeof(key), "link_key",
&le_addr, NULL);
settings_delete(key);
}
le_addr.type = BT_ADDR_LE_PUBLIC;
bt_addr_copy(&le_addr.a, &link_key->addr);
bt_settings_encode_key(key, sizeof(key), "link_key", &le_addr, NULL);
settings_delete(key);
}
BT_DBG("%s", bt_addr_str(&link_key->addr));
(void)memset(link_key, 0, sizeof(*link_key));
BT_DBG("%s", bt_addr_str(&link_key->addr));
(void)memset(link_key, 0, sizeof(*link_key));
}
void bt_keys_link_key_clear_addr(const bt_addr_t *addr)
{
int i;
struct bt_keys_link_key *key;
void bt_keys_link_key_clear_addr(const bt_addr_t *addr) {
int i;
struct bt_keys_link_key *key;
if (!addr) {
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
key = &key_pool[i];
bt_keys_link_key_clear(key);
}
return;
if (!addr) {
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
key = &key_pool[i];
bt_keys_link_key_clear(key);
}
return;
}
key = bt_keys_find_link_key(addr);
if (key) {
bt_keys_link_key_clear(key);
}
key = bt_keys_find_link_key(addr);
if (key) {
bt_keys_link_key_clear(key);
}
}
void bt_keys_link_key_store(struct bt_keys_link_key *link_key)
{
#if 0 //MBHJ
void bt_keys_link_key_store(struct bt_keys_link_key *link_key) {
#if 0 // MBHJ
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
int err;
char key[BT_SETTINGS_KEY_MAX];
@@ -153,89 +147,78 @@ void bt_keys_link_key_store(struct bt_keys_link_key *link_key)
#if defined(CONFIG_BT_SETTINGS)
static int link_key_set(const char *name, size_t len_rd,
settings_read_cb read_cb, void *cb_arg)
{
int err;
ssize_t len;
bt_addr_le_t le_addr;
struct bt_keys_link_key *link_key;
char val[BT_KEYS_LINK_KEY_STORAGE_LEN];
static int link_key_set(const char *name, size_t len_rd, settings_read_cb read_cb, void *cb_arg) {
int err;
ssize_t len;
bt_addr_le_t le_addr;
struct bt_keys_link_key *link_key;
char val[BT_KEYS_LINK_KEY_STORAGE_LEN];
if (!name) {
BT_ERR("Insufficient number of arguments");
return -EINVAL;
if (!name) {
BT_ERR("Insufficient number of arguments");
return -EINVAL;
}
len = read_cb(cb_arg, val, sizeof(val));
if (len < 0) {
BT_ERR("Failed to read value (err %zu)", len);
return -EINVAL;
}
BT_DBG("name %s val %s", log_strdup(name), len ? bt_hex(val, sizeof(val)) : "(null)");
err = bt_settings_decode_key(name, &le_addr);
if (err) {
BT_ERR("Unable to decode address %s", name);
return -EINVAL;
}
link_key = bt_keys_get_link_key(&le_addr.a);
if (len != BT_KEYS_LINK_KEY_STORAGE_LEN) {
if (link_key) {
bt_keys_link_key_clear(link_key);
BT_DBG("Clear keys for %s", bt_addr_le_str(&le_addr));
} else {
BT_WARN("Unable to find deleted keys for %s", bt_addr_le_str(&le_addr));
}
len = read_cb(cb_arg, val, sizeof(val));
if (len < 0) {
BT_ERR("Failed to read value (err %zu)", len);
return -EINVAL;
}
return 0;
}
BT_DBG("name %s val %s", log_strdup(name),
len ? bt_hex(val, sizeof(val)) : "(null)");
err = bt_settings_decode_key(name, &le_addr);
if (err) {
BT_ERR("Unable to decode address %s", name);
return -EINVAL;
}
link_key = bt_keys_get_link_key(&le_addr.a);
if (len != BT_KEYS_LINK_KEY_STORAGE_LEN) {
if (link_key) {
bt_keys_link_key_clear(link_key);
BT_DBG("Clear keys for %s", bt_addr_le_str(&le_addr));
} else {
BT_WARN("Unable to find deleted keys for %s",
bt_addr_le_str(&le_addr));
}
return 0;
}
memcpy(link_key->storage_start, val, len);
BT_DBG("Successfully restored link key for %s",
bt_addr_le_str(&le_addr));
memcpy(link_key->storage_start, val, len);
BT_DBG("Successfully restored link key for %s", bt_addr_le_str(&le_addr));
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
if (aging_counter_val < link_key->aging_counter) {
aging_counter_val = link_key->aging_counter;
}
if (aging_counter_val < link_key->aging_counter) {
aging_counter_val = link_key->aging_counter;
}
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
return 0;
return 0;
}
static int link_key_commit(void)
{
return 0;
}
static int link_key_commit(void) { return 0; }
SETTINGS_STATIC_HANDLER_DEFINE(bt_link_key, "bt/link_key", NULL, link_key_set,
link_key_commit, NULL);
SETTINGS_STATIC_HANDLER_DEFINE(bt_link_key, "bt/link_key", NULL, link_key_set, link_key_commit, NULL);
void bt_keys_link_key_update_usage(const bt_addr_t *addr)
{
struct bt_keys_link_key *link_key = bt_keys_find_link_key(addr);
void bt_keys_link_key_update_usage(const bt_addr_t *addr) {
struct bt_keys_link_key *link_key = bt_keys_find_link_key(addr);
if (!link_key) {
return;
}
if (!link_key) {
return;
}
if (last_keys_updated == link_key) {
return;
}
if (last_keys_updated == link_key) {
return;
}
link_key->aging_counter = ++aging_counter_val;
last_keys_updated = link_key;
link_key->aging_counter = ++aging_counter_val;
last_keys_updated = link_key;
BT_DBG("Aging counter for %s is set to %u", bt_addr_str(addr),
link_key->aging_counter);
BT_DBG("Aging counter for %s is set to %u", bt_addr_str(addr), link_key->aging_counter);
if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
bt_keys_link_key_store(link_key);
}
if (IS_ENABLED(CONFIG_BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING)) {
bt_keys_link_key_store(link_key);
}
}
#endif

View File

@@ -9,20 +9,16 @@
*/
#if defined(CONFIG_BT_DEBUG_MONITOR)
#include <zephyr.h>
#include <buf.h>
#include "monitor.h"
#include "log.h"
#include <buf.h>
#include <zephyr.h>
void bt_monitor_send(uint16_t opcode, const void *data, size_t len)
{
const uint8_t *buf = data;
void bt_monitor_send(uint16_t opcode, const void *data, size_t len) {
const uint8_t *buf = data;
BT_WARN("[Hci]:pkt_type:[0x%x],pkt_data:[%s]\r\n", opcode, bt_hex(buf, len));
BT_WARN("[Hci]:pkt_type:[0x%x],pkt_data:[%s]\r\n", opcode, bt_hex(buf, len));
}
void bt_monitor_new_index(uint8_t type, uint8_t bus, bt_addr_t *addr,
const char *name)
{
}
void bt_monitor_new_index(uint8_t type, uint8_t bus, bt_addr_t *addr, const char *name) {}
#endif

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